From bab13bf829b08e977ebfabd7ca5bb1d4c08dcb92 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Tue, 4 Jul 2023 11:56:21 +0000 Subject: [PATCH 01/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/file_cloud.c | 2 +- fs/hmdfs/file_local.c | 1 + fs/hmdfs/file_remote.c | 1 + fs/hmdfs/hmdfs_dentryfile.c | 30 ++++- fs/hmdfs/hmdfs_dentryfile.h | 1 + fs/hmdfs/hmdfs_merge_view.h | 1 + fs/hmdfs/hmdfs_server.c | 219 ++++++++++++++++++++++++++++++++++-- fs/hmdfs/hmdfs_trace.h | 6 + fs/hmdfs/inode_local.c | 57 +++++++++- fs/hmdfs/inode_merge.c | 65 ++++++++++- fs/hmdfs/inode_remote.c | 9 +- fs/hmdfs/stash.c | 4 +- 12 files changed, 370 insertions(+), 26 deletions(-) diff --git a/fs/hmdfs/file_cloud.c b/fs/hmdfs/file_cloud.c index f4506ec1510d..e7db1a20f45c 100644 --- a/fs/hmdfs/file_cloud.c +++ b/fs/hmdfs/file_cloud.c @@ -81,7 +81,7 @@ int hmdfs_file_open_cloud(struct inode *inode, struct file *file) return -ENOENT; } - lower_file = file_open_root(&root_path, dir_path, + lower_file = file_open_root(root_path.dentry, root_path.mnt, dir_path, file->f_flags, file->f_mode); path_put(&root_path); if (IS_ERR(lower_file)) { diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index c4649bd20476..44207c6e55b9 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -220,6 +220,7 @@ static int hmdfs_iterate_local(struct file *file, struct dir_context *ctx) int err = 0; loff_t start_pos = ctx->pos; struct file *lower_file = hmdfs_f(file)->lower_file; + hmdfs_info("lzr hmdfs_iterate_local"); if (ctx->pos == -1) return 0; diff --git a/fs/hmdfs/file_remote.c b/fs/hmdfs/file_remote.c index aac6f508e18b..e5745e94d8bc 100644 --- a/fs/hmdfs/file_remote.c +++ b/fs/hmdfs/file_remote.c @@ -985,6 +985,7 @@ static int hmdfs_iterate_remote(struct file *file, struct dir_context *ctx) struct hmdfs_dentry_info *di = hmdfs_d(file->f_path.dentry); bool is_local = !((ctx->pos) >> (POS_BIT_NUM - 1)); uint64_t dev_id = di->device_id; + hmdfs_info("lzr hmdfs_iterate_remote"); if (ctx->pos == -1) return 0; diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index 01efcba2f6ce..7d3f0a82659a 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -579,6 +579,9 @@ int read_dentry(struct hmdfs_sb_info *sbi, char *file_name, else if (S_ISREG(le16_to_cpu( dentry_group->nsl[j].i_mode))) file_type = DT_REG; + else if (S_ISLNK(le16_to_cpu( + dentry_group->nsl[j].i_mode))) + file_type = DT_LNK; else continue; @@ -770,17 +773,25 @@ struct hmdfs_dentry *hmdfs_find_dentry(struct dentry *child_dentry, } void update_dentry(struct hmdfs_dentry_group *d, struct dentry *child_dentry, - struct inode *inode, __u32 name_hash, unsigned int bit_pos) + struct inode *inode, struct super_block *hmdfs_sb, + __u32 name_hash, unsigned int bit_pos) { struct hmdfs_dentry *de; + struct hmdfs_dentry_info *gdi; const struct qstr name = child_dentry->d_name; int slots = get_dentry_slots(name.len); int i; unsigned long ino; __u32 igen; - ino = inode->i_ino; - igen = inode->i_generation; + gdi = hmdfs_sb == child_dentry->d_sb ? hmdfs_d(child_dentry) : NULL; + if (!gdi && S_ISLNK(d_inode(child_dentry)->i_mode)) { + ino = d_inode(child_dentry)->i_ino; + igen = d_inode(child_dentry)->i_generation; + } else { + ino = inode->i_ino; + igen = inode->i_generation; + } de = &d->nsl[bit_pos]; de->hash = cpu_to_le32(name_hash); @@ -791,7 +802,13 @@ void update_dentry(struct hmdfs_dentry_group *d, struct dentry *child_dentry, de->i_size = cpu_to_le64(inode->i_size); de->i_ino = cpu_to_le64(generate_u64_ino(ino, igen)); de->i_flag = 0; - de->i_mode = cpu_to_le16(inode->i_mode); + + if (gdi && hm_islnk(gdi->file_type)) + de->i_mode = cpu_to_le16(S_IFLNK); + else if (!gdi && S_ISLNK(d_inode(child_dentry)->i_mode)) + de->i_mode = d_inode(child_dentry)->i_mode; + else + de->i_mode = cpu_to_le16(inode->i_mode); for (i = 0; i < slots; i++) { __set_bit_le(bit_pos + i, d->bitmap); @@ -902,7 +919,8 @@ int create_dentry(struct dentry *child_dentry, struct inode *inode, goto find; add: pos = get_dentry_group_pos(bidx); - update_dentry(dentry_blk, child_dentry, inode, namehash, bit_pos); + update_dentry(dentry_blk, child_dentry, inode, sbi->sb, namehash, + bit_pos); size = cache_file_write(sbi, file, dentry_blk, sizeof(struct hmdfs_dentry_group), &pos); if (size != sizeof(struct hmdfs_dentry_group)) @@ -1043,7 +1061,7 @@ struct file *create_local_dentry_file_cache(struct hmdfs_sb_info *sbi) goto out; } - filp = file_open_root(&cache_dir, ".", + filp = file_open_root(cache_dir.dentry, cache_dir.mnt, ".", O_RDWR | O_LARGEFILE | O_TMPFILE, DENTRY_FILE_PERM); if (IS_ERR(filp)) diff --git a/fs/hmdfs/hmdfs_dentryfile.h b/fs/hmdfs/hmdfs_dentryfile.h index 72bb5954a8b4..fd2bdddffcc8 100644 --- a/fs/hmdfs/hmdfs_dentryfile.h +++ b/fs/hmdfs/hmdfs_dentryfile.h @@ -193,6 +193,7 @@ struct getdents_callback_real { struct file *file; struct hmdfs_sb_info *sbi; const char *dir; + struct list_head dir_ents; }; struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, diff --git a/fs/hmdfs/hmdfs_merge_view.h b/fs/hmdfs/hmdfs_merge_view.h index aeda4127d1cc..1e7eedffa697 100644 --- a/fs/hmdfs/hmdfs_merge_view.h +++ b/fs/hmdfs/hmdfs_merge_view.h @@ -241,6 +241,7 @@ struct dentry *hmdfs_get_fst_lo_d(struct dentry *dentry); extern const struct inode_operations hmdfs_file_iops_merge; extern const struct file_operations hmdfs_file_fops_merge; +extern const struct inode_operations hmdfs_symlink_iops_merge; extern const struct inode_operations hmdfs_dir_iops_merge; extern const struct file_operations hmdfs_dir_fops_merge; extern const struct inode_operations hmdfs_file_iops_cloud_merge; diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 7e7460a7be6a..78a77b7c7e37 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -73,11 +73,44 @@ void remove_file_from_conn(struct hmdfs_peer *conn, __u32 file_id) spin_unlock(lock); } +struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, + const char *path) +{ + struct file *file; + int err; + const char *root_name = sbi->local_dst; + char *real_path; + int path_len; + + path_len = strlen(root_name) + strlen(path) + 2; + if (path_len > PATH_MAX) { + err = -EINVAL; + return ERR_PTR(err); + } + real_path = kzalloc(path_len, GFP_KERNEL); + if (!real_path) { + err = -ENOMEM; + return ERR_PTR(err); + } + + sprintf(real_path, "%s%s", root_name, path); + file = filp_open(real_path, O_RDWR | O_LARGEFILE, 0644); + if (IS_ERR(file)) { + hmdfs_info("filp_open failed: %ld", PTR_ERR(file)); + } else { + hmdfs_info("get file with magic %lu", + file->f_inode->i_sb->s_magic); + } + + kfree(real_path); + return file; +} + struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) { + int err; struct path root_path; struct file *file; - int err; const char *root_name = sbi->local_dst; err = kern_path(root_name, 0, &root_path); @@ -85,7 +118,7 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } - file = file_open_root(&root_path, path, + file = file_open_root(root_path.dentry, root_path.mnt, path, O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); if (IS_ERR(file)) { @@ -157,6 +190,38 @@ void __init hmdfs_server_add_node_evt_cb(void) hmdfs_node_add_evt_cb(server_cb, ARRAY_SIZE(server_cb)); } +static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, + uint64_t *ino) +{ + int ret = 0; + struct path root_path; + struct path dst_path; + struct inode *inode = NULL; + + ret = kern_path(con->sbi->local_dst, 0, &root_path); + if (ret) { + hmdfs_err("kern_path failed err = %d", ret); + return ret; + } + + ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, + &dst_path); + if (ret) { + path_put(&root_path); + return ret; + } + + inode = d_inode(dst_path.dentry); + if (con->sbi->sb == inode->i_sb) + inode = hmdfs_i(inode)->lower_inode; + *ino = generate_u64_ino(inode->i_ino, inode->i_generation); + + path_put(&dst_path); + path_put(&root_path); + + return 0; +} + static const char *datasl_str[] = { "s0", "s1", "s2", "s3", "s4" }; @@ -249,6 +314,9 @@ static struct file *hmdfs_open_file(struct hmdfs_peer *con, if (err) return ERR_PTR(err); } + + if (hm_islnk(file_type)) + file = hmdfs_open_link(con->sbi, filename); file = hmdfs_open_path(con->sbi, filename); if (IS_ERR(file)) { @@ -402,8 +470,14 @@ static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, info->stat_valid = true; } - info->real_ino = generate_u64_ino(info->inode->i_ino, - info->inode->i_generation); + if (hm_islnk(file_type)) { + ret = hmdfs_get_inode_by_name(con, filename, &info->real_ino); + if (ret) + return ret; + } else { + info->real_ino = generate_u64_ino(info->inode->i_ino, + info->inode->i_generation); + } return 0; } @@ -477,7 +551,8 @@ static int hmdfs_check_and_create(struct path *path_parent, } else { if (is_excl) err = -EEXIST; - else if (S_ISLNK(d_inode(dentry)->i_mode)) + else if (S_ISREG(d_inode(dentry)->i_mode) && + hm_islnk(hmdfs_d(dentry)->file_type)) err = -EINVAL; else if (S_ISDIR(d_inode(dentry)->i_mode)) err = -EISDIR; @@ -1149,6 +1224,50 @@ void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_send_err_response(con, cmd, err); } +static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, + ... ) +{ + int ret; + va_list args; + char *path = kmalloc(PATH_MAX, GFP_KERNEL); + + if (!path) + return -ENOMEM; + + va_start(args, path_fmt); + ret = vsnprintf(path, PATH_MAX, path_fmt, args); + va_end(args); + + if(ret >= PATH_MAX) { + ret = -ENAMETOOLONG; + goto out; + } + + ret = kern_path(path, LOOKUP_FOLLOW, link_path); + if (ret) { + hmdfs_err("kern_path failed err = %d", ret); + goto out; + } + + if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) { + hmdfs_err("path is dir symlink"); + path_put(link_path); + ret = -EOPNOTSUPP; + goto out; + } + +out: + kfree(path); + return ret; +} + +struct dir_entry_info { + struct list_head list; + char *name; + int name_len; + unsigned int d_type; +}; + static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, int name_len, loff_t offset, u64 ino, unsigned int d_type) @@ -1201,6 +1320,61 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, return 0; } +static void _do_create_dentry(struct getdents_callback_real *gc, + struct dir_entry_info *di) +{ + int res = 0; + struct dentry *child = NULL; + + inode_lock(d_inode(gc->parent_path->dentry)); + child = lookup_one_len(di->name, gc->parent_path->dentry, di->name_len); + inode_unlock(d_inode(gc->parent_path->dentry)); + if (IS_ERR(child)) { + res = PTR_ERR(child); + hmdfs_err("lookup faild because %d", res); + return; + } + + if (d_really_is_negative(child)) { + hmdfs_err("lookup faild because negative dentry"); + goto out; + } + + if (di->d_type == DT_REG || di->d_type == DT_DIR) { + create_dentry(child, d_inode(child), gc->file, gc->sbi); + gc->num++; + } else if (di->d_type == DT_LNK) { + struct path link_path; + + res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", + gc->sbi->local_src, gc->dir, + di->name); + if (!res) { + create_dentry(child, d_inode(link_path.dentry), + gc->file, gc->sbi); + path_put(&link_path); + gc->num++; + } else if (res == -ENOENT) { + create_dentry(child, d_inode(child), gc->file, gc->sbi); + gc->num++; + } + } +out: + dput(child); +} + +static void _gen_dir_dents_info(struct getdents_callback_real *gc) +{ + struct dir_entry_info *di = NULL, *tmp = NULL; + + list_for_each_entry_safe(di, tmp, &gc->dir_ents, list) { + _do_create_dentry(gc, di); + list_del(&di->list); + kfree(di->name); + kfree(di); + } +} + static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, struct file *file, struct file *dentry_file) { @@ -1249,8 +1423,10 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.parent_path = path; gc.file = dentry_file; + INIT_LIST_HEAD(&gc.dir_ents); err = iterate_dir(file, &(gc.ctx)); + _gen_dir_dents_info(&gc); if (err) { hmdfs_err("iterate_dir failed"); goto out; @@ -1315,6 +1491,27 @@ void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, hmdfs_server_check_writeback(hswb); } +static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, + const char *path_name, struct path *dst_path) +{ + struct path link_path; + int err; + + err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, + path_name); + if (err) + return err; + + if (d_inode(link_path.dentry)->i_sb != sbi->sb) { + path_put(dst_path); + *dst_path = link_path; + } else { + path_put(&link_path); + } + + return 0; +} + static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, struct super_block *sb) { @@ -1382,8 +1579,11 @@ void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } if (S_ISLNK(inode->i_mode)) { - err = -EPERM; - goto out_put_dst; + err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); + if(err == -ENOENT) + err = 0; + else if (err) + goto out_put_dst; } dentry = dst_path.dentry; @@ -1476,8 +1676,9 @@ void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, } if (S_ISLNK(inode->i_mode)) { - err = -EPERM; - goto out_put_dst; + err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); + if(err && err != -ENOENT) + goto out_put_dst; } err = vfs_getattr(&dst_path, &ks, STATX_BASIC_STATS | STATX_BTIME, 0); diff --git a/fs/hmdfs/hmdfs_trace.h b/fs/hmdfs/hmdfs_trace.h index 86478425aea8..dd89f750ccc5 100644 --- a/fs/hmdfs/hmdfs_trace.h +++ b/fs/hmdfs/hmdfs_trace.h @@ -203,6 +203,12 @@ define_hmdfs_lookup_op_end_event(hmdfs_mkdir_merge); define_hmdfs_lookup_op_end_event(hmdfs_rmdir_merge); define_hmdfs_lookup_op_end_event(hmdfs_create_merge); +define_hmdfs_lookup_op_end_event(hmdfs_symlink_merge); +define_hmdfs_lookup_op_end_event(hmdfs_symlink_local); + +define_hmdfs_lookup_op_end_event(hmdfs_get_link_merge); +define_hmdfs_lookup_op_end_event(hmdfs_get_link_local); + define_hmdfs_lookup_op_end_event(hmdfs_lookup_share); define_hmdfs_lookup_op_end_event(hmdfs_lookup_share_end); diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index 5d26f6dbbd02..c02302af238f 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -103,6 +103,9 @@ struct inode *fill_inode_local(struct super_block *sb, else if (S_ISREG(lower_inode->i_mode)) inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + else if (S_ISLNK(lower_inode->i_mode)) + inode->i_mode = + S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; #ifdef CONFIG_HMDFS_FS_PERMISSION inode->i_uid = lower_inode->i_uid; @@ -124,6 +127,10 @@ struct inode *fill_inode_local(struct super_block *sb, } else if (S_ISREG(lower_inode->i_mode)) { inode->i_op = &hmdfs_file_iops_local; inode->i_fop = &hmdfs_file_fops_local; + } else if (S_ISLNK(lower_inode->i_mode)) { + inode->i_op = &hmdfs_symlink_iops_local; + inode->i_fop = &hmdfs_file_fops_local; + inode->i_size = i_size_read(lower_inode); } else { ret = -EIO; goto bad_inode; @@ -217,6 +224,12 @@ static int __lookup_nosensitive(struct path *lower_parent_path, return err; } +static inline void set_symlink_flag(struct hmdfs_dentry_info *gdi) +{ + gdi->file_type = HM_SYMLINK; +} + + struct dentry *hmdfs_lookup_local(struct inode *parent_inode, struct dentry *child_dentry, unsigned int flags) @@ -261,7 +274,8 @@ struct dentry *hmdfs_lookup_local(struct inode *parent_inode, child_inode = fill_inode_local(parent_inode->i_sb, d_inode(lower_path.dentry), child_dentry->d_name.name); - + if (S_ISLNK(d_inode(lower_path.dentry)->i_mode)) + set_symlink_flag(gdi); if (IS_ERR(child_inode)) { err = PTR_ERR(child_inode); ret = ERR_PTR(err); @@ -726,6 +740,40 @@ int hmdfs_rename_local(struct inode *old_dir, struct dentry *old_dentry, return err; } +static const char *hmdfs_get_link_local(struct dentry *dentry, + struct inode *inode, + struct delayed_call *done) +{ + const char *link = NULL; + struct dentry *lower_dentry = NULL; + struct inode *lower_inode = NULL; + struct path lower_path; + + if(!dentry) { + hmdfs_err("dentry MULL"); + link = ERR_PTR(-ECHILD); + goto link_out; + } + + hmdfs_get_lower_path(dentry, &lower_path); + lower_dentry = lower_path.dentry; + lower_inode = d_inode(lower_dentry); + if(!lower_inode->i_op || !lower_inode->i_op->get_link) { + hmdfs_err("The lower inode doesn't support get_link i_op"); + link = ERR_PTR(-EINVAL); + goto out; + } + + link = lower_inode->i_op->get_link(lower_dentry, lower_inode, done); + if(IS_ERR_OR_NULL(link)) + goto out; + fsstack_copy_attr_atime(inode, lower_inode); +out: + hmdfs_put_lower_path(&lower_path); +link_out: + return link; +} + static int hmdfs_setattr_local(struct dentry *dentry, struct iattr *ia) { struct inode *inode = d_inode(dentry); @@ -779,6 +827,7 @@ static int hmdfs_getattr_local(const struct path *path, struct kstat *stat, stat->gid = d_inode(path->dentry)->i_gid; hmdfs_put_lower_path(&lower_path); + hmdfs_info("hmdfs_getattr_local, ret: %d", ret); return ret; } @@ -899,6 +948,12 @@ const struct inode_operations hmdfs_dir_inode_ops_local = { .getattr = hmdfs_getattr_local, }; +const struct inode_operations hmdfs_symlink_iops_local = { + .get_link = hmdfs_get_link_local, + .permission = hmdfs_permission, + .setattr = hmdfs_setattr_local, +}; + const struct inode_operations hmdfs_dir_inode_ops_share = { .lookup = hmdfs_lookup_share, .permission = hmdfs_permission, diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 17a7af217d8d..96f83b8539da 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -109,9 +109,9 @@ static struct inode *fill_inode_merge(struct super_block *sb, if (lo_d_dentry) { fst_lo_d = lo_d_dentry; dget(fst_lo_d); - } else { + } else fst_lo_d = hmdfs_get_fst_lo_d(child_dentry); - } + if (!fst_lo_d) { inode = ERR_PTR(-EINVAL); goto out; @@ -119,15 +119,20 @@ static struct inode *fill_inode_merge(struct super_block *sb, if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_MERGE, NULL, NULL); + else inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); + if (!inode) { hmdfs_err("iget5_locked get inode NULL"); inode = ERR_PTR(-ENOMEM); goto out; } - if (!(inode->i_state & I_NEW)) + if (!(inode->i_state & I_NEW)){ + hmdfs_err("lzr !(inode->i_state & I_NEW)"); goto out; + } + info = hmdfs_i(inode); if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) info->inode_type = HMDFS_LAYER_FIRST_MERGE; @@ -140,7 +145,14 @@ static struct inode *fill_inode_merge(struct super_block *sb, update_inode_attr(inode, child_dentry); mode = d_inode(fst_lo_d)->i_mode; - if (S_ISREG(mode)) { + + if (hm_islnk(hmdfs_d(fst_lo_d)->file_type) && + hmdfs_d(fst_lo_d)->device_id == 0) { + inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + inode->i_op = &hmdfs_symlink_iops_merge; + inode->i_fop = &hmdfs_file_fops_merge; + set_nlink(inode, 1); + } else if (S_ISREG(mode)) { inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; inode->i_op = &hmdfs_file_iops_merge; inode->i_fop = &hmdfs_file_fops_merge; @@ -725,6 +737,7 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, err = init_hmdfs_dentry_info_merge(sbi, child_dentry); if (unlikely(err)) goto out; + if (pii->inode_type == HMDFS_LAYER_ZERO) { hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_FIRST_MERGE; @@ -760,7 +773,7 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, if ((err == -ENOENT) && create) err = 0; - + out: hmdfs_trace_merge(trace_hmdfs_lookup_merge_end, parent_inode, child_dentry, err); @@ -1385,6 +1398,48 @@ int hmdfs_rename_merge(struct inode *old_dir, struct dentry *old_dentry, return ret; } +static const char *hmdfs_get_link_merge(struct dentry *dentry, + struct inode *inode, + struct delayed_call *done) +{ + const char *link = NULL; + struct dentry *lower_dentry = NULL; + struct inode *lower_inode = NULL; + + if(!dentry) { + hmdfs_err("dentry MULL"); + link = ERR_PTR(-EINVAL); + goto link_out; + } + + lower_dentry = hmdfs_get_fst_lo_d(dentry); + if(!lower_dentry) { + WARN_ON(1); + link = ERR_PTR(-EINVAL); + goto out; + } + lower_inode = d_inode(lower_dentry); + if(!lower_inode->i_op || !lower_inode->i_op->get_link) { + hmdfs_err("lower inode hold no operations"); + link = ERR_PTR(-EINVAL); + goto out; + } + + link = lower_inode->i_op->get_link(lower_dentry, lower_inode, done); + if(IS_ERR_OR_NULL(link)) + goto out; + fsstack_copy_attr_atime(inode, lower_inode); +out: + dput(lower_dentry); +link_out: + return link; +} + +const struct inode_operations hmdfs_symlink_iops_merge = { + .get_link = hmdfs_get_link_merge, + .permission = hmdfs_permission, +}; + const struct inode_operations hmdfs_dir_iops_merge = { .lookup = hmdfs_lookup_merge, .mkdir = hmdfs_mkdir_merge, diff --git a/fs/hmdfs/inode_remote.c b/fs/hmdfs/inode_remote.c index 2670e3e81891..8ac934dbbdc6 100644 --- a/fs/hmdfs/inode_remote.c +++ b/fs/hmdfs/inode_remote.c @@ -375,12 +375,15 @@ struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con, inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH; else if (S_ISREG(mode)) inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + else if (S_ISLNK(mode)) + inode->i_mode = S_IFREG | S_IRWXU | S_IRWXG; else { + hmdfs_info("fill_inode_remote: ret=%d", -EIO); ret = -EIO; goto bad_inode; } - if (S_ISREG(mode)) { + if (S_ISREG(mode) || S_ISLNK(mode)) { inode->i_op = con->conn_operations->remote_file_iops; inode->i_fop = con->conn_operations->remote_file_fops; inode->i_size = res->i_size; @@ -446,7 +449,9 @@ static struct dentry *hmdfs_lookup_remote_dentry(struct inode *parent_inode, lookup_result = hmdfs_lookup_by_con(con, child_dentry, &qstr, flags, relative_path); if (lookup_result != NULL) { - if (in_share_dir(child_dentry)) + if (S_ISLNK(lookup_result->i_mode)) + gdi->file_type = HM_SYMLINK; + else if (in_share_dir(child_dentry)) gdi->file_type = HM_SHARE; inode = fill_inode_remote(sb, con, lookup_result, parent_inode); ret = d_splice_alias(inode, child_dentry); diff --git a/fs/hmdfs/stash.c b/fs/hmdfs/stash.c index 413720404cc7..1ac2580afffa 100644 --- a/fs/hmdfs/stash.c +++ b/fs/hmdfs/stash.c @@ -1261,7 +1261,7 @@ static int hmdfs_open_restore_dst_file(struct hmdfs_file_restore_ctx *ctx, goto out; /* Error comes from connection or server ? */ - dst = file_open_root(&ctx->dst_root_path, + dst = file_open_root(ctx->dst_root_path.dentry, ctx->dst_root_path.mnt, ctx->dst, O_LARGEFILE | rw_flag, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); @@ -2179,7 +2179,7 @@ hmdfs_need_rebuild_inode_stash_status(struct hmdfs_peer *conn, umode_t mode) { return hmdfs_is_stash_enabled(conn->sbi) && READ_ONCE(conn->need_rebuild_stash_list) && - S_ISREG(mode); + (S_ISREG(mode) || S_ISLNK(mode)); } void hmdfs_remote_init_stash_status(struct hmdfs_peer *conn, -- Gitee From 5dff9a5cb2754b3a45fc9fd0dbb963b4d20b7965 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Tue, 4 Jul 2023 12:02:06 +0000 Subject: [PATCH 02/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/file_cloud.c | 2 +- fs/hmdfs/file_local.c | 3 +-- fs/hmdfs/file_remote.c | 1 - fs/hmdfs/hmdfs_dentryfile.c | 2 +- fs/hmdfs/hmdfs_server.c | 2 +- fs/hmdfs/inode_merge.c | 4 +--- fs/hmdfs/stash.c | 2 +- 7 files changed, 6 insertions(+), 10 deletions(-) diff --git a/fs/hmdfs/file_cloud.c b/fs/hmdfs/file_cloud.c index e7db1a20f45c..f4506ec1510d 100644 --- a/fs/hmdfs/file_cloud.c +++ b/fs/hmdfs/file_cloud.c @@ -81,7 +81,7 @@ int hmdfs_file_open_cloud(struct inode *inode, struct file *file) return -ENOENT; } - lower_file = file_open_root(root_path.dentry, root_path.mnt, dir_path, + lower_file = file_open_root(&root_path, dir_path, file->f_flags, file->f_mode); path_put(&root_path); if (IS_ERR(lower_file)) { diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 44207c6e55b9..084992336f65 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -220,8 +220,7 @@ static int hmdfs_iterate_local(struct file *file, struct dir_context *ctx) int err = 0; loff_t start_pos = ctx->pos; struct file *lower_file = hmdfs_f(file)->lower_file; - hmdfs_info("lzr hmdfs_iterate_local"); - + if (ctx->pos == -1) return 0; diff --git a/fs/hmdfs/file_remote.c b/fs/hmdfs/file_remote.c index e5745e94d8bc..aac6f508e18b 100644 --- a/fs/hmdfs/file_remote.c +++ b/fs/hmdfs/file_remote.c @@ -985,7 +985,6 @@ static int hmdfs_iterate_remote(struct file *file, struct dir_context *ctx) struct hmdfs_dentry_info *di = hmdfs_d(file->f_path.dentry); bool is_local = !((ctx->pos) >> (POS_BIT_NUM - 1)); uint64_t dev_id = di->device_id; - hmdfs_info("lzr hmdfs_iterate_remote"); if (ctx->pos == -1) return 0; diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index 7d3f0a82659a..84eedab9545f 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -1061,7 +1061,7 @@ struct file *create_local_dentry_file_cache(struct hmdfs_sb_info *sbi) goto out; } - filp = file_open_root(cache_dir.dentry, cache_dir.mnt, ".", + filp = file_open_root(&cache_dir.dentry, ".", O_RDWR | O_LARGEFILE | O_TMPFILE, DENTRY_FILE_PERM); if (IS_ERR(filp)) diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 78a77b7c7e37..5211a9113512 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -118,7 +118,7 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } - file = file_open_root(root_path.dentry, root_path.mnt, path, + file = file_open_root(&root_path.dentry, path, O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); if (IS_ERR(file)) { diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 96f83b8539da..182372ad5ea2 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -128,10 +128,8 @@ static struct inode *fill_inode_merge(struct super_block *sb, inode = ERR_PTR(-ENOMEM); goto out; } - if (!(inode->i_state & I_NEW)){ - hmdfs_err("lzr !(inode->i_state & I_NEW)"); + if (!(inode->i_state & I_NEW)) goto out; - } info = hmdfs_i(inode); if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) diff --git a/fs/hmdfs/stash.c b/fs/hmdfs/stash.c index 1ac2580afffa..8bdc6937f2da 100644 --- a/fs/hmdfs/stash.c +++ b/fs/hmdfs/stash.c @@ -1261,7 +1261,7 @@ static int hmdfs_open_restore_dst_file(struct hmdfs_file_restore_ctx *ctx, goto out; /* Error comes from connection or server ? */ - dst = file_open_root(ctx->dst_root_path.dentry, ctx->dst_root_path.mnt, + dst = file_open_root(&ctx->dst_root_path.dentry, ctx->dst, O_LARGEFILE | rw_flag, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); -- Gitee From 44ca8810ca74d120cefacdb1e826f4f1e14738f1 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Tue, 4 Jul 2023 13:46:29 +0000 Subject: [PATCH 03/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/hmdfs_merge_view.h | 1 - fs/hmdfs/hmdfs_trace.h | 2 -- fs/hmdfs/inode_merge.c | 55 ++----------------------------------- fs/hmdfs/stash.c | 2 +- 4 files changed, 3 insertions(+), 57 deletions(-) diff --git a/fs/hmdfs/hmdfs_merge_view.h b/fs/hmdfs/hmdfs_merge_view.h index 1e7eedffa697..aeda4127d1cc 100644 --- a/fs/hmdfs/hmdfs_merge_view.h +++ b/fs/hmdfs/hmdfs_merge_view.h @@ -241,7 +241,6 @@ struct dentry *hmdfs_get_fst_lo_d(struct dentry *dentry); extern const struct inode_operations hmdfs_file_iops_merge; extern const struct file_operations hmdfs_file_fops_merge; -extern const struct inode_operations hmdfs_symlink_iops_merge; extern const struct inode_operations hmdfs_dir_iops_merge; extern const struct file_operations hmdfs_dir_fops_merge; extern const struct inode_operations hmdfs_file_iops_cloud_merge; diff --git a/fs/hmdfs/hmdfs_trace.h b/fs/hmdfs/hmdfs_trace.h index dd89f750ccc5..4206e5ca0b1d 100644 --- a/fs/hmdfs/hmdfs_trace.h +++ b/fs/hmdfs/hmdfs_trace.h @@ -205,8 +205,6 @@ define_hmdfs_lookup_op_end_event(hmdfs_create_merge); define_hmdfs_lookup_op_end_event(hmdfs_symlink_merge); define_hmdfs_lookup_op_end_event(hmdfs_symlink_local); - -define_hmdfs_lookup_op_end_event(hmdfs_get_link_merge); define_hmdfs_lookup_op_end_event(hmdfs_get_link_local); define_hmdfs_lookup_op_end_event(hmdfs_lookup_share); diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 182372ad5ea2..ecda32c65b93 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -111,7 +111,6 @@ static struct inode *fill_inode_merge(struct super_block *sb, dget(fst_lo_d); } else fst_lo_d = hmdfs_get_fst_lo_d(child_dentry); - if (!fst_lo_d) { inode = ERR_PTR(-EINVAL); goto out; @@ -119,10 +118,8 @@ static struct inode *fill_inode_merge(struct super_block *sb, if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_MERGE, NULL, NULL); - else - inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); - + inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); if (!inode) { hmdfs_err("iget5_locked get inode NULL"); inode = ERR_PTR(-ENOMEM); @@ -144,13 +141,7 @@ static struct inode *fill_inode_merge(struct super_block *sb, mode = d_inode(fst_lo_d)->i_mode; - if (hm_islnk(hmdfs_d(fst_lo_d)->file_type) && - hmdfs_d(fst_lo_d)->device_id == 0) { - inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; - inode->i_op = &hmdfs_symlink_iops_merge; - inode->i_fop = &hmdfs_file_fops_merge; - set_nlink(inode, 1); - } else if (S_ISREG(mode)) { + if (S_ISREG(mode)) { inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; inode->i_op = &hmdfs_file_iops_merge; inode->i_fop = &hmdfs_file_fops_merge; @@ -1396,48 +1387,6 @@ int hmdfs_rename_merge(struct inode *old_dir, struct dentry *old_dentry, return ret; } -static const char *hmdfs_get_link_merge(struct dentry *dentry, - struct inode *inode, - struct delayed_call *done) -{ - const char *link = NULL; - struct dentry *lower_dentry = NULL; - struct inode *lower_inode = NULL; - - if(!dentry) { - hmdfs_err("dentry MULL"); - link = ERR_PTR(-EINVAL); - goto link_out; - } - - lower_dentry = hmdfs_get_fst_lo_d(dentry); - if(!lower_dentry) { - WARN_ON(1); - link = ERR_PTR(-EINVAL); - goto out; - } - lower_inode = d_inode(lower_dentry); - if(!lower_inode->i_op || !lower_inode->i_op->get_link) { - hmdfs_err("lower inode hold no operations"); - link = ERR_PTR(-EINVAL); - goto out; - } - - link = lower_inode->i_op->get_link(lower_dentry, lower_inode, done); - if(IS_ERR_OR_NULL(link)) - goto out; - fsstack_copy_attr_atime(inode, lower_inode); -out: - dput(lower_dentry); -link_out: - return link; -} - -const struct inode_operations hmdfs_symlink_iops_merge = { - .get_link = hmdfs_get_link_merge, - .permission = hmdfs_permission, -}; - const struct inode_operations hmdfs_dir_iops_merge = { .lookup = hmdfs_lookup_merge, .mkdir = hmdfs_mkdir_merge, diff --git a/fs/hmdfs/stash.c b/fs/hmdfs/stash.c index 8bdc6937f2da..e59499f5dcdc 100644 --- a/fs/hmdfs/stash.c +++ b/fs/hmdfs/stash.c @@ -1261,7 +1261,7 @@ static int hmdfs_open_restore_dst_file(struct hmdfs_file_restore_ctx *ctx, goto out; /* Error comes from connection or server ? */ - dst = file_open_root(&ctx->dst_root_path.dentry, + dst = file_open_root(&ctx->dst_root_path, ctx->dst, O_LARGEFILE | rw_flag, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); -- Gitee From ddf377c8d020ec76f99ec78449232cd8b62a0acc Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 03:01:04 +0000 Subject: [PATCH 04/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/file_local.c | 2 +- fs/hmdfs/hmdfs_dentryfile.h | 1 - fs/hmdfs/hmdfs_server.c | 57 ------------------------------------- 3 files changed, 1 insertion(+), 59 deletions(-) diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index 084992336f65..c4649bd20476 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -220,7 +220,7 @@ static int hmdfs_iterate_local(struct file *file, struct dir_context *ctx) int err = 0; loff_t start_pos = ctx->pos; struct file *lower_file = hmdfs_f(file)->lower_file; - + if (ctx->pos == -1) return 0; diff --git a/fs/hmdfs/hmdfs_dentryfile.h b/fs/hmdfs/hmdfs_dentryfile.h index fd2bdddffcc8..72bb5954a8b4 100644 --- a/fs/hmdfs/hmdfs_dentryfile.h +++ b/fs/hmdfs/hmdfs_dentryfile.h @@ -193,7 +193,6 @@ struct getdents_callback_real { struct file *file; struct hmdfs_sb_info *sbi; const char *dir; - struct list_head dir_ents; }; struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 5211a9113512..d8f78a2a9439 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -1320,61 +1320,6 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, return 0; } -static void _do_create_dentry(struct getdents_callback_real *gc, - struct dir_entry_info *di) -{ - int res = 0; - struct dentry *child = NULL; - - inode_lock(d_inode(gc->parent_path->dentry)); - child = lookup_one_len(di->name, gc->parent_path->dentry, di->name_len); - inode_unlock(d_inode(gc->parent_path->dentry)); - if (IS_ERR(child)) { - res = PTR_ERR(child); - hmdfs_err("lookup faild because %d", res); - return; - } - - if (d_really_is_negative(child)) { - hmdfs_err("lookup faild because negative dentry"); - goto out; - } - - if (di->d_type == DT_REG || di->d_type == DT_DIR) { - create_dentry(child, d_inode(child), gc->file, gc->sbi); - gc->num++; - } else if (di->d_type == DT_LNK) { - struct path link_path; - - res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", - gc->sbi->local_src, gc->dir, - di->name); - if (!res) { - create_dentry(child, d_inode(link_path.dentry), - gc->file, gc->sbi); - path_put(&link_path); - gc->num++; - } else if (res == -ENOENT) { - create_dentry(child, d_inode(child), gc->file, gc->sbi); - gc->num++; - } - } -out: - dput(child); -} - -static void _gen_dir_dents_info(struct getdents_callback_real *gc) -{ - struct dir_entry_info *di = NULL, *tmp = NULL; - - list_for_each_entry_safe(di, tmp, &gc->dir_ents, list) { - _do_create_dentry(gc, di); - list_del(&di->list); - kfree(di->name); - kfree(di); - } -} - static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, struct file *file, struct file *dentry_file) { @@ -1423,10 +1368,8 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.parent_path = path; gc.file = dentry_file; - INIT_LIST_HEAD(&gc.dir_ents); err = iterate_dir(file, &(gc.ctx)); - _gen_dir_dents_info(&gc); if (err) { hmdfs_err("iterate_dir failed"); goto out; -- Gitee From 34f829a6fcc797773583067ae3303aee1ee67499 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 06:51:20 +0000 Subject: [PATCH 05/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/hmdfs_server.c | 79 +++++++++++++++++++++++++++++++++++++++-- fs/hmdfs/inode_local.c | 3 +- fs/hmdfs/inode_merge.c | 7 ++-- fs/hmdfs/stash.c | 2 +- 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index d8f78a2a9439..6e0e5e079036 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -118,7 +118,7 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } - file = file_open_root(&root_path.dentry, path, + file = file_open_root(root_path.dentry, root_path.mnt, path, O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); if (IS_ERR(file)) { @@ -317,7 +317,8 @@ static struct file *hmdfs_open_file(struct hmdfs_peer *con, if (hm_islnk(file_type)) file = hmdfs_open_link(con->sbi, filename); - file = hmdfs_open_path(con->sbi, filename); + else + file = hmdfs_open_path(con->sbi, filename); if (IS_ERR(file)) { reset_item_opened_status(con->sbi, filename); @@ -1022,6 +1023,7 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, trace_hmdfs_server_readdir(readdir_recv); + hmdfs_info("lzr hmdfs_server_readdir"); lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p); if (IS_ERR(lo_p_name)) { err = PTR_ERR(lo_p_name); @@ -1308,6 +1310,21 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, if (d_type == DT_REG || d_type == DT_DIR) { create_dentry(child, d_inode(child), gc->file, gc->sbi); gc->num++; + } else if (d_type == DT_LNK) { + struct path link_path; + + res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", + gc->sbi->local_src, gc->dir, + name); + if (!res) { + create_dentry(child, d_inode(link_path.dentry), + gc->file, gc->sbi); + path_put(&link_path); + gc->num++; + } else if (res == -ENOENT) { + create_dentry(child, d_inode(child), gc->file, gc->sbi); + gc->num++; + } } dput(child); @@ -1319,7 +1336,62 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, */ return 0; } +/* +static void _do_create_dentry(struct getdents_callback_real *gc, + struct dir_entry_info *di) +{ + int res = 0; + struct dentry *child = NULL; + + inode_lock(d_inode(gc->parent_path->dentry)); + child = lookup_one_len(di->name, gc->parent_path->dentry, di->name_len); + inode_unlock(d_inode(gc->parent_path->dentry)); + if (IS_ERR(child)) { + res = PTR_ERR(child); + hmdfs_err("lookup faild because %d", res); + return; + } + + if (d_really_is_negative(child)) { + hmdfs_err("lookup faild because negative dentry"); + goto out; + } + + if (di->d_type == DT_REG || di->d_type == DT_DIR) { + create_dentry(child, d_inode(child), gc->file, gc->sbi); + gc->num++; + } else if (di->d_type == DT_LNK) { + struct path link_path; + + res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", + gc->sbi->local_src, gc->dir, + di->name); + if (!res) { + create_dentry(child, d_inode(link_path.dentry), + gc->file, gc->sbi); + path_put(&link_path); + gc->num++; + } else if (res == -ENOENT) { + create_dentry(child, d_inode(child), gc->file, gc->sbi); + gc->num++; + } + } +out: + dput(child); +} + +static void _gen_dir_dents_info(struct getdents_callback_real *gc) +{ + struct dir_entry_info *di = NULL, *tmp = NULL; + list_for_each_entry_safe(di, tmp, &gc->dir_ents, list) { + _do_create_dentry(gc, di); + list_del(&di->list); + kfree(di->name); + kfree(di); + } +} +*/ static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, struct file *file, struct file *dentry_file) { @@ -1351,6 +1423,7 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, struct file *dentry_file = NULL; struct hmdfs_dcache_header header; + hmdfs_info("lzr hmdfs_server_rebuild_dents"); dentry_file = create_local_dentry_file_cache(sbi); if (IS_ERR(dentry_file)) { hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file)); @@ -1368,8 +1441,10 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.parent_path = path; gc.file = dentry_file; + //INIT_LIST_HEAD(&gc.dir_ents); err = iterate_dir(file, &(gc.ctx)); + //_gen_dir_dents_info(&gc); if (err) { hmdfs_err("iterate_dir failed"); goto out; diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index c02302af238f..aca355d33928 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -229,7 +229,6 @@ static inline void set_symlink_flag(struct hmdfs_dentry_info *gdi) gdi->file_type = HM_SYMLINK; } - struct dentry *hmdfs_lookup_local(struct inode *parent_inode, struct dentry *child_dentry, unsigned int flags) @@ -274,6 +273,7 @@ struct dentry *hmdfs_lookup_local(struct inode *parent_inode, child_inode = fill_inode_local(parent_inode->i_sb, d_inode(lower_path.dentry), child_dentry->d_name.name); + if (S_ISLNK(d_inode(lower_path.dentry)->i_mode)) set_symlink_flag(gdi); if (IS_ERR(child_inode)) { @@ -827,7 +827,6 @@ static int hmdfs_getattr_local(const struct path *path, struct kstat *stat, stat->gid = d_inode(path->dentry)->i_gid; hmdfs_put_lower_path(&lower_path); - hmdfs_info("hmdfs_getattr_local, ret: %d", ret); return ret; } diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index ecda32c65b93..26a2405f373f 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -119,7 +119,7 @@ static struct inode *fill_inode_merge(struct super_block *sb, inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_MERGE, NULL, NULL); else - inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); + inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); if (!inode) { hmdfs_err("iget5_locked get inode NULL"); inode = ERR_PTR(-ENOMEM); @@ -127,7 +127,6 @@ static struct inode *fill_inode_merge(struct super_block *sb, } if (!(inode->i_state & I_NEW)) goto out; - info = hmdfs_i(inode); if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) info->inode_type = HMDFS_LAYER_FIRST_MERGE; @@ -140,7 +139,6 @@ static struct inode *fill_inode_merge(struct super_block *sb, update_inode_attr(inode, child_dentry); mode = d_inode(fst_lo_d)->i_mode; - if (S_ISREG(mode)) { inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; inode->i_op = &hmdfs_file_iops_merge; @@ -726,7 +724,6 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, err = init_hmdfs_dentry_info_merge(sbi, child_dentry); if (unlikely(err)) goto out; - if (pii->inode_type == HMDFS_LAYER_ZERO) { hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_FIRST_MERGE; @@ -762,7 +759,7 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, if ((err == -ENOENT) && create) err = 0; - + out: hmdfs_trace_merge(trace_hmdfs_lookup_merge_end, parent_inode, child_dentry, err); diff --git a/fs/hmdfs/stash.c b/fs/hmdfs/stash.c index e59499f5dcdc..c320af7f60e0 100644 --- a/fs/hmdfs/stash.c +++ b/fs/hmdfs/stash.c @@ -1261,7 +1261,7 @@ static int hmdfs_open_restore_dst_file(struct hmdfs_file_restore_ctx *ctx, goto out; /* Error comes from connection or server ? */ - dst = file_open_root(&ctx->dst_root_path, + dst = file_open_root(&ctx->dst_root_path, ctx->dst, O_LARGEFILE | rw_flag, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); -- Gitee From 52b0fec230c35fb160de7d94e9c8488ae6ddc50b Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 07:02:08 +0000 Subject: [PATCH 06/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/hmdfs_dentryfile.c | 2 +- fs/hmdfs/hmdfs_server.c | 61 ++----------------------------------- fs/hmdfs/hmdfs_trace.h | 2 -- fs/hmdfs/inode_remote.c | 1 - 4 files changed, 3 insertions(+), 63 deletions(-) diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index 84eedab9545f..1b96ed8db248 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -1061,7 +1061,7 @@ struct file *create_local_dentry_file_cache(struct hmdfs_sb_info *sbi) goto out; } - filp = file_open_root(&cache_dir.dentry, ".", + filp = file_open_root(&cache_dir, ".", O_RDWR | O_LARGEFILE | O_TMPFILE, DENTRY_FILE_PERM); if (IS_ERR(filp)) diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index 6e0e5e079036..b696b64fda41 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -108,9 +108,9 @@ struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) { - int err; struct path root_path; struct file *file; + int err; const char *root_name = sbi->local_dst; err = kern_path(root_name, 0, &root_path); @@ -118,7 +118,7 @@ struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) hmdfs_info("kern_path failed: %d", err); return ERR_PTR(err); } - file = file_open_root(root_path.dentry, root_path.mnt, path, + file = file_open_root(&root_path, path, O_RDWR | O_LARGEFILE, 0644); path_put(&root_path); if (IS_ERR(file)) { @@ -1023,7 +1023,6 @@ void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, trace_hmdfs_server_readdir(readdir_recv); - hmdfs_info("lzr hmdfs_server_readdir"); lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p); if (IS_ERR(lo_p_name)) { err = PTR_ERR(lo_p_name); @@ -1336,62 +1335,7 @@ static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, */ return 0; } -/* -static void _do_create_dentry(struct getdents_callback_real *gc, - struct dir_entry_info *di) -{ - int res = 0; - struct dentry *child = NULL; - - inode_lock(d_inode(gc->parent_path->dentry)); - child = lookup_one_len(di->name, gc->parent_path->dentry, di->name_len); - inode_unlock(d_inode(gc->parent_path->dentry)); - if (IS_ERR(child)) { - res = PTR_ERR(child); - hmdfs_err("lookup faild because %d", res); - return; - } - - if (d_really_is_negative(child)) { - hmdfs_err("lookup faild because negative dentry"); - goto out; - } - - if (di->d_type == DT_REG || di->d_type == DT_DIR) { - create_dentry(child, d_inode(child), gc->file, gc->sbi); - gc->num++; - } else if (di->d_type == DT_LNK) { - struct path link_path; - - res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", - gc->sbi->local_src, gc->dir, - di->name); - if (!res) { - create_dentry(child, d_inode(link_path.dentry), - gc->file, gc->sbi); - path_put(&link_path); - gc->num++; - } else if (res == -ENOENT) { - create_dentry(child, d_inode(child), gc->file, gc->sbi); - gc->num++; - } - } -out: - dput(child); -} -static void _gen_dir_dents_info(struct getdents_callback_real *gc) -{ - struct dir_entry_info *di = NULL, *tmp = NULL; - - list_for_each_entry_safe(di, tmp, &gc->dir_ents, list) { - _do_create_dentry(gc, di); - list_del(&di->list); - kfree(di->name); - kfree(di); - } -} -*/ static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, struct file *file, struct file *dentry_file) { @@ -1423,7 +1367,6 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, struct file *dentry_file = NULL; struct hmdfs_dcache_header header; - hmdfs_info("lzr hmdfs_server_rebuild_dents"); dentry_file = create_local_dentry_file_cache(sbi); if (IS_ERR(dentry_file)) { hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file)); diff --git a/fs/hmdfs/hmdfs_trace.h b/fs/hmdfs/hmdfs_trace.h index 4206e5ca0b1d..c12b7fa5cf42 100644 --- a/fs/hmdfs/hmdfs_trace.h +++ b/fs/hmdfs/hmdfs_trace.h @@ -203,8 +203,6 @@ define_hmdfs_lookup_op_end_event(hmdfs_mkdir_merge); define_hmdfs_lookup_op_end_event(hmdfs_rmdir_merge); define_hmdfs_lookup_op_end_event(hmdfs_create_merge); -define_hmdfs_lookup_op_end_event(hmdfs_symlink_merge); -define_hmdfs_lookup_op_end_event(hmdfs_symlink_local); define_hmdfs_lookup_op_end_event(hmdfs_get_link_local); define_hmdfs_lookup_op_end_event(hmdfs_lookup_share); diff --git a/fs/hmdfs/inode_remote.c b/fs/hmdfs/inode_remote.c index 8ac934dbbdc6..5efeae398d23 100644 --- a/fs/hmdfs/inode_remote.c +++ b/fs/hmdfs/inode_remote.c @@ -378,7 +378,6 @@ struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con, else if (S_ISLNK(mode)) inode->i_mode = S_IFREG | S_IRWXU | S_IRWXG; else { - hmdfs_info("fill_inode_remote: ret=%d", -EIO); ret = -EIO; goto bad_inode; } -- Gitee From 92ca2bc8ed7dede5595e034dcb6933caca9d04b8 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 07:03:34 +0000 Subject: [PATCH 07/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/hmdfs_server.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/hmdfs/hmdfs_server.c b/fs/hmdfs/hmdfs_server.c index b696b64fda41..1eaf72bc4f61 100644 --- a/fs/hmdfs/hmdfs_server.c +++ b/fs/hmdfs/hmdfs_server.c @@ -1384,10 +1384,8 @@ struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, gc.parent_path = path; gc.file = dentry_file; - //INIT_LIST_HEAD(&gc.dir_ents); err = iterate_dir(file, &(gc.ctx)); - //_gen_dir_dents_info(&gc); if (err) { hmdfs_err("iterate_dir failed"); goto out; -- Gitee From e0a95538c1ce57458402236c24cc249198474fcb Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 07:14:57 +0000 Subject: [PATCH 08/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/file_merge.c | 40 ++++++++++++++++++++++++++++++++++++++++ fs/hmdfs/hmdfs.h | 8 ++++++++ 2 files changed, 48 insertions(+) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 8048a203a8e6..962185a92995 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -582,11 +582,50 @@ static long hmdfs_ioc_get_writeopen_cnt(struct file *filp, unsigned long arg) return put_user(wo_cnt, (int __user *)arg); } +static long hmdfs_ioc_get_drag_path(struct file *filp, unsigned long arg) +{ + int error = 0; + char localPath[NAME_MAX]; + char cloudPath[NAME_MAX]; + struct dentry *dentry; + struct path path; + struct hmdfs_drag_info hdi; + + if (!access_ok((struct hmdfs_drag_info __user *)arg, + sizeof(struct hmdfs_drag_info))) + return -EFAULT; + + if (copy_from_user(&hdi, (struct hmdfs_drag_info __user *)arg, + sizeof(hdi))) + return -EFAULT; + + if (!access_ok((char *)hdi.localPath, hdi.localLen)) + return -EFAULT; + if (!access_ok((char *)hdi.cloudPath, hdi.cloudLen)) + return -EFAULT; + if (copy_from_user(localPath, (char __user *)hdi.localPath, + hdi.localLen)) + return -EFAULT; + if (copy_from_user(cloudPath, (char __user *)hdi.cloudPath, + hdi.cloudLen)) + return -EFAULT; + + dentry = kern_path_create(AT_FDCWD, cloudPath, &path, 0); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + error = vfs_symlink(path.dentry->d_inode, dentry, localPath); + done_path_create(&path, dentry); + hmdfs_info("error: %d", error); + return error; +} + static long hmdfs_file_ioctl_merge(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { case HMDFS_IOC_GET_WRITEOPEN_CNT: return hmdfs_ioc_get_writeopen_cnt(filp, arg); + case HMDFS_IOC_GET_DRAG_PATH: + return hmdfs_ioc_get_drag_path(filp, arg); default: return -ENOTTY; } @@ -606,6 +645,7 @@ const struct file_operations hmdfs_file_fops_merge = { .release = hmdfs_file_release_local, .fsync = hmdfs_fsync_local, .unlocked_ioctl = hmdfs_file_ioctl_merge, + .compat_ioctl = hmdfs_file_ioctl_merge, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, }; diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index 14adb4fac1b7..181ba0a39ab2 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -30,6 +30,7 @@ #define HMDFS_IOC 0xf2 #define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) #define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, 2, __u32) +#define HMDFS_IOC_GET_DRAG_PATH _IOR(HMDFS_IOC, 3, __u32) #define HMDFS_PAGE_SIZE 4096 #define HMDFS_PAGE_OFFSET 12 @@ -222,6 +223,13 @@ static inline bool hmdfs_is_stash_enabled(const struct hmdfs_sb_info *sbi) return sbi->s_offline_stash; } +struct hmdfs_drag_info{ + uint64_t localLen; + uint64_t localPath; + uint64_t cloudLen; + uint64_t cloudPath; +}; + struct setattr_info { loff_t size; unsigned int valid; -- Gitee From 667e96b977929ccf69a82f70580d5269b91b22f9 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Wed, 5 Jul 2023 08:02:08 +0000 Subject: [PATCH 09/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/file_merge.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 962185a92995..22190499ba44 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -615,7 +615,6 @@ static long hmdfs_ioc_get_drag_path(struct file *filp, unsigned long arg) return PTR_ERR(dentry); error = vfs_symlink(path.dentry->d_inode, dentry, localPath); done_path_create(&path, dentry); - hmdfs_info("error: %d", error); return error; } -- Gitee From 7fa6e8e5f3859e8d429c294fcb9520dddee8e7cb Mon Sep 17 00:00:00 2001 From: liuzerun Date: Thu, 6 Jul 2023 09:31:58 +0000 Subject: [PATCH 10/13] change cloud to distrubuted Signed-off-by: liuzerun --- fs/hmdfs/file_merge.c | 24 ++++++++++++------------ fs/hmdfs/hmdfs.h | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 22190499ba44..2412841de275 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -582,35 +582,35 @@ static long hmdfs_ioc_get_writeopen_cnt(struct file *filp, unsigned long arg) return put_user(wo_cnt, (int __user *)arg); } -static long hmdfs_ioc_get_drag_path(struct file *filp, unsigned long arg) +static long hmdfs_ioc_get_dst_path(struct file *filp, unsigned long arg) { int error = 0; char localPath[NAME_MAX]; - char cloudPath[NAME_MAX]; + char distributedPath[NAME_MAX]; struct dentry *dentry; struct path path; - struct hmdfs_drag_info hdi; + struct hmdfs_dst_info hdi; - if (!access_ok((struct hmdfs_drag_info __user *)arg, - sizeof(struct hmdfs_drag_info))) + if (!access_ok((struct hmdfs_dst_info __user *)arg, + sizeof(struct hmdfs_dst_info))) return -EFAULT; - if (copy_from_user(&hdi, (struct hmdfs_drag_info __user *)arg, + if (copy_from_user(&hdi, (struct hmdfs_dst_info __user *)arg, sizeof(hdi))) return -EFAULT; if (!access_ok((char *)hdi.localPath, hdi.localLen)) return -EFAULT; - if (!access_ok((char *)hdi.cloudPath, hdi.cloudLen)) + if (!access_ok((char *)hdi.distributedPath, hdi.distributedLen)) return -EFAULT; if (copy_from_user(localPath, (char __user *)hdi.localPath, hdi.localLen)) return -EFAULT; - if (copy_from_user(cloudPath, (char __user *)hdi.cloudPath, - hdi.cloudLen)) + if (copy_from_user(distributedPath, (char __user *)hdi.distributedPath, + hdi.distributedLen)) return -EFAULT; - dentry = kern_path_create(AT_FDCWD, cloudPath, &path, 0); + dentry = kern_path_create(AT_FDCWD, distributedPath, &path, 0); if (IS_ERR(dentry)) return PTR_ERR(dentry); error = vfs_symlink(path.dentry->d_inode, dentry, localPath); @@ -623,8 +623,8 @@ static long hmdfs_file_ioctl_merge(struct file *filp, unsigned int cmd, unsigned switch (cmd) { case HMDFS_IOC_GET_WRITEOPEN_CNT: return hmdfs_ioc_get_writeopen_cnt(filp, arg); - case HMDFS_IOC_GET_DRAG_PATH: - return hmdfs_ioc_get_drag_path(filp, arg); + case HMDFS_IOC_GET_DST_PATH: + return hmdfs_ioc_get_dst_path(filp, arg); default: return -ENOTTY; } diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index 181ba0a39ab2..8b2ad1442134 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -30,7 +30,7 @@ #define HMDFS_IOC 0xf2 #define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) #define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, 2, __u32) -#define HMDFS_IOC_GET_DRAG_PATH _IOR(HMDFS_IOC, 3, __u32) +#define HMDFS_IOC_GET_DST_PATH _IOR(HMDFS_IOC, 3, __u32) #define HMDFS_PAGE_SIZE 4096 #define HMDFS_PAGE_OFFSET 12 @@ -223,11 +223,11 @@ static inline bool hmdfs_is_stash_enabled(const struct hmdfs_sb_info *sbi) return sbi->s_offline_stash; } -struct hmdfs_drag_info{ +struct hmdf_dst_info{ uint64_t localLen; uint64_t localPath; - uint64_t cloudLen; - uint64_t cloudPath; + uint64_t distributedLen; + uint64_t distributedPath; }; struct setattr_info { -- Gitee From 7cfdcb9fe83601828c33c88cd909e5c5120ea102 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Fri, 7 Jul 2023 06:42:53 +0000 Subject: [PATCH 11/13] add symlink Signed-off-by: liuzerun --- fs/hmdfs/hmdfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index 8b2ad1442134..d7d2d1b0591e 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -223,7 +223,7 @@ static inline bool hmdfs_is_stash_enabled(const struct hmdfs_sb_info *sbi) return sbi->s_offline_stash; } -struct hmdf_dst_info{ +struct hmdfs_dst_info{ uint64_t localLen; uint64_t localPath; uint64_t distributedLen; -- Gitee From e8d69325092f000101ff6f7397b9a7d48fc145e1 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Mon, 10 Jul 2023 10:08:35 +0000 Subject: [PATCH 12/13] add override Signed-off-by: liuzerun --- fs/hmdfs/file_merge.c | 219 +++++++++++++++++++++++++++++++++++++----- fs/hmdfs/hmdfs.h | 11 ++- 2 files changed, 204 insertions(+), 26 deletions(-) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index 2412841de275..b09f8ef6ba69 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -11,6 +11,8 @@ #include "hmdfs.h" #include "hmdfs_trace.h" +#include "authority/authentication.h" + struct hmdfs_iterate_callback_merge { struct dir_context ctx; @@ -35,6 +37,12 @@ struct hmdfs_cache_entry { int file_type; }; +struct hmdfs_user_info { + char *local_path; + char *distributed_path; + char *bundle_name; +}; + struct hmdfs_cache_entry *allocate_entry(const char *name, int namelen, int d_type) { @@ -582,48 +590,215 @@ static long hmdfs_ioc_get_writeopen_cnt(struct file *filp, unsigned long arg) return put_user(wo_cnt, (int __user *)arg); } -static long hmdfs_ioc_get_dst_path(struct file *filp, unsigned long arg) +static int hmdfs_get_info_from_user(unsigned long pos, struct hmdfs_dst_info *hdi, struct hmdfs_user_info *data) { - int error = 0; - char localPath[NAME_MAX]; - char distributedPath[NAME_MAX]; - struct dentry *dentry; - struct path path; - struct hmdfs_dst_info hdi; - - if (!access_ok((struct hmdfs_dst_info __user *)arg, + if (!access_ok((struct hmdfs_dst_info __user *)pos, + sizeof(struct hmdfs_dst_info))) + return -ENOMEM; + hmdfs_info("lzr access_ok hmdfs_dst_info"); + if (copy_from_user(hdi, (struct hmdfs_dst_info __user *)pos, sizeof(struct hmdfs_dst_info))) return -EFAULT; + + hmdfs_info("lzr local_path_pos: %llx", hdi->local_path_pos); + hmdfs_info("lzr distributed_path_pos: %llx", hdi->distributed_path_pos); + hmdfs_info("lzr local_path_len: %llu", hdi->local_path_len); + hmdfs_info("lzr distributed_path_len: %llu", hdi->distributed_path_len); + hmdfs_info("lzr bundle_name_len: %llu", hdi->bundle_name_len); + hmdfs_info("lzr bundle_name_pos: %llx", hdi->bundle_name_pos); + hmdfs_info("lzr size: %llx", hdi->size); + + if (!access_ok((char *)hdi->local_path_pos, hdi->local_path_len)) + return -ENOMEM; + hmdfs_info("lzr access_ok 1"); + if (!access_ok((char *)hdi->distributed_path_pos, hdi->distributed_path_len)) + return -ENOMEM; + hmdfs_info("lzr access_ok 2"); + if (!access_ok((char *)hdi->bundle_name_pos, hdi->bundle_name_len)) + return -ENOMEM; - if (copy_from_user(&hdi, (struct hmdfs_dst_info __user *)arg, - sizeof(hdi))) - return -EFAULT; + hmdfs_info("lzr access_ok 3"); + data->local_path = kmalloc(hdi->local_path_len, GFP_KERNEL); + if (!data->local_path) + return -ENOMEM; + hmdfs_info("lzr kmalloc 1"); + data->distributed_path = kmalloc(hdi->distributed_path_len, GFP_KERNEL); + if (!data->distributed_path) + return -ENOMEM; + hmdfs_info("lzr kmallo 2c"); + data->bundle_name = kmalloc(hdi->bundle_name_len, GFP_KERNEL); + if (!data->bundle_name) + return -ENOMEM; - if (!access_ok((char *)hdi.localPath, hdi.localLen)) + hmdfs_info("lzr kmalloc 3"); + if (copy_from_user(data->local_path, (char __user *)hdi->local_path_pos, + hdi->local_path_len)) return -EFAULT; - if (!access_ok((char *)hdi.distributedPath, hdi.distributedLen)) + hmdfs_info("lzr copy_from_user 1"); + if (copy_from_user(data->distributed_path, (char __user *)hdi->distributed_path_pos, + hdi->distributed_path_len)) return -EFAULT; - if (copy_from_user(localPath, (char __user *)hdi.localPath, - hdi.localLen)) - return -EFAULT; - if (copy_from_user(distributedPath, (char __user *)hdi.distributedPath, - hdi.distributedLen)) + hmdfs_info("lzr copy_from_user 2"); + if (copy_from_user(data->bundle_name, (char __user *)hdi->bundle_name_pos, + hdi->bundle_name_len)) return -EFAULT; + hmdfs_info("lzr copy_from_user 3"); + return 0; +} + +static const struct cred *change_cred(struct dentry *dentry, const char *bundle_name) +{ + int bid; + struct cred *cred = NULL; + const struct cred *old_cred; + + cred = prepare_creds(); + if (!cred) { + return NULL; + } + bid = get_bundle_uid(hmdfs_sb(dentry->d_sb), + bundle_name); + if (bid != 0) { + cred->fsuid = KUIDT_INIT(bid); + cred->fsgid = KGIDT_INIT(bid); + } else { + return NULL; + } + old_cred = override_creds(cred); + return old_cred; +} + +static int get_file_size(const char *path_value, uint64_t pos) +{ + int ret; + uint64_t size; + struct path path; + struct kstat buf; - dentry = kern_path_create(AT_FDCWD, distributedPath, &path, 0); + ret = kern_path(path_value, 0, &path); + if (ret) + return ret; + ret = vfs_getattr(&path, &buf, STATX_BASIC_STATS | STATX_BTIME, 0); + if (ret) { + hmdfs_err("call vfs_getattr failed, err %d", ret); + return ret; + } + + size = buf.size; + + ret = copy_to_user((void __user *)pos, &size, sizeof(uint64_t)); + return ret; +} + +static int create_link_file(struct hmdfs_user_info *data) +{ + int ret; + struct dentry *dentry; + struct path path; + + ret = kern_path(data->distributed_path, 0, &path); + if (ret == 0) + return ret; + + dentry = kern_path_create(AT_FDCWD, data->distributed_path, &path, 0); if (IS_ERR(dentry)) return PTR_ERR(dentry); - error = vfs_symlink(path.dentry->d_inode, dentry, localPath); + ret = vfs_symlink(path.dentry->d_inode, dentry, data->local_path); done_path_create(&path, dentry); - return error; + + return ret; +} + +static int create_dir_recursive(const char *path_value, mode_t mode) +{ + char *tmp_path = kstrdup(path_value, GFP_KERNEL); + char *p = tmp_path; + struct dentry *dentry; + struct path path; + int err = 0; + if (!tmp_path) + return -ENOMEM; + + if (*p == '/') + p++; + + while (*p) { + if (*p == '/') { + *p = '\0'; + hmdfs_info("create_dir_recursive tmp_path : %s", tmp_path); + dentry = kern_path_create(AT_FDCWD, tmp_path, &path, LOOKUP_DIRECTORY); + if (PTR_ERR(dentry) == -EEXIST) { + *p = '/'; + p++; + continue; + } + if (IS_ERR(dentry) ) + return PTR_ERR(dentry); + + hmdfs_info("create_dir_recursive finish kern_path_create"); + err = vfs_mkdir(d_inode(path.dentry), dentry, mode); + if (err && err != -EEXIST) + hmdfs_err("vfs_mkdir failed, err = %d", err); + hmdfs_info("create_dir_recursive finish vfs_mkdir"); + done_path_create(&path, dentry); + if (err && err != -EEXIST) { + break; + } + *p = '/'; + } + p++; + } + + kfree(tmp_path); + return err; +} + +static long hmdfs_ioc_get_dst_path(struct file *filp, unsigned long arg) +{ + int ret = 0; + const struct cred *old_cred; + struct hmdfs_dst_info hdi; + struct hmdfs_user_info *data; + + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + ret = hmdfs_get_info_from_user(arg, &hdi, data); + if (ret) + return ret; + hmdfs_info("lzr local_path: %s", data->local_path); + hmdfs_info("lzr distributed_path: %s", data->distributed_path); + + old_cred = change_cred(filp->f_path.dentry, data->bundle_name); + hmdfs_info("lzr change_cred: %d", ret); + if (!old_cred) + return -ENOMEM; + ret = create_dir_recursive(data->distributed_path, 0771); + hmdfs_info("lzr create_dir_recursive: %d", ret); + if (ret) + return ret; + ret = create_link_file(data); + hmdfs_info("lzr create_link_file: %d", ret); + if (ret && ret != -EEXIST) + return ret; + + hmdfs_info("hdi.size %llx", hdi.size); + ret = get_file_size(data->local_path, hdi.size); + hmdfs_info("lzr get_file_size: %d", ret); + + revert_creds(old_cred); + return ret; } static long hmdfs_file_ioctl_merge(struct file *filp, unsigned int cmd, unsigned long arg) { + hmdfs_info("lzr hmdfs_file_ioctl_merge"); switch (cmd) { case HMDFS_IOC_GET_WRITEOPEN_CNT: return hmdfs_ioc_get_writeopen_cnt(filp, arg); case HMDFS_IOC_GET_DST_PATH: + hmdfs_info("lzr HMDFS_IOC_GET_DST_PATH"); return hmdfs_ioc_get_dst_path(filp, arg); default: return -ENOTTY; diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index d7d2d1b0591e..8ec5a260afaa 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -224,10 +224,13 @@ static inline bool hmdfs_is_stash_enabled(const struct hmdfs_sb_info *sbi) } struct hmdfs_dst_info{ - uint64_t localLen; - uint64_t localPath; - uint64_t distributedLen; - uint64_t distributedPath; + uint64_t local_path_len; + uint64_t local_path_pos; + uint64_t distributed_path_len; + uint64_t distributed_path_pos; + uint64_t bundle_name_len; + uint64_t bundle_name_pos; + uint64_t size; }; struct setattr_info { -- Gitee From c9926d5c7f439330c14ce4330fcb509e7f343479 Mon Sep 17 00:00:00 2001 From: liuzerun Date: Mon, 10 Jul 2023 11:21:05 +0000 Subject: [PATCH 13/13] add override Signed-off-by: liuzerun --- fs/hmdfs/file_merge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/hmdfs/file_merge.c b/fs/hmdfs/file_merge.c index b09f8ef6ba69..d4863c9d928b 100644 --- a/fs/hmdfs/file_merge.c +++ b/fs/hmdfs/file_merge.c @@ -788,6 +788,10 @@ static long hmdfs_ioc_get_dst_path(struct file *filp, unsigned long arg) hmdfs_info("lzr get_file_size: %d", ret); revert_creds(old_cred); + kfree(data->local_path); + kfree(data->distributed_path); + kfree(data->bundle_name); + kfree(data); return ret; } -- Gitee