updated patch for 2.1.89-3 lock owners

Bill Hawes (whawes@star.net)
Fri, 27 Feb 1998 21:42:06 -0500


This is a multi-part message in MIME format.
--------------BFE908B35C2F8846D60212D3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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
--------------BFE908B35C2F8846D60212D3
Content-Type: text/plain; charset=us-ascii; name="locks_owner89-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="locks_owner89-patch"

--- 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);

--------------BFE908B35C2F8846D60212D3--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu