Skip to content

Commit

Permalink
fat: add a vfat_rename2() and make existing .rename callback a helper
Browse files Browse the repository at this point in the history
Patch series "fat: add support for the renameat2 RENAME_EXCHANGE flag", v6.

The series adds support for the renameat2 system call RENAME_EXCHANGE flag
(which allows to atomically replace two paths) to the vfat filesystem
code.

There are many use cases for this, but we are particularly interested in
making possible for vfat filesystems to be part of OSTree [0] deployments.

Currently OSTree relies on symbolic links to make the deployment updates
an atomic transactional operation.  But RENAME_EXCHANGE could be used [1]
to achieve a similar level of robustness when using a vfat filesystem.

Patch #1 is just a preparatory patch to introduce the RENAME_EXCHANGE
support, patch #2 moves some code blocks in vfat_rename() to a set of
helper functions, that can be reused by tvfat_rename_exchange() that's
added by patch #3 and finally patch #4 adds some kselftests to test it.


This patch (of 4):

Currently vfat only supports the RENAME_NOREPLACE flag which is handled by
the virtual file system layer but doesn't support the RENAME_EXCHANGE
flag.

Add a vfat_rename2() function to be used as the .rename callback and move
the current vfat_rename() handler to a helper.  This is in preparation for
implementing the RENAME_NOREPLACE flag using a different helper function.

Link: https://lkml.kernel.org/r/[email protected]
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Javier Martinez Canillas <[email protected]>
Acked-by: OGAWA Hirofumi <[email protected]>
Cc: Christian Kellner <[email protected]>
Cc: Peter Jones <[email protected]>
Cc: Chung-Chiang Cheng <[email protected]>
Cc: Lennart Poettering <[email protected]>
Cc: Alexander Larsson <[email protected]>
Cc: Colin Walters <[email protected]>
Cc: Muhammad Usama Anjum <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
martinezjavier authored and akpm00 committed Jun 17, 2022
1 parent 1bb1a07 commit 019a0c9
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions fs/fat/namei_vfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,9 +889,8 @@ static int vfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
return err;
}

static int vfat_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
struct buffer_head *dotdot_bh;
struct msdos_dir_entry *dotdot_de;
Expand All @@ -902,9 +901,6 @@ static int vfat_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
int err, is_dir, update_dotdot, corrupt = 0;
struct super_block *sb = old_dir->i_sb;

if (flags & ~RENAME_NOREPLACE)
return -EINVAL;

old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = d_inode(old_dentry);
new_inode = d_inode(new_dentry);
Expand Down Expand Up @@ -1021,13 +1017,24 @@ static int vfat_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
goto out;
}

static int vfat_rename2(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;

/* VFS already handled RENAME_NOREPLACE, handle it as a normal rename */
return vfat_rename(old_dir, old_dentry, new_dir, new_dentry);
}

static const struct inode_operations vfat_dir_inode_operations = {
.create = vfat_create,
.lookup = vfat_lookup,
.unlink = vfat_unlink,
.mkdir = vfat_mkdir,
.rmdir = vfat_rmdir,
.rename = vfat_rename,
.rename = vfat_rename2,
.setattr = fat_setattr,
.getattr = fat_getattr,
.update_time = fat_update_time,
Expand Down

0 comments on commit 019a0c9

Please sign in to comment.