patch for 2.1.88 locks owner (thread support)

Bill Hawes (whawes@star.net)
Wed, 25 Feb 1998 09:56:22 -0500


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

Thorsten Kukuk wrote:

> The problem is, that the lock will not always be removed if the program
> exit. Normally, the lock should be given free, if the program exits. But
> that doesn't happen always. In the moment I start a thread which acts as
> signal handler and wait for signals which would kill a thread, and then
> give the lock free. This works in 9 from 10 cases, but not always.
>
> The problem is, after this, you have a locked file which is owned by a non
> existent pid, and you couldn't access /proc/locks without core dump
> and kernel oops.

I've looked into the locks problem with threads and understand why you're
getting an oops -- the lock left behind when a file was closed has a stale
reference to the file pointer. An access to proc/locks will attempt to
dereference the pointer, causing an oops.

The attached patch should take care of the problem. I've changed the lock owner
field to be the files structure rather than the task, so that clone tasks
sharing a files structure will all have the same owner field. If any clone
closes a file, any posix locks on the file will be removed.

Locks are still distinguished by PID, so the locks installed by two separate
clone tasks would still be considered separate from the standpoint of the
locks_same_owner() routine. I'm not sure whether this is the desired behavior,
but it's separate from the issue of removing locks when a file is closed.

Please give this patch a try and let me know if it helps your problem. (You'll
need to upgrade to 2.1.88 first, as the patch requires other changes made in
2.1.88.)

Regards,
Bill
--------------9B68EBDF633AFDB8BCD68A34
Content-Type: text/plain; charset=us-ascii; name="locks_owner88-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="locks_owner88-patch"

--- fs/locks.c.old Sat Feb 21 09:25:00 1998
+++ fs/locks.c Wed Feb 25 10:17:39 1998
@@ -176,7 +177,10 @@
(fl2->fl_end >= fl1->fl_start));
}

-/* Check whether two locks have the same owner
+/*
+ * Check whether two locks have the same owner
+ * N.B. Do we need the test on PID as well as owner?
+ * (Clone tasks should be considered as one "owner".)
*/
static inline int
locks_same_owner(struct file_lock *fl1, struct file_lock *fl2)
@@ -448,6 +474,7 @@
void locks_remove_posix(struct task_struct *task, struct file *filp)
{
struct inode * inode = filp->f_dentry->d_inode;
+ void * owner = task->files;
struct file_lock file_lock, *fl;
struct file_lock **before;

@@ -457,7 +484,7 @@
repeat:
before = &inode->i_flock;
while ((fl = *before) != NULL) {
- if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == task) {
+ if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) {
int (*lock)(struct file *, int, struct file_lock *);
lock = filp->f_op->lock;
if (lock) {
@@ -548,6 +575,7 @@

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

/* Search the lock list for this inode for any POSIX locks.
@@ -555,7 +583,7 @@
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & FL_POSIX))
continue;
- if (fl->fl_owner != current)
+ if (fl->fl_owner != owner)
return (-EAGAIN);
}
return (0);
@@ -572,7 +600,7 @@

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

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

return (1);

--------------9B68EBDF633AFDB8BCD68A34--

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