From 528ad6537708f95b5aae44ec4ef409668dcc0801 Mon Sep 17 00:00:00 2001 From: fuletian Date: Fri, 29 Aug 2025 14:33:13 +0800 Subject: [PATCH] modify_realdst Signed-off-by: fuletian Change-Id: I3fc1731210bb550c6eb5228e0d6a63442e698f0c --- fs/hmdfs/hmdfs_merge_view.h | 2 +- fs/hmdfs/inode.c | 46 +++++++++++ fs/hmdfs/inode.h | 4 + fs/hmdfs/inode_cloud_merge.c | 105 ++++++++++-------------- fs/hmdfs/inode_merge.c | 153 +++++++++++++++-------------------- 5 files changed, 158 insertions(+), 152 deletions(-) diff --git a/fs/hmdfs/hmdfs_merge_view.h b/fs/hmdfs/hmdfs_merge_view.h index 940741a5b920..2218baec1ec8 100644 --- a/fs/hmdfs/hmdfs_merge_view.h +++ b/fs/hmdfs/hmdfs_merge_view.h @@ -112,7 +112,7 @@ void update_inode_attr(struct inode *inode, struct dentry *child_dentry); int get_num_comrades(struct dentry *dentry); void assign_comrades_unlocked(struct dentry *child_dentry, struct list_head *onstack_comrades_head); -struct hmdfs_dentry_comrade *lookup_comrade(struct path lower_path, +struct hmdfs_dentry_comrade *lookup_comrade(struct dentry *lower_dentry, const char *d_name, int dev_id, unsigned int flags); diff --git a/fs/hmdfs/inode.c b/fs/hmdfs/inode.c index 33cc8c7419d5..7132c30a12b6 100644 --- a/fs/hmdfs/inode.c +++ b/fs/hmdfs/inode.c @@ -4,6 +4,7 @@ * * Copyright (c) 2020-2021 Huawei Device Co., Ltd. */ +#include #include "hmdfs_device_view.h" #include "inode.h" @@ -354,4 +355,49 @@ void hmdfs_update_upper_file(struct file *upper_file, struct file *lower_file) i_size_write(upper_file->f_inode, lower_size); truncate_inode_pages(upper_file->f_inode->i_mapping, 0); } +} + +struct dentry *lookup_multi_dir(struct dentry *root_dentry, + const char *name, + unsigned int flags) +{ + struct dentry *current_dentry = root_dentry; + struct dentry *ret_dentry = NULL; + const char *start = name; + const char *end = NULL; + + while (*start == '/') + start = start + 1; + + if (*start) + dget(root_dentry); + + while (*start) { + if (*start == '/') { + start = start + 1; + continue; + } + end = strchr(start, '/'); + if (!end) + end = start + strlen(start); + inode_lock(d_inode(current_dentry)); + ret_dentry = lookup_one_len(start, current_dentry, end - start); + if (IS_ERR(ret_dentry) || d_is_negative(ret_dentry)) { + inode_unlock(d_inode(current_dentry)); + dput(current_dentry); + inode_unlock(current_dentry->d_inode); + return ret_dentry; + } + inode_unlock(d_inode(current_dentry)); + dput(current_dentry); + current_dentry = ret_dentry; + if (*end == '/') { + start = end + 1; + } else { + break; + } + } + if ((flags & LOOKUP_DIRECTORY) && ret_dentry != NULL && !d_can_lookup(ret_dentry)) + return -ENOTDIR; + return ret_dentry; } \ No newline at end of file diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index fb9bd2929d58..78346806c218 100644 --- a/fs/hmdfs/inode.h +++ b/fs/hmdfs/inode.h @@ -261,4 +261,8 @@ struct inode *hmdfs_iget5_locked_cloud(struct super_block *sb, void hmdfs_update_upper_file(struct file *upper_file, struct file *lower_file); uint32_t make_ino_raw_cloud(uint8_t *cloud_id); + +struct dentry *lookup_multi_dir(struct dentry *root_dentry, + const char *name, + unsigned int flags); #endif // INODE_H diff --git a/fs/hmdfs/inode_cloud_merge.c b/fs/hmdfs/inode_cloud_merge.c index a6f0b150fcfc..a57f61297e8f 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -94,28 +94,19 @@ cloud_merge_lookup_comrade(struct hmdfs_sb_info *sbi, int devid, unsigned int flags) { - int err; - struct path root, path; + struct dentry *dentry = NULL; struct hmdfs_dentry_comrade *comrade = NULL; - err = kern_path(sbi->real_dst, LOOKUP_DIRECTORY, &root); - if (err) { - comrade = ERR_PTR(err); - goto out; - } - - err = vfs_path_lookup(root.dentry, root.mnt, name, flags, &path); - if (err) { - comrade = ERR_PTR(err); - goto root_put; + dentry = lookup_multi_dir(sbi->sb->s_root, name, flags); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + if (d_is_negative(dentry)) { + dput(dentry); + return ERR_PTR(-ENOENT); } - comrade = alloc_comrade(path.dentry, devid); - - path_put(&path); -root_put: - path_put(&root); -out: + comrade = alloc_comrade(dentry, devid); + dput(dentry); return comrade; } @@ -202,7 +193,7 @@ static int lookup_merge_normal(struct dentry *dentry, unsigned int flags) * It's common for a network filesystem to incur various of faults, so we * intent to show mercy for faults here, except faults reported by the local. */ -static int do_lookup_cloud_merge_root(struct path path_dev, +static int do_lookup_cloud_merge_root(struct dentry *dentry_dev, struct dentry *child_dentry, unsigned int flags) { struct hmdfs_dentry_comrade *comrade; @@ -217,7 +208,7 @@ static int do_lookup_cloud_merge_root(struct path path_dev, // lookup real_dst/device_view/local memcpy(buf, DEVICE_VIEW_LOCAL, sizeof(DEVICE_VIEW_LOCAL)); - comrade = lookup_comrade(path_dev, buf, HMDFS_DEVID_LOCAL, flags); + comrade = lookup_comrade(dentry_dev, buf, HMDFS_DEVID_LOCAL, flags); if (IS_ERR(comrade)) { ret = PTR_ERR(comrade); goto out; @@ -226,7 +217,7 @@ static int do_lookup_cloud_merge_root(struct path path_dev, memcpy(buf, CLOUD_CID, 6); buf[5] = '\0'; - comrade = lookup_comrade(path_dev, buf, CLOUD_DEVICE, flags); + comrade = lookup_comrade(dentry_dev, buf, CLOUD_DEVICE, flags); if (IS_ERR(comrade)) { ret = 0; goto out; @@ -246,34 +237,21 @@ static int lookup_cloud_merge_root(struct inode *root_inode, struct dentry *child_dentry, unsigned int flags) { struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); - struct path path_dev; + struct dentry *dentry_dev = NULL; int ret = -ENOENT; - int buf_len; - char *buf = NULL; bool locked, down; - // consider additional one slash and one '\0' - buf_len = strlen(sbi->real_dst) + 1 + sizeof(DEVICE_VIEW_ROOT); - if (buf_len > PATH_MAX) - return -ENAMETOOLONG; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (unlikely(!buf)) - return -ENOMEM; - - sprintf(buf, "%s/%s", sbi->real_dst, DEVICE_VIEW_ROOT); - lock_root_inode_shared(root_inode, &locked, &down); - ret = hmdfs_get_path_in_sb(child_dentry->d_sb, buf, LOOKUP_DIRECTORY, - &path_dev); - if (ret) - goto free_buf; + dentry_dev = lookup_multi_dir(sbi->sb->s_root, DEVICE_VIEW_ROOT, flags); + if (IS_ERR(dentry_dev)) + return PTR_ERR(dentry_dev); + if (d_is_negative(dentry_dev)) { + dput(dentry_dev); + return -ENOENT; + } - ret = do_lookup_cloud_merge_root(path_dev, child_dentry, flags); - path_put(&path_dev); + ret = do_lookup_cloud_merge_root(dentry_dev, child_dentry, flags); + dput(dentry_dev); -free_buf: - kfree(buf); - restore_root_inode_sem(root_inode, locked, down); return ret; } @@ -414,7 +392,7 @@ int do_create_cloud_merge(struct inode *parent_inode, struct dentry *child_dentr } int hmdfs_do_ops_cloud_merge(struct inode *i_parent, struct dentry *d_child, - struct dentry *lo_d_child, struct path path, + struct dentry *lo_d_child, struct dentry *lo_d_parent, struct hmdfs_recursive_para *rec_op_para) { int ret = 0; @@ -424,20 +402,20 @@ int hmdfs_do_ops_cloud_merge(struct inode *i_parent, struct dentry *d_child, case F_MKDIR_MERGE: ret = do_mkdir_cloud_merge(i_parent, d_child, rec_op_para->mode, - d_inode(path.dentry), lo_d_child); + d_inode(lo_d_parent), lo_d_child); break; case F_CREATE_MERGE: ret = do_create_cloud_merge(i_parent, d_child, rec_op_para->mode, rec_op_para->want_excl, - d_inode(path.dentry), lo_d_child); + d_inode(lo_d_parent), lo_d_child); break; default: ret = -EINVAL; break; } } else { - ret = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), lo_d_child, + ret = vfs_mkdir(&nop_mnt_idmap, d_inode(lo_d_parent), lo_d_child, rec_op_para->mode); } if (ret) @@ -456,7 +434,6 @@ int hmdfs_create_lower_cloud_dentry(struct inode *i_parent, struct dentry *d_chi char *path_buf = kmalloc(PATH_MAX, GFP_KERNEL); char *absolute_path_buf = kmalloc(PATH_MAX, GFP_KERNEL); char *path_name = NULL; - struct path path = { .mnt = NULL, .dentry = NULL }; int ret = 0; if (unlikely(!path_buf || !absolute_path_buf)) { @@ -469,42 +446,44 @@ int hmdfs_create_lower_cloud_dentry(struct inode *i_parent, struct dentry *d_chi ret = PTR_ERR(path_name); goto out; } - if ((strlen(sbi->real_dst) + strlen(path_name) + - strlen(d_child->d_name.name) + 2) > PATH_MAX) { + if (strlen(path_name) + strlen(d_child->d_name.name) + 1 > PATH_MAX) { ret = -ENAMETOOLONG; goto out; } - sprintf(absolute_path_buf, "%s%s/%s", sbi->real_dst, path_name, - d_child->d_name.name); + sprintf(absolute_path_buf, "%s/%s", path_name, d_child->d_name.name); if (is_dir) - lo_d_child = kern_path_create(AT_FDCWD, absolute_path_buf, - &path, LOOKUP_DIRECTORY); + lo_d_child = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf, LOOKUP_DIRECTORY); else - lo_d_child = kern_path_create(AT_FDCWD, absolute_path_buf, - &path, 0); - if (IS_ERR(lo_d_child)) { + lo_d_child = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf, 0); + if (lo_d_child == NULL || IS_ERR(lo_d_child)) { ret = PTR_ERR(lo_d_child); goto out; } + if (d_is_positive(lo_d_child)) { + ret = -EEXIST; + goto out_put; + } + inode_lock(d_inode(lo_d_parent)); // to ensure link_comrade after vfs_mkdir succeed - ret = hmdfs_do_ops_cloud_merge(i_parent, d_child, lo_d_child, path, - rec_op_para); + ret = hmdfs_do_ops_cloud_merge(i_parent, d_child, lo_d_child, lo_d_parent, rec_op_para); if (ret) - goto out_put; + goto unlock; new_comrade = alloc_comrade(lo_d_child, HMDFS_DEVID_LOCAL); if (IS_ERR(new_comrade)) { ret = PTR_ERR(new_comrade); - goto out_put; + goto unlock; } else { link_comrade_unlocked(d_child, new_comrade); } update_inode_attr(d_inode(d_child), d_child); +unlock: + inode_unlock(d_inode(lo_d_parent)); out_put: - done_path_create(&path, lo_d_child); + dput(lo_d_child); out: kfree(absolute_path_buf); kfree(path_buf); diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 7c1e1e4f8539..cde7e0e00a3e 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -217,22 +217,24 @@ void assign_comrades_unlocked(struct dentry *child_dentry, mutex_unlock(&cdi->comrade_list_lock); } -struct hmdfs_dentry_comrade *lookup_comrade(struct path lower_path, +struct hmdfs_dentry_comrade *lookup_comrade(struct dentry *lower_dentry, const char *d_name, int dev_id, unsigned int flags) { - struct path path; + struct dentry *dentry = NULL; struct hmdfs_dentry_comrade *comrade = NULL; - int err; - err = vfs_path_lookup(lower_path.dentry, lower_path.mnt, d_name, flags, - &path); - if (err) - return ERR_PTR(err); + dentry = lookup_multi_dir(lower_dentry, d_name, flags); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + if (d_is_negative(dentry)) { + dput(dentry); + return ERR_PTR(-ENOENT); + } - comrade = alloc_comrade(path.dentry, dev_id); - path_put(&path); + comrade = alloc_comrade(dentry, dev_id); + dput(dentry); return comrade; } @@ -346,28 +348,23 @@ static struct hmdfs_dentry_comrade *merge_lookup_comrade( struct hmdfs_sb_info *sbi, const char *name, int devid, unsigned int flags) { - int err; - struct path root, path; + struct dentry *dentry = NULL; struct hmdfs_dentry_comrade *comrade = NULL; const struct cred *old_cred = hmdfs_override_creds(sbi->cred); - err = kern_path(sbi->real_dst, LOOKUP_DIRECTORY, &root); - if (err) { - comrade = ERR_PTR(err); + dentry = lookup_multi_dir(sbi->sb->s_root, name, flags); + if (IS_ERR(dentry)) { + comrade = ERR_CAST(dentry); goto out; } - - err = vfs_path_lookup(root.dentry, root.mnt, name, flags, &path); - if (err) { - comrade = ERR_PTR(err); - goto root_put; + if (d_is_negative(dentry)) { + dput(dentry); + return ERR_PTR(-ENOENT); } - - comrade = alloc_comrade(path.dentry, devid); - path_put(&path); -root_put: - path_put(&root); + comrade = alloc_comrade(dentry, devid); + dput(dentry); + out: hmdfs_revert_creds(old_cred); return comrade; @@ -550,7 +547,7 @@ static int lookup_merge_normal(struct dentry *dentry, unsigned int flags) * It's common for a network filesystem to incur various of faults, so we * intent to show mercy for faults here, except faults reported by the local. */ -static int do_lookup_merge_root(struct path path_dev, +static int do_lookup_merge_root(struct dentry *dentry_dev, struct dentry *child_dentry, unsigned int flags) { struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); @@ -567,7 +564,7 @@ static int do_lookup_merge_root(struct path path_dev, // lookup real_dst/device_view/local memcpy(buf, DEVICE_VIEW_LOCAL, sizeof(DEVICE_VIEW_LOCAL)); - comrade = lookup_comrade(path_dev, buf, HMDFS_DEVID_LOCAL, flags); + comrade = lookup_comrade(dentry_dev, buf, HMDFS_DEVID_LOCAL, flags); if (IS_ERR(comrade)) { ret = PTR_ERR(comrade); goto out; @@ -579,7 +576,7 @@ static int do_lookup_merge_root(struct path path_dev, list_for_each_entry(peer, &sbi->connections.node_list, list) { mutex_unlock(&sbi->connections.node_lock); memcpy(buf, peer->cid, HMDFS_CID_SIZE); - comrade = lookup_comrade(path_dev, buf, peer->device_id, flags); + comrade = lookup_comrade(dentry_dev, buf, peer->device_id, flags); if (IS_ERR(comrade)) continue; @@ -641,33 +638,25 @@ static int lookup_merge_root(struct inode *root_inode, struct dentry *child_dentry, unsigned int flags) { struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); - struct path path_dev; + struct dentry *dentry_dev = NULL; int ret = -ENOENT; - int buf_len; - char *buf = NULL; bool locked, down; - // consider additional one slash and one '\0' - buf_len = strlen(sbi->real_dst) + 1 + sizeof(DEVICE_VIEW_ROOT); - if (buf_len > PATH_MAX) - return -ENAMETOOLONG; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (unlikely(!buf)) - return -ENOMEM; - - sprintf(buf, "%s/%s", sbi->real_dst, DEVICE_VIEW_ROOT); lock_root_inode_shared(root_inode, &locked, &down); - ret = hmdfs_get_path_in_sb(child_dentry->d_sb, buf, LOOKUP_DIRECTORY, - &path_dev); - if (ret) - goto free_buf; + dentry_dev = lookup_multi_dir(sbi->sb->s_root, DEVICE_VIEW_ROOT, flags); + if (dentry_dev == NULL || IS_ERR(dentry_dev)) { + ret = PTR_ERR(dentry_dev); + goto out; + } + if (d_is_negative(dentry_dev)) { + dput(dentry_dev); + return ERR_PTR(-ENOENT); + } - ret = do_lookup_merge_root(path_dev, child_dentry, flags); - path_put(&path_dev); + ret = do_lookup_merge_root(dentry_dev, child_dentry, flags); + dput(dentry_dev); -free_buf: - kfree(buf); +out: restore_root_inode_sem(root_inode, locked, down); return ret; } @@ -893,7 +882,7 @@ int do_create_merge(struct inode *parent_inode, struct dentry *child_dentry, } int hmdfs_do_ops_merge(struct inode *i_parent, struct dentry *d_child, - struct dentry *lo_d_child, struct path path, + struct dentry *lo_d_child, struct dentry *lo_d_parent, struct hmdfs_recursive_para *rec_op_para) { int ret = 0; @@ -903,20 +892,20 @@ int hmdfs_do_ops_merge(struct inode *i_parent, struct dentry *d_child, case F_MKDIR_MERGE: ret = do_mkdir_merge(i_parent, d_child, rec_op_para->mode, - d_inode(path.dentry), lo_d_child); + d_inode(lo_d_parent), lo_d_child); break; case F_CREATE_MERGE: ret = do_create_merge(i_parent, d_child, rec_op_para->mode, rec_op_para->want_excl, - d_inode(path.dentry), lo_d_child); + d_inode(lo_d_parent), lo_d_child); break; default: ret = -EINVAL; break; } } else { - ret = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), lo_d_child, + ret = vfs_mkdir(&nop_mnt_idmap, d_inode(lo_d_parent), lo_d_child, rec_op_para->mode); } if (ret) @@ -935,7 +924,6 @@ int hmdfs_create_lower_dentry(struct inode *i_parent, struct dentry *d_child, char *path_buf = kmalloc(PATH_MAX, GFP_KERNEL); char *absolute_path_buf = kmalloc(PATH_MAX, GFP_KERNEL); char *path_name = NULL; - struct path path = { .mnt = NULL, .dentry = NULL }; int ret = 0; if (unlikely(!path_buf || !absolute_path_buf)) { @@ -948,42 +936,45 @@ int hmdfs_create_lower_dentry(struct inode *i_parent, struct dentry *d_child, ret = PTR_ERR(path_name); goto out; } - if ((strlen(sbi->real_dst) + strlen(path_name) + - strlen(d_child->d_name.name) + 2) > PATH_MAX) { + if ((strlen(path_name) + strlen(d_child->d_name.name) + 1) > PATH_MAX) { ret = -ENAMETOOLONG; goto out; } - sprintf(absolute_path_buf, "%s%s/%s", sbi->real_dst, path_name, - d_child->d_name.name); + sprintf(absolute_path_buf, "%s/%s", path_name, d_child->d_name.name); if (is_dir) - lo_d_child = kern_path_create(AT_FDCWD, absolute_path_buf, - &path, LOOKUP_DIRECTORY); + lo_d_child = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf, LOOKUP_DIRECTORY); else - lo_d_child = kern_path_create(AT_FDCWD, absolute_path_buf, - &path, 0); - if (IS_ERR(lo_d_child)) { + lo_d_child = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf, 0); + + if (lo_d_child == NULL == IS_ERR(lo_d_child)) { ret = PTR_ERR(lo_d_child); goto out; } + if (d_is_positive(lo_d_child)) { + ret = -EEXIST; + goto out_put; + } + inode_lock(d_inode(lo_d_parent)); // to ensure link_comrade after vfs_mkdir succeed - ret = hmdfs_do_ops_merge(i_parent, d_child, lo_d_child, path, - rec_op_para); + ret = hmdfs_do_ops_merge(i_parent, d_child, lo_d_child, lo_d_parent, rec_op_para); if (ret) - goto out_put; + goto unlock; new_comrade = alloc_comrade(lo_d_child, HMDFS_DEVID_LOCAL); if (IS_ERR(new_comrade)) { ret = PTR_ERR(new_comrade); - goto out_put; + goto unlock; } else { link_comrade_unlocked(d_child, new_comrade); } update_inode_attr(d_inode(d_child), d_child); +unlock: + inode_unlock(d_inode(lo_d_parent)); out_put: - done_path_create(&path, lo_d_child); + dput(lo_d_child); out: kfree(absolute_path_buf); kfree(path_buf); @@ -1242,7 +1233,6 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, struct hmdfs_sb_info *sbi = (old_dir->i_sb)->s_fs_info; struct hmdfs_dentry_info_merge *dim = hmdfs_dm(old_dentry); struct hmdfs_dentry_comrade *comrade = NULL, *new_comrade = NULL; - struct path lo_p_new = { .mnt = NULL, .dentry = NULL }; struct inode *lo_i_old_dir = NULL, *lo_i_new_dir = NULL; struct dentry *lo_d_old_dir = NULL, *lo_d_old = NULL, *lo_d_new_dir = NULL, *lo_d_new = NULL; @@ -1282,26 +1272,21 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, continue; } - if (strlen(sbi->real_dst) + strlen(path_name) + - strlen(new_dentry->d_name.name) + 2 > PATH_MAX) { + if (strlen(path_name) + strlen(new_dentry->d_name.name) + 1 > PATH_MAX) { ret = -ENAMETOOLONG; goto out; } - snprintf(abs_path_buf, PATH_MAX, "%s%s/%s", sbi->real_dst, - path_name, new_dentry->d_name.name); + snprintf(abs_path_buf, PATH_MAX, "%s/%s", path_name, new_dentry->d_name.name); if (S_ISDIR(d_inode(old_dentry)->i_mode)) - lo_d_new = kern_path_create(AT_FDCWD, abs_path_buf, - &lo_p_new, - LOOKUP_DIRECTORY); + lo_d_new = lookup_multi_dir(sbi->sb->s_root, abs_path_buf, LOOKUP_DIRECTORY); else - lo_d_new = kern_path_create(AT_FDCWD, abs_path_buf, - &lo_p_new, 0); - if (IS_ERR(lo_d_new)) { + lo_d_new = lookup_multi_dir(sbi->sb->s_root, abs_path_buf, 0); + + if (lo_d_new == NULL || IS_ERR(lo_d_new)) { ret = PTR_ERR(lo_d_new); goto out; } - lo_d_new_dir = dget_parent(lo_d_new); lo_i_new_dir = d_inode(lo_d_new_dir); lo_d_old_dir = dget_parent(lo_d_old); @@ -1316,15 +1301,7 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, rename_data.flags = flags; ret = vfs_rename(&rename_data); - new_comrade = alloc_comrade(lo_p_new.dentry, comrade->dev_id); - if (IS_ERR(new_comrade)) { - ret = PTR_ERR(new_comrade); - goto no_comrade; - } - - link_comrade_unlocked(new_dentry, new_comrade); -no_comrade: - done_path_create(&lo_p_new, lo_d_new); + dput(lo_d_new); dput(lo_d_old_dir); dput(lo_d_new_dir); } -- Gitee