From bd0d974d5e74b25b59cea4943dd99fc6e69e8e83 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Tue, 23 May 2023 14:55:14 +0800 Subject: [PATCH] hmdfs: cloud_merge rename Support recursively create parent dirs when rename a local file to different merge parent dirs. Signed-off-by: Qiheng Lin Change-Id: Idfcb99f2ab1db023942184c6153fef458f60b854 --- fs/hmdfs/hmdfs_merge_view.h | 11 ++++++ fs/hmdfs/inode_cloud_merge.c | 74 +++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/fs/hmdfs/hmdfs_merge_view.h b/fs/hmdfs/hmdfs_merge_view.h index 13c2666a91ee..1d7beae7147e 100644 --- a/fs/hmdfs/hmdfs_merge_view.h +++ b/fs/hmdfs/hmdfs_merge_view.h @@ -60,6 +60,14 @@ struct hmdfs_recursive_para { const char *name; }; +struct hmdfs_rename_para { + struct inode *old_dir; + struct dentry *old_dentry; + struct inode *new_dir; + struct dentry *new_dentry; + unsigned int flags; +}; + static inline struct hmdfs_dentry_info_merge *hmdfs_dm(struct dentry *dentry) { return dentry->d_fsdata; @@ -122,6 +130,9 @@ int hmdfs_unlink_merge(struct inode *dir, struct dentry *dentry); int hmdfs_rename_merge(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags); +int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags); static inline void destroy_comrade(struct hmdfs_dentry_comrade *comrade) { diff --git a/fs/hmdfs/inode_cloud_merge.c b/fs/hmdfs/inode_cloud_merge.c index b56ba87ba7e0..d8cbebe7f972 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -599,12 +599,84 @@ int hmdfs_create_cloud_merge(struct inode *dir, struct dentry *dentry, umode_t m return ret; } +static int rename_lo_d_cloud_child(struct hmdfs_rename_para *rename_para, + struct hmdfs_recursive_para *rec_op_para) +{ + struct dentry *d_pparent, *lo_d_parent; + struct dentry *d_parent = dget_parent(rename_para->new_dentry); + struct hmdfs_dentry_info_merge *pmdi = hmdfs_dm(d_parent); + int ret = 0; + + wait_event(pmdi->wait_queue, !has_merge_lookup_work(pmdi)); + + lo_d_parent = hmdfs_get_lo_d(d_parent, HMDFS_DEVID_LOCAL); + if (!lo_d_parent) { + d_pparent = dget_parent(d_parent); + ret = create_lo_d_parent_recur(d_pparent, d_parent, + d_inode(d_parent)->i_mode, + rec_op_para); + dput(d_pparent); + if (unlikely(ret)) + goto out; + lo_d_parent = hmdfs_get_lo_d(d_parent, HMDFS_DEVID_LOCAL); + if (!lo_d_parent) { + ret = -ENOENT; + goto out; + } + } + ret = do_rename_merge(rename_para->old_dir, rename_para->old_dentry, + rename_para->new_dir, rename_para->new_dentry, + rename_para->flags); + +out: + dput(d_parent); + dput(lo_d_parent); + return ret; +} + +static int hmdfs_rename_cloud_merge(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + unsigned int flags) +{ + struct hmdfs_recursive_para *rec_op_para = NULL; + struct hmdfs_rename_para rename_para = { old_dir, old_dentry, new_dir, + new_dentry, flags }; + int ret = 0; + + if (hmdfs_file_type(old_dentry->d_name.name) != HMDFS_TYPE_COMMON || + hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) { + ret = -EACCES; + goto rename_out; + } + rec_op_para = kmalloc(sizeof(*rec_op_para), GFP_KERNEL); + if (!rec_op_para) { + ret = -ENOMEM; + goto rename_out; + } + trace_hmdfs_rename_merge(old_dir, old_dentry, new_dir, new_dentry, + flags); + + hmdfs_init_recursive_para(rec_op_para, F_MKDIR_MERGE, 0, 0, NULL); + ret = rename_lo_d_cloud_child(&rename_para, rec_op_para); + if (ret != 0) + d_drop(new_dentry); + + if (S_ISREG(old_dentry->d_inode->i_mode) && !ret) + d_invalidate(old_dentry); +rename_out: + hmdfs_trace_rename_merge(old_dir, old_dentry, new_dir, new_dentry, ret); + kfree(rec_op_para); + return ret; +} + const struct inode_operations hmdfs_dir_iops_cloud_merge = { .lookup = hmdfs_lookup_cloud_merge, .mkdir = hmdfs_mkdir_cloud_merge, .create = hmdfs_create_cloud_merge, .rmdir = hmdfs_rmdir_merge, .unlink = hmdfs_unlink_merge, - .rename = hmdfs_rename_merge, + .rename = hmdfs_rename_cloud_merge, .permission = hmdfs_permission, }; -- Gitee