Messages in this thread Patch in this message | | | From | (Matthias Urlichs) | Subject | File locking anomaly under 2.0.30 | Date | 24 Jul 1997 12:02:52 +0200 |
| |
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;
| |