aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 663c069b59b3..11dbf08651b7 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -773,7 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
773 * give it the opportunity to lock the file. 773 * give it the opportunity to lock the file.
774 */ 774 */
775 if (found) 775 if (found)
776 cond_resched(); 776 cond_resched_bkl();
777 777
778find_conflict: 778find_conflict:
779 for_each_lock(inode, before) { 779 for_each_lock(inode, before) {
@@ -1753,6 +1753,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
1753 struct file_lock *file_lock = locks_alloc_lock(); 1753 struct file_lock *file_lock = locks_alloc_lock();
1754 struct flock flock; 1754 struct flock flock;
1755 struct inode *inode; 1755 struct inode *inode;
1756 struct file *f;
1756 int error; 1757 int error;
1757 1758
1758 if (file_lock == NULL) 1759 if (file_lock == NULL)
@@ -1825,7 +1826,15 @@ again:
1825 * Attempt to detect a close/fcntl race and recover by 1826 * Attempt to detect a close/fcntl race and recover by
1826 * releasing the lock that was just acquired. 1827 * releasing the lock that was just acquired.
1827 */ 1828 */
1828 if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { 1829 /*
1830 * we need that spin_lock here - it prevents reordering between
1831 * update of inode->i_flock and check for it done in close().
1832 * rcu_read_lock() wouldn't do.
1833 */
1834 spin_lock(&current->files->file_lock);
1835 f = fcheck(fd);
1836 spin_unlock(&current->files->file_lock);
1837 if (!error && f != filp && flock.l_type != F_UNLCK) {
1829 flock.l_type = F_UNLCK; 1838 flock.l_type = F_UNLCK;
1830 goto again; 1839 goto again;
1831 } 1840 }
@@ -1881,6 +1890,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
1881 struct file_lock *file_lock = locks_alloc_lock(); 1890 struct file_lock *file_lock = locks_alloc_lock();
1882 struct flock64 flock; 1891 struct flock64 flock;
1883 struct inode *inode; 1892 struct inode *inode;
1893 struct file *f;
1884 int error; 1894 int error;
1885 1895
1886 if (file_lock == NULL) 1896 if (file_lock == NULL)
@@ -1953,7 +1963,10 @@ again:
1953 * Attempt to detect a close/fcntl race and recover by 1963 * Attempt to detect a close/fcntl race and recover by
1954 * releasing the lock that was just acquired. 1964 * releasing the lock that was just acquired.
1955 */ 1965 */
1956 if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { 1966 spin_lock(&current->files->file_lock);
1967 f = fcheck(fd);
1968 spin_unlock(&current->files->file_lock);
1969 if (!error && f != filp && flock.l_type != F_UNLCK) {
1957 flock.l_type = F_UNLCK; 1970 flock.l_type = F_UNLCK;
1958 goto again; 1971 goto again;
1959 } 1972 }