aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@fieldses.org>2007-05-10 18:38:43 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-10 23:25:59 -0400
commit129a84de2347002f09721cda3155ccfd19fade40 (patch)
tree11dabc5695dbcd0eb814935b2c02ddeb01442932
parenta9deecba19b8f384d97f82c75379da48bccb2588 (diff)
locks: fix F_GETLK regression (failure to find conflicts)
In 9d6a8c5c213e34c475e72b245a8eb709258e968c we changed posix_test_lock to modify its single file_lock argument instead of taking separate input and output arguments. This makes it no longer safe to set the output lock's fl_type to F_UNLCK before looking for a conflict, since that means searching for a conflict against a lock with type F_UNLCK. This fixes a regression which causes F_GETLK to incorrectly report no conflict on most filesystems (including any filesystem that doesn't do its own locking). Also fix posix_lock_to_flock() to copy the lock type. This isn't strictly necessary, since the caller already does this; but it seems less likely to cause confusion in the future. Thanks to Doug Chapman for the bug report. Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu> Acked-by: Doug Chapman <doug.chapman@hp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/locks.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 671a034dc999..8ec16ab5ef74 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -669,7 +669,6 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
669{ 669{
670 struct file_lock *cfl; 670 struct file_lock *cfl;
671 671
672 fl->fl_type = F_UNLCK;
673 lock_kernel(); 672 lock_kernel();
674 for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { 673 for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
675 if (!IS_POSIX(cfl)) 674 if (!IS_POSIX(cfl))
@@ -681,7 +680,8 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
681 __locks_copy_lock(fl, cfl); 680 __locks_copy_lock(fl, cfl);
682 unlock_kernel(); 681 unlock_kernel();
683 return 1; 682 return 1;
684 } 683 } else
684 fl->fl_type = F_UNLCK;
685 unlock_kernel(); 685 unlock_kernel();
686 return 0; 686 return 0;
687} 687}
@@ -1632,6 +1632,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
1632 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 1632 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
1633 fl->fl_end - fl->fl_start + 1; 1633 fl->fl_end - fl->fl_start + 1;
1634 flock->l_whence = 0; 1634 flock->l_whence = 0;
1635 flock->l_type = fl->fl_type;
1635 return 0; 1636 return 0;
1636} 1637}
1637 1638