Skip to content

Commit 7ca132f

Browse files
author
Rafael Aquini
committed
fs: new helper: simple_rename_timestamp
JIRA: https://issues.redhat.com/browse/RHEL-27743 Conflicts: * include/linux/fs.h: minor context difference due to RHEL9 missing upstream commit e18275a ("fs: port ->rename() to pass mnt_idmap") This patch is a backport of the following upstream commit: commit 0c47679 Author: Jeff Layton <[email protected]> Date: Wed Jul 5 14:58:11 2023 -0400 fs: new helper: simple_rename_timestamp A rename potentially involves updating 4 different inode timestamps. Add a function that handles the details sanely, and convert the libfs.c callers to use it. Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Jan Kara <[email protected]> Message-Id: <[email protected]> Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: Rafael Aquini <[email protected]>
1 parent 2492503 commit 7ca132f

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

fs/libfs.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,31 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
446446
}
447447
EXPORT_SYMBOL(simple_rmdir);
448448

449+
/**
450+
* simple_rename_timestamp - update the various inode timestamps for rename
451+
* @old_dir: old parent directory
452+
* @old_dentry: dentry that is being renamed
453+
* @new_dir: new parent directory
454+
* @new_dentry: target for rename
455+
*
456+
* POSIX mandates that the old and new parent directories have their ctime and
457+
* mtime updated, and that inodes of @old_dentry and @new_dentry (if any), have
458+
* their ctime updated.
459+
*/
460+
void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
461+
struct inode *new_dir, struct dentry *new_dentry)
462+
{
463+
struct inode *newino = d_inode(new_dentry);
464+
465+
old_dir->i_mtime = inode_set_ctime_current(old_dir);
466+
if (new_dir != old_dir)
467+
new_dir->i_mtime = inode_set_ctime_current(new_dir);
468+
inode_set_ctime_current(d_inode(old_dentry));
469+
if (newino)
470+
inode_set_ctime_current(newino);
471+
}
472+
EXPORT_SYMBOL_GPL(simple_rename_timestamp);
473+
449474
int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
450475
struct inode *new_dir, struct dentry *new_dentry)
451476
{
@@ -461,11 +486,7 @@ int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
461486
inc_nlink(old_dir);
462487
}
463488
}
464-
old_dir->i_ctime = old_dir->i_mtime =
465-
new_dir->i_ctime = new_dir->i_mtime =
466-
d_inode(old_dentry)->i_ctime =
467-
d_inode(new_dentry)->i_ctime = current_time(old_dir);
468-
489+
simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
469490
return 0;
470491
}
471492
EXPORT_SYMBOL_GPL(simple_rename_exchange);
@@ -474,7 +495,6 @@ int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
474495
struct dentry *old_dentry, struct inode *new_dir,
475496
struct dentry *new_dentry, unsigned int flags)
476497
{
477-
struct inode *inode = d_inode(old_dentry);
478498
int they_are_dirs = d_is_dir(old_dentry);
479499

480500
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
@@ -497,9 +517,7 @@ int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
497517
inc_nlink(new_dir);
498518
}
499519

500-
old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
501-
new_dir->i_mtime = inode->i_ctime = current_time(old_dir);
502-
520+
simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
503521
return 0;
504522
}
505523
EXPORT_SYMBOL(simple_rename);

include/linux/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3424,6 +3424,8 @@ extern int simple_open(struct inode *inode, struct file *file);
34243424
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
34253425
extern int simple_unlink(struct inode *, struct dentry *);
34263426
extern int simple_rmdir(struct inode *, struct dentry *);
3427+
void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
3428+
struct inode *new_dir, struct dentry *new_dentry);
34273429
extern int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
34283430
struct inode *new_dir, struct dentry *new_dentry);
34293431
extern int simple_rename(struct user_namespace *, struct inode *,

0 commit comments

Comments
 (0)