From dae3ea2a021753e53e04b64986223992fc041359 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 May 2008 13:58:34 -0400 Subject: [PATCH] --- yaml --- r: 96109 b: refs/heads/master c: 0b2bac2f1ea0d33a3621b27ca68b9ae760fca2e9 h: refs/heads/master i: 96107: 388ae6a7eb48aa31d6b23caaceca49b3c8dcfb65 v: v3 --- [refs] | 2 +- trunk/fs/locks.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 5c0326e866d2..ec1123619a22 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 33dcdac2df54e66c447ae03f58c95c7251aa5649 +refs/heads/master: 0b2bac2f1ea0d33a3621b27ca68b9ae760fca2e9 diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 663c069b59b3..0ac6b92cb0b6 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -1753,6 +1753,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1825,7 +1826,15 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + /* + * we need that spin_lock here - it prevents reordering between + * update of inode->i_flock and check for it done in close(). + * rcu_read_lock() wouldn't do. + */ + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } @@ -1881,6 +1890,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1953,7 +1963,10 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; }