From: Linus Torvalds Date: Fri, 12 Jan 2024 04:00:22 +0000 (-0800) Subject: Merge tag 'pull-rename' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=bf4e7080aeed29354cb156a8eb5d221ab2b6a8cc;p=linux.git Merge tag 'pull-rename' of git://git./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 --- bf4e7080aeed29354cb156a8eb5d221ab2b6a8cc diff --cc Documentation/filesystems/porting.rst index ced3a67613293,33cd56e2ca1a5..c549fb2fc3ba7 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@@ -1064,12 -1064,27 +1064,39 @@@ generic_encode_ino32_fh() explicitly --- + **mandatory** + + If ->rename() update of .. on cross-directory move needs an exclusion with + directory modifications, do *not* lock the subdirectory in question in your + ->rename() - it's done by the caller now [that item should've been added in + 28eceeda130f "fs: Lock moved directories"]. + + --- + + **mandatory** + + On same-directory ->rename() the (tautological) update of .. is not protected + by any locks; just don't do it if the old parent is the same as the new one. + We really can't lock two subdirectories in same-directory rename - not without + deadlocks. + + --- + + **mandatory** + + lock_rename() and lock_rename_child() may fail in cross-directory case, if + their arguments do not have a common ancestor. In that case ERR_PTR(-EXDEV) + is returned, with no locks taken. In-tree users updated; out-of-tree ones + would need to do so. ++ ++--- ++ +**recommended** + +Block device freezing and thawing have been moved to holder operations. + +Before this change, get_active_super() would only be able to find the +superblock of the main block device, i.e., the one stored in sb->s_bdev. Block +device freezing now works for any block device owned by a given superblock, not +just the main block device. The get_active_super() helper and bd_fsfreeze_sb +pointer are gone. diff --cc fs/overlayfs/copy_up.c index 696478f09cc1b,e44dc5f661610..b8e25ca51016d --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@@ -779,13 -757,14 +779,15 @@@ static int ovl_copy_up_workdir(struct o * lock ordering with sb_writers, which shouldn't be held when calling * ovl_copy_up_data(), so lock workdir and destdir and make sure that * temp wasn't moved before copy up completion or cleanup. - * If temp was moved, abort without the cleanup. */ ovl_start_write(c->dentry); - if (lock_rename(c->workdir, c->destdir) != NULL || - temp->d_parent != c->workdir) { + trap = lock_rename(c->workdir, c->destdir); + if (trap || temp->d_parent != c->workdir) { + /* temp or workdir moved underneath us? abort without cleanup */ + dput(temp); err = -EIO; + if (IS_ERR(trap)) + goto out; goto unlock; } else if (err) { goto cleanup;