Skip to content

Commit e30ccbb

Browse files
konisakpm00
authored andcommitted
nilfs2: do not update mtime of renamed directory that is not moved
A minor issue with nilfs_rename, originating from an old ext2 implementation, is that the mtime is updated even if the rename target is a directory and it is renamed within the same directory, rather than moved to a different directory. In this case, the child directory being renamed does not change in any way, so changing its mtime is unnecessary according to the specification, and can unnecessarily confuse backup tools. In ext2, this issue was fixed by commit 39fe755 ("ext2: Do not update mtime of a moved directory") and a few subsequent fixes, but it remained in nilfs2. Fix this issue by not calling nilfs_set_link(), which rewrites the inode number of the directory entry that refers to the parent directory, when the move target is a directory and the source and destination are the same directory. Here, the directory to be moved only needs to be read if the inode number of the parent directory is rewritten with nilfs_set_link, so also adjust the execution conditions of the preparation work to avoid unnecessary directory reads. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ryusuke Konishi <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent ee70999 commit e30ccbb

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

fs/nilfs2/namei.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ static int nilfs_rename(struct mnt_idmap *idmap,
370370
struct folio *old_folio;
371371
struct nilfs_dir_entry *old_de;
372372
struct nilfs_transaction_info ti;
373+
bool old_is_dir = S_ISDIR(old_inode->i_mode);
373374
int err;
374375

375376
if (flags & ~RENAME_NOREPLACE)
@@ -385,7 +386,7 @@ static int nilfs_rename(struct mnt_idmap *idmap,
385386
goto out;
386387
}
387388

388-
if (S_ISDIR(old_inode->i_mode)) {
389+
if (old_is_dir && old_dir != new_dir) {
389390
err = -EIO;
390391
dir_de = nilfs_dotdot(old_inode, &dir_folio);
391392
if (!dir_de)
@@ -397,7 +398,7 @@ static int nilfs_rename(struct mnt_idmap *idmap,
397398
struct nilfs_dir_entry *new_de;
398399

399400
err = -ENOTEMPTY;
400-
if (dir_de && !nilfs_empty_dir(new_inode))
401+
if (old_is_dir && !nilfs_empty_dir(new_inode))
401402
goto out_dir;
402403

403404
new_de = nilfs_find_entry(new_dir, &new_dentry->d_name,
@@ -412,15 +413,15 @@ static int nilfs_rename(struct mnt_idmap *idmap,
412413
goto out_dir;
413414
nilfs_mark_inode_dirty(new_dir);
414415
inode_set_ctime_current(new_inode);
415-
if (dir_de)
416+
if (old_is_dir)
416417
drop_nlink(new_inode);
417418
drop_nlink(new_inode);
418419
nilfs_mark_inode_dirty(new_inode);
419420
} else {
420421
err = nilfs_add_link(new_dentry, old_inode);
421422
if (err)
422423
goto out_dir;
423-
if (dir_de) {
424+
if (old_is_dir) {
424425
inc_nlink(new_dir);
425426
nilfs_mark_inode_dirty(new_dir);
426427
}
@@ -434,9 +435,10 @@ static int nilfs_rename(struct mnt_idmap *idmap,
434435

435436
err = nilfs_delete_entry(old_de, old_folio);
436437
if (likely(!err)) {
437-
if (dir_de) {
438-
err = nilfs_set_link(old_inode, dir_de, dir_folio,
439-
new_dir);
438+
if (old_is_dir) {
439+
if (old_dir != new_dir)
440+
err = nilfs_set_link(old_inode, dir_de,
441+
dir_folio, new_dir);
440442
drop_nlink(old_dir);
441443
}
442444
nilfs_mark_inode_dirty(old_dir);

0 commit comments

Comments
 (0)