lkml.org 
[lkml]   [1998]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectupdated patch for 2.1.89-3 lock owners
I've found the problem that was causing locks not to be removed with xdm.
Changing the lock owner field to be the files_struct was conceptually OK, but
there's a problem in that the files pointer is cleared from the task structure
_before_ the files are closed. This caused the owner comparison to fail when a
file with posix locks was being closed at task exit time.

Since the "owner" value from the locking standpoint just needs to be something
with the same value for all threads, I've changed the code to use the task's fs
structure pointer. This will be the same among all threads and remains fixed
until after the files structure has been removed. The attached patch against
pre-2.1.89-3 should clear up the problems.

Perhaps someone familiar with the threads implementation has a better suggestion
for a field in the task structure that (1) will always be the same among all
threads, and (2) remains fixed for the life of the threads.

Regards,
Bill--- fs/locks.c Fri Feb 27 22:23:43 1998
+++ fs/locks.c Fri Feb 27 19:32:15 1998
@@ -119,6 +119,12 @@

#define OFFSET_MAX ((off_t)0x7fffffff) /* FIXME: move elsewhere? */

+/*
+ * A note on lock ownership ... this needs to be some field
+ * shared among all threads. Otherwise it doesn't matter.
+ */
+#define LOCK_OWNER(task) ((task)->fs)
+
static int flock_make_lock(struct file *filp, struct file_lock *fl,
unsigned int cmd);
static int posix_make_lock(struct file *filp, struct file_lock *fl,
@@ -473,13 +479,14 @@
*/
void locks_remove_posix(struct task_struct *task, struct file *filp)
{
- struct inode * inode = filp->f_dentry->d_inode;
- void * owner = task->files;
+ struct dentry * dentry = filp->f_dentry;
+ struct inode * inode = dentry->d_inode;
+ void * owner = LOCK_OWNER(task);
struct file_lock file_lock, *fl;
struct file_lock **before;

/*
- * For POSIX locks we free all locks on this file for the given task.
+ * For POSIX locks we free all locks on this file for the given owner.
*/
repeat:
before = &inode->i_flock;
@@ -508,10 +515,13 @@
*/
void locks_remove_flock(struct file *filp)
{
- struct inode * inode = filp->f_dentry->d_inode;
+ struct dentry * dentry = filp->f_dentry;
+ struct inode * inode = dentry->d_inode;
struct file_lock file_lock, *fl;
struct file_lock **before;

+ if (filp->f_count != 1)
+ printk("locks_remove_flock: count=%d\n", filp->f_count);
repeat:
before = &inode->i_flock;
while ((fl = *before) != NULL) {
@@ -532,6 +542,19 @@
}
before = &fl->fl_next;
}
+ /*
+ * Sanity check: there shouldn't be any more locks now ...
+ */
+ if (dentry->d_count == 1 && inode->i_flock != NULL) {
+ printk("locks_remove_flock: %s/%s, owner=%p, pid=%d\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,
+ LOCK_OWNER(current), current->pid);
+ fl = inode->i_flock;
+ for (; fl; fl = fl->fl_next) {
+ printk(" flags=%x, owner=%p, pid=%d\n",
+ fl->fl_flags, fl->fl_owner, fl->fl_pid);
+ }
+ }
}

struct file_lock *
@@ -575,7 +598,7 @@

int locks_mandatory_locked(struct inode *inode)
{
- void * owner = current->files;
+ void * owner = LOCK_OWNER(current);
struct file_lock *fl;

/* Search the lock list for this inode for any POSIX locks.
@@ -600,7 +623,7 @@

tfl.fl_file = filp;
tfl.fl_flags = FL_POSIX | FL_ACCESS;
- tfl.fl_owner = current->files;
+ tfl.fl_owner = LOCK_OWNER(current);
tfl.fl_pid = current->pid;
tfl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
tfl.fl_start = offset;
@@ -684,7 +707,7 @@
fl->fl_end = OFFSET_MAX;

fl->fl_file = filp;
- fl->fl_owner = current->files;
+ fl->fl_owner = LOCK_OWNER(current);
fl->fl_pid = current->pid;

return (1);
\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.042 / U:0.152 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site