From: Chris Wright This is a rather ugly fix, but it demonstrates the hole. It's possible for a posix lock to get applied after the final close of the file. This means locks_remove_posix misses the yet to be created posix lock, and on final fput when leaving fcntl, locks_remove_flock will BUG(). I was able to reproduce Ivan's bugreport. I doubt it's the right/best fix, but it's functional (no more BUG()). Signed-off-by: Chris Wright Signed-off-by: Andrew Morton --- 25-akpm/fs/fcntl.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diff -puN fs/fcntl.c~posix-locks-bug-fix fs/fcntl.c --- 25/fs/fcntl.c~posix-locks-bug-fix 2004-10-01 21:08:48.457390480 -0700 +++ 25-akpm/fs/fcntl.c 2004-10-01 21:08:48.472388200 -0700 @@ -363,7 +363,7 @@ static long do_fcntl(int fd, unsigned in asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct file *filp; + struct file *filp, *filp2; long err = -EBADF; filp = fget(fd); @@ -378,6 +378,11 @@ asmlinkage long sys_fcntl(unsigned int f err = do_fcntl(fd, cmd, arg, filp); + filp2 = fget(fd); + if (filp2 != filp) + locks_remove_posix(filp, current->files); + if (filp2) + fput(filp2); fput(filp); out: return err; @@ -386,7 +391,7 @@ out: #if BITS_PER_LONG == 32 asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct file * filp; + struct file *filp, *filp2; long err; err = -EBADF; @@ -413,6 +418,12 @@ asmlinkage long sys_fcntl64(unsigned int err = do_fcntl(fd, cmd, arg, filp); break; } + + filp2 = fget(fd); + if (filp2 != filp) + locks_remove_posix(filp, current->files); + if (filp2) + fput(filp2); fput(filp); out: return err; _