lkml.org 
[lkml]   [1997]   [Jul]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectFile locking anomaly under 2.0.30
Date
POSIX-(=fcntl)-style locks are associated with a process. Right? Right.

I'm trying to install mysql, an SQL database which uses threading and
fcntl-style file locks.

Now look at this:
% cat /proc/locks
1: POSIX ADVISORY READ 0 08:13:8245 0 2147483647 01753bd8 00000000
02aa6218 00000000 00000000

That first zero is the process ID. This is not supposed to happen at all.

Apparently, POSIX locks are not released when a thread dies because all the
files are still open from other threads -- but that doesn't help. :-/

This patch needs to go in 2.0.31 _and_ 2.1.whatever.


Index: kernel/exit.c
===================================================================
RCS file: /usr/src/cvs/kernel/linux/kernel/exit.c,v
retrieving revision 1.4
diff -u -r1.4 exit.c
--- exit.c 1997/06/08 08:17:57 1.4
+++ exit.c 1997/07/24 09:55:46
@@ -413,6 +413,27 @@
}
}

+extern void remove_posix_locks(struct task_struct *task, struct file *filp);
+static inline void unlock_files(struct files_struct * files)
+{
+ int i, j;
+
+ j = 0;
+ for (;;) {
+ unsigned long set = files->open_fds.fds_bits[j];
+ i = j * __NFDBITS;
+ j++;
+ if (i >= MAX_OPEN)
+ break;
+ while (set) {
+ if (set & 1)
+ remove_posix_locks(current,files->fd[i]);
+ i++;
+ set >>= 1;
+ }
+ }
+}
+
static inline void __exit_files(struct task_struct *tsk)
{
struct files_struct * files = tsk->files;
@@ -422,7 +443,8 @@
if (!--files->count) {
close_files(files);
kfree(files);
- }
+ } else
+ unlock_files(files);
}
}

Index: fs/locks.c
===================================================================
RCS file: /usr/src/cvs/kernel/linux/fs/locks.c,v
retrieving revision 1.2
diff -u -r1.2 locks.c
--- locks.c 1997/06/08 08:17:22 1.2
+++ locks.c 1997/07/24 10:00:44
@@ -352,6 +352,21 @@
return;
}

+/* This function is called from ../kernel/exit.c when a thread dies.
+ */
+void remove_posix_locks(struct task_struct *task, struct file *filp)
+{
+ struct file_lock *fl;
+
+ /* For POSIX locks we free all locks on this file for the given task. */
+ if ((fl = filp->f_inode->i_flock) != NULL) {
+ if (fl->fl_flags & F_POSIX)
+ posix_remove_locks(&filp->f_inode->i_flock, task);
+ }
+
+ return;
+}
+
static void posix_remove_locks(struct file_lock **before, struct task_struct *task)
{
struct file_lock *fl;



\
 
 \ /
  Last update: 2005-03-22 13:39    [W:0.503 / U:0.424 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site