diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-11 20:00:22 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-11 20:00:22 -0800 |
commit | bf4e7080aeed29354cb156a8eb5d221ab2b6a8cc (patch) | |
tree | e73826bb1b0b9170a3f410ce622bf62774ecdbf1 /fs/ocfs2 | |
parent | 2f444347a8d6b03b4e6a9aeff13d67b8cbbe08ce (diff) | |
parent | a8b0026847b8c43445c921ad2c85521c92eb175f (diff) |
Merge tag 'pull-rename' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull rename updates from Al Viro:
"Fix directory locking scheme on rename
This was broken in 6.5; we really can't lock two unrelated directories
without holding ->s_vfs_rename_mutex first and in case of same-parent
rename of a subdirectory 6.5 ends up doing just that"
* tag 'pull-rename' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
rename(): avoid a deadlock in the case of parents having no common ancestor
kill lock_two_inodes()
rename(): fix the locking of subdirectories
f2fs: Avoid reading renamed directory if parent does not change
ext4: don't access the source subdirectory content on same-directory rename
ext2: Avoid reading renamed directory if parent does not change
udf_rename(): only access the child content on cross-directory rename
ocfs2: Avoid touching renamed directory if parent does not change
reiserfs: Avoid touching renamed directory if parent does not change
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/namei.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 814733ba2f4b..9221a33f917b 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1336,7 +1336,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, goto bail; } - if (S_ISDIR(old_inode->i_mode)) { + if (S_ISDIR(old_inode->i_mode) && new_dir != old_dir) { u64 old_inode_parent; update_dot_dot = 1; @@ -1353,8 +1353,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, goto bail; } - if (!new_inode && new_dir != old_dir && - new_dir->i_nlink >= ocfs2_link_max(osb)) { + if (!new_inode && new_dir->i_nlink >= ocfs2_link_max(osb)) { status = -EMLINK; goto bail; } @@ -1601,6 +1600,9 @@ static int ocfs2_rename(struct mnt_idmap *idmap, mlog_errno(status); goto bail; } + } + + if (S_ISDIR(old_inode->i_mode)) { drop_nlink(old_dir); if (new_inode) { drop_nlink(new_inode); |