|
|
@@ -2181,7 +2181,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
-again:
|
|
|
error = flock_to_posix_lock(filp, file_lock, &flock);
|
|
|
if (error)
|
|
|
goto out;
|
|
|
@@ -2223,19 +2222,22 @@ again:
|
|
|
* Attempt to detect a close/fcntl race and recover by
|
|
|
* releasing the lock that was just acquired.
|
|
|
*/
|
|
|
- /*
|
|
|
- * we need that spin_lock here - it prevents reordering between
|
|
|
- * update of i_flctx->flc_posix 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;
|
|
|
+ if (!error && file_lock->fl_type != F_UNLCK) {
|
|
|
+ /*
|
|
|
+ * We need that spin_lock here - it prevents reordering between
|
|
|
+ * update of i_flctx->flc_posix 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 (f != filp) {
|
|
|
+ file_lock->fl_type = F_UNLCK;
|
|
|
+ error = do_lock_file_wait(filp, cmd, file_lock);
|
|
|
+ WARN_ON_ONCE(error);
|
|
|
+ error = -EBADF;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
out:
|
|
|
locks_free_lock(file_lock);
|
|
|
return error;
|
|
|
@@ -2321,7 +2323,6 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
-again:
|
|
|
error = flock64_to_posix_lock(filp, file_lock, &flock);
|
|
|
if (error)
|
|
|
goto out;
|
|
|
@@ -2363,14 +2364,22 @@ again:
|
|
|
* Attempt to detect a close/fcntl race and recover by
|
|
|
* releasing the lock that was just acquired.
|
|
|
*/
|
|
|
- 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;
|
|
|
+ if (!error && file_lock->fl_type != F_UNLCK) {
|
|
|
+ /*
|
|
|
+ * We need that spin_lock here - it prevents reordering between
|
|
|
+ * update of i_flctx->flc_posix 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 (f != filp) {
|
|
|
+ file_lock->fl_type = F_UNLCK;
|
|
|
+ error = do_lock_file_wait(filp, cmd, file_lock);
|
|
|
+ WARN_ON_ONCE(error);
|
|
|
+ error = -EBADF;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
out:
|
|
|
locks_free_lock(file_lock);
|
|
|
return error;
|