Messages in this thread Patch in this message | | | Date | Fri, 23 Dec 2005 23:38:39 +0900 (JST) | Subject | [PATCH] fix posix lock on NFS, #2 | From | ASANO Masahiro <> |
| |
Hi,
This is another problem report on posix lock.
The nfsd may handle the lock information incorrectly if new lock is contiguous to old one. I think both 2.6 and 2.4 kernel have this bug.
The following is a sample program to produce the circumstance. fd = open("file_on_nfs_2", O_RDWR | O_CREAT, 0644); memset(&lck, 0, sizeof(lck)); lck.l_type = F_WRLCK; switch (child = fork()) { case 0: lck.l_start = 0; lck.l_len = 1; fcntl(fd, F_SETLK, &lck); sleep(1); lck.l_start = 1; lck.l_len = 1; fcntl(fd, F_SETLKW, &lck); _exit(0); default: lck.l_start = 1; lck.l_len = 1; fcntl(fd, F_SETLK, &lck); sleep(2); close(fd); printf("waiting...\n"); // sleep(1); kill(chiled, SIGINT); wait(NULL); break; }
All version of linux requires time to grant the lock, but on older kernel the lock is leaked if it is signaled while waiting the grant.
I think it is caused by a miss-calling of posix_lock_file() in nfsd. posix_lock_file() updates the second argument `request' as you know, but it seems that nfsd gives no care about that.
Here is a patch. It changes nfsd to keep the range of file_lock for later use. Any comments and feedback are welcome.
Signed-off-by: ASANO Masahiro <masano@tnes.nec.co.jp>
--- linux-2.6.15-rc6/fs/lockd/svclock.c.orig 2005-12-23 20:16:33.000000000 +0900 +++ linux-2.6.15-rc6/fs/lockd/svclock.c 2005-12-23 20:24:13.000000000 +0900 @@ -510,6 +510,7 @@ nlmsvc_grant_blocked(struct nlm_block *b struct nlm_file *file = block->b_file; struct nlm_lock *lock = &block->b_call.a_args.lock; struct file_lock *conflock; + struct file_lock tmplck; int error; dprintk("lockd: grant blocked lock %p\n", block); @@ -542,7 +543,8 @@ nlmsvc_grant_blocked(struct nlm_block *b * following yields an error, this is most probably due to low * memory. Retry the lock in a few seconds. */ - if ((error = posix_lock_file(file->f_file, &lock->fl)) < 0) { + tmplck = lock->fl; /* keep the range for later use */ + if ((error = posix_lock_file(file->f_file, &tmplck)) < 0) { printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", -error, __FUNCTION__); nlmsvc_insert_block(block, 10 * HZ); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |