Hi, Kent,

Give you a friendly ping.🙂

Thanks,
Hongbo

On 2024/7/5 15:19, Hongbo Li wrote:
As i_generation is used in bcachefs, updating this value by ioctl
(FS_IOC_SETVERSION) should be allowed. Here we implement this cmd
to support modify i_generation.

Signed-off-by: Hongbo Li <[email protected]>
---
  fs/bcachefs/fs-ioctl.c | 53 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
index aea8132d2c40..33728bbab778 100644
--- a/fs/bcachefs/fs-ioctl.c
+++ b/fs/bcachefs/fs-ioctl.c
@@ -277,6 +277,54 @@ static int bch2_ioc_getversion(struct bch_inode_info 
*inode, u32 __user *arg)
        return put_user(inode->v.i_generation, arg);
  }
+static int bch2_inode_version_set(struct btree_trans *trans,
+                                 struct bch_inode_info *inode,
+                                 struct bch_inode_unpacked *bi,
+                                 void *p)
+{
+       struct bch_fs *c = inode->v.i_sb->s_fs_info;
+       __u32 *generation = p;
+
+       inode->v.i_generation = bi->bi_generation = *generation;
+       bi->bi_ctime = timespec_to_bch2_time(c, current_time(&inode->v));
+
+       return 0;
+}
+
+static int bch2_ioc_setversion(struct bch_fs *c,
+                              struct file *file,
+                              struct bch_inode_info *inode,
+                              void __user *arg)
+{
+       int ret;
+       __u32 generation;
+
+       ret = mnt_want_write_file(file);
+       if (ret)
+               return ret;
+
+       inode_lock(&inode->v);
+       if (!inode_owner_or_capable(file_mnt_idmap(file), &inode->v)) {
+               ret = -EACCES;
+               goto setversion_out;
+       }
+
+       if (get_user(generation, (int __user *) arg)) {
+               ret = -EFAULT;
+               goto setversion_out;
+       }
+
+       mutex_lock(&inode->ei_update_lock);
+       ret = bch2_write_inode(c, inode, bch2_inode_version_set, &generation, 
ATTR_CTIME);
+       mutex_unlock(&inode->ei_update_lock);
+
+setversion_out:
+       inode_unlock(&inode->v);
+       mnt_drop_write_file(file);
+
+       return ret;
+}
+
  static int bch2_ioc_getlabel(struct bch_fs *c, char __user *user_label)
  {
        int ret;
@@ -567,7 +615,7 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
                break;
case FS_IOC_SETVERSION:
-               ret = -ENOTTY;
+               ret = bch2_ioc_setversion(c, file, inode, (int __user *) arg);
                break;
case FS_IOC_GETFSLABEL:
@@ -622,6 +670,9 @@ long bch2_compat_fs_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
        case FS_IOC32_GETVERSION:
                cmd = FS_IOC_GETVERSION;
                break;
+       case FS_IOC32_SETVERSION:
+               cmd = FS_IOC_SETVERSION;
+               break;
        case FS_IOC_GETFSLABEL:
        case FS_IOC_SETFSLABEL:
                break;

Reply via email to