Skip to content

Commit dbd8132

Browse files
committed
Merge tag 'vfs-6.10-rc7.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner: "VFS: - Improve handling of deep ancestor chains in is_subdir() - Release locks cleanly when fctnl_setlk() races with close(). When setting a file lock fails the VFS tries to cleanup the already created lock. The helper used for this calls back into the LSM layer which may cause it to fail, leaving the stale lock accessible via /proc/locks. AFS: - Fix a comma/semicolon typo" * tag 'vfs-6.10-rc7.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: afs: Convert comma to semicolon fs: better handle deep ancestor chains in is_subdir() filelock: Remove locks reliably when fcntl/close race is detected
2 parents 7346105 + 655593a commit dbd8132

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

fs/afs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ static int afs_iget5_set_root(struct inode *inode, void *opaque)
512512
struct afs_vnode *vnode = AFS_FS_I(inode);
513513

514514
vnode->volume = as->volume;
515-
vnode->fid.vid = as->volume->vid,
515+
vnode->fid.vid = as->volume->vid;
516516
vnode->fid.vnode = 1;
517517
vnode->fid.unique = 1;
518518
inode->i_ino = 1;
@@ -545,7 +545,7 @@ struct inode *afs_root_iget(struct super_block *sb, struct key *key)
545545
BUG_ON(!(inode->i_state & I_NEW));
546546

547547
vnode = AFS_FS_I(inode);
548-
vnode->cb_v_check = atomic_read(&as->volume->cb_v_break),
548+
vnode->cb_v_check = atomic_read(&as->volume->cb_v_break);
549549
afs_set_netfs_context(vnode);
550550

551551
op = afs_alloc_operation(key, as->volume);

fs/dcache.c

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3029,28 +3029,25 @@ EXPORT_SYMBOL(d_splice_alias);
30293029

30303030
bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
30313031
{
3032-
bool result;
3032+
bool subdir;
30333033
unsigned seq;
30343034

30353035
if (new_dentry == old_dentry)
30363036
return true;
30373037

3038-
do {
3039-
/* for restarting inner loop in case of seq retry */
3040-
seq = read_seqbegin(&rename_lock);
3041-
/*
3042-
* Need rcu_readlock to protect against the d_parent trashing
3043-
* due to d_move
3044-
*/
3045-
rcu_read_lock();
3046-
if (d_ancestor(old_dentry, new_dentry))
3047-
result = true;
3048-
else
3049-
result = false;
3050-
rcu_read_unlock();
3051-
} while (read_seqretry(&rename_lock, seq));
3052-
3053-
return result;
3038+
/* Access d_parent under rcu as d_move() may change it. */
3039+
rcu_read_lock();
3040+
seq = read_seqbegin(&rename_lock);
3041+
subdir = d_ancestor(old_dentry, new_dentry);
3042+
/* Try lockless once... */
3043+
if (read_seqretry(&rename_lock, seq)) {
3044+
/* ...else acquire lock for progress even on deep chains. */
3045+
read_seqlock_excl(&rename_lock);
3046+
subdir = d_ancestor(old_dentry, new_dentry);
3047+
read_sequnlock_excl(&rename_lock);
3048+
}
3049+
rcu_read_unlock();
3050+
return subdir;
30543051
}
30553052
EXPORT_SYMBOL(is_subdir);
30563053

fs/locks.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,8 +2448,9 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
24482448
error = do_lock_file_wait(filp, cmd, file_lock);
24492449

24502450
/*
2451-
* Attempt to detect a close/fcntl race and recover by releasing the
2452-
* lock that was just acquired. There is no need to do that when we're
2451+
* Detect close/fcntl races and recover by zapping all POSIX locks
2452+
* associated with this file and our files_struct, just like on
2453+
* filp_flush(). There is no need to do that when we're
24532454
* unlocking though, or for OFD locks.
24542455
*/
24552456
if (!error && file_lock->c.flc_type != F_UNLCK &&
@@ -2464,9 +2465,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
24642465
f = files_lookup_fd_locked(files, fd);
24652466
spin_unlock(&files->file_lock);
24662467
if (f != filp) {
2467-
file_lock->c.flc_type = F_UNLCK;
2468-
error = do_lock_file_wait(filp, cmd, file_lock);
2469-
WARN_ON_ONCE(error);
2468+
locks_remove_posix(filp, files);
24702469
error = -EBADF;
24712470
}
24722471
}

0 commit comments

Comments
 (0)