diff --git a/fs/hmdfs/inode.c b/fs/hmdfs/inode.c index 33cc8c7419d5c89ee3292df056f6164907b65972..c11fba903f25265e5906c0485a777dc57632de04 100644 --- a/fs/hmdfs/inode.c +++ b/fs/hmdfs/inode.c @@ -354,4 +354,39 @@ 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; + if (*start) { + dget(root_dentry); + } + + while (*start) { + end = strchr(start, '/'); + if (!end) { + end = start + strlen(start); + } + hmdfs_err("flt :: goto lookup_one_len name = %s, len = %d\n", start, end - start); + ret_dentry = lookup_one_len(start, current_dentry, end - start); + if (IS_ERR(ret_dentry)) { + hmdfs_err("flt :: lookup_one_len failed!"); + dput(current_dentry); + return ret_dentry; + } + dput(current_dentry); + current_dentry = ret_dentry; + if (*end == '/') { + start = end + 1; + } else { + break; + } + } + return ret_dentry; } \ No newline at end of file diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index fb9bd2929d581e6e48dee17bd369962869440e02..43c6ba02728533fcd3a1a043cc6471c575122aee 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 a6f0b150fcfcf229326ea210af8899556d25088d..e509bcd2a3d272c00f4e5c9f15a2e6b62ae19b8b 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -97,6 +97,9 @@ cloud_merge_lookup_comrade(struct hmdfs_sb_info *sbi, int err; struct path root, path; struct hmdfs_dentry_comrade *comrade = NULL; + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; err = kern_path(sbi->real_dst, LOOKUP_DIRECTORY, &root); if (err) { @@ -109,7 +112,23 @@ cloud_merge_lookup_comrade(struct hmdfs_sb_info *sbi, comrade = ERR_PTR(err); goto root_put; } - + tmp_dentry = path.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in cloud_merge_lookup_comrade BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + dentry = lookup_multi_dir(sbi->sb->s_root, name, flags); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in cloud_merge_lookup_comrade lookup_multi_dir FAILED!"); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in cloud_merge_lookup_comrade AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } comrade = alloc_comrade(path.dentry, devid); path_put(&path); @@ -251,6 +270,9 @@ static int lookup_cloud_merge_root(struct inode *root_inode, int buf_len; char *buf = NULL; bool locked, down; + struct dentry *dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *tmp_dentry = NULL; // consider additional one slash and one '\0' buf_len = strlen(sbi->real_dst) + 1 + sizeof(DEVICE_VIEW_ROOT); @@ -268,6 +290,24 @@ static int lookup_cloud_merge_root(struct inode *root_inode, if (ret) goto free_buf; + tmp_dentry = path_dev.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in lookup_cloud_merge_root BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + dentry = lookup_multi_dir(sbi->sb->s_root, DEVICE_VIEW_ROOT, flags); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in lookup_cloud_merge_root lookup_multi_dir FAILED!"); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in lookup_cloud_merge_root AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } + ret = do_lookup_cloud_merge_root(path_dev, child_dentry, flags); path_put(&path_dev); @@ -458,6 +498,10 @@ int hmdfs_create_lower_cloud_dentry(struct inode *i_parent, struct dentry *d_chi char *path_name = NULL; struct path path = { .mnt = NULL, .dentry = NULL }; int ret = 0; + char *absolute_path_buf_tmp = kmalloc(PATH_MAX, GFP_KERNEL); + struct dentry *dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *tmp_dentry = NULL; if (unlikely(!path_buf || !absolute_path_buf)) { ret = -ENOMEM; @@ -478,6 +522,9 @@ int hmdfs_create_lower_cloud_dentry(struct inode *i_parent, struct dentry *d_chi sprintf(absolute_path_buf, "%s%s/%s", sbi->real_dst, path_name, d_child->d_name.name); + sprintf(absolute_path_buf_tmp, "%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); @@ -488,6 +535,30 @@ int hmdfs_create_lower_cloud_dentry(struct inode *i_parent, struct dentry *d_chi ret = PTR_ERR(lo_d_child); goto out; } + tmp_dentry = lo_d_child; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_cloud_dentry BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + if (is_dir) + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, LOOKUP_DIRECTORY); + else + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, 0); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in hmdfs_create_lower_cloud_dentry lookup_multi_dir FAILED!"); + } else if (d_is_positive(dentry)) { + hmdfs_err("flt :: in hmdfs_create_lower_cloud_dentry EXIST!"); + dput(dentry); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_cloud_dentry AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } + kfree(absolute_path_buf_tmp); // 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); diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 7c1e1e4f8539adf339c4633ddbf0b0dc8f54833a..fccc90b0d5e77392ee59c55a31ce943bb233f16f 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -350,6 +350,11 @@ static struct hmdfs_dentry_comrade *merge_lookup_comrade( struct path root, path; struct hmdfs_dentry_comrade *comrade = NULL; const struct cred *old_cred = hmdfs_override_creds(sbi->cred); + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; + + hmdfs_err("flt :: init merge_lookup_comrade, name = %s\n", name); err = kern_path(sbi->real_dst, LOOKUP_DIRECTORY, &root); if (err) { @@ -362,6 +367,28 @@ static struct hmdfs_dentry_comrade *merge_lookup_comrade( comrade = ERR_PTR(err); goto root_put; } + tmp_dentry = path.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in merge_lookup_comrade BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + dentry = lookup_multi_dir(sbi->sb->s_root, name, flags); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in merge_lookup_comrade lookup_multi_dir FAILED!"); + if (dentry == NULL) { + hmdfs_err("flt :: dentry == NULL"); + } else { + hmdfs_err("flt :: IS_ERR(dentry)"); + } + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in merge_lookup_comrade AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } comrade = alloc_comrade(path.dentry, devid); @@ -646,6 +673,9 @@ static int lookup_merge_root(struct inode *root_inode, int buf_len; char *buf = NULL; bool locked, down; + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; // consider additional one slash and one '\0' buf_len = strlen(sbi->real_dst) + 1 + sizeof(DEVICE_VIEW_ROOT); @@ -663,6 +693,24 @@ static int lookup_merge_root(struct inode *root_inode, if (ret) goto free_buf; + tmp_dentry = path_dev.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in lookup_merge_root BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + dentry = lookup_multi_dir(sbi->sb->s_root, DEVICE_VIEW_ROOT, flags); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in lookup_merge_root lookup_multi_dir FAILED!"); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in lookup_merge_root AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } + ret = do_lookup_merge_root(path_dev, child_dentry, flags); path_put(&path_dev); @@ -937,6 +985,10 @@ int hmdfs_create_lower_dentry(struct inode *i_parent, struct dentry *d_child, char *path_name = NULL; struct path path = { .mnt = NULL, .dentry = NULL }; int ret = 0; + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; + char *absolute_path_buf_tmp = kmalloc(PATH_MAX, GFP_KERNEL); if (unlikely(!path_buf || !absolute_path_buf)) { ret = -ENOMEM; @@ -956,6 +1008,8 @@ int hmdfs_create_lower_dentry(struct inode *i_parent, struct dentry *d_child, sprintf(absolute_path_buf, "%s%s/%s", sbi->real_dst, path_name, d_child->d_name.name); + sprintf(absolute_path_buf_tmp, "%s/%s", path_name, + d_child->d_name.name); if (is_dir) lo_d_child = kern_path_create(AT_FDCWD, absolute_path_buf, @@ -967,7 +1021,42 @@ int hmdfs_create_lower_dentry(struct inode *i_parent, struct dentry *d_child, ret = PTR_ERR(lo_d_child); goto out; } + tmp_dentry = lo_d_child; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_dentry BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + + if (is_dir) + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, LOOKUP_DIRECTORY); + else + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, 0); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in hmdfs_create_lower_dentry lookup_multi_dir FAILED!"); + } else if (d_is_positive(dentry)) { + hmdfs_err("flt :: in hmdfs_create_lower_dentry EXIST!"); + dput(dentry); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_dentry AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } + kfree(absolute_path_buf_tmp); // to ensure link_comrade after vfs_mkdir succeed + tmp_dentry = path.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_dentry goto next 11111 dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + tmp_dentry = lo_d_parent; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in hmdfs_create_lower_dentry goto next 11111 dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + ret = hmdfs_do_ops_merge(i_parent, d_child, lo_d_child, path, rec_op_para); if (ret) @@ -1252,6 +1341,10 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, char *path_name = NULL; struct hmdfs_dentry_info_merge *pmdi = NULL; struct renamedata rename_data; + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; + char *absolute_path_buf_tmp = kmalloc(PATH_MAX, GFP_KERNEL); if (flags & ~RENAME_NOREPLACE) { ret = -EINVAL; @@ -1290,6 +1383,8 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, snprintf(abs_path_buf, PATH_MAX, "%s%s/%s", sbi->real_dst, path_name, new_dentry->d_name.name); + sprintf(absolute_path_buf_tmp, "%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, @@ -1301,6 +1396,29 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, ret = PTR_ERR(lo_d_new); goto out; } + tmp_dentry = lo_d_new; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in do_rename_merge BEFORE dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + if (S_ISDIR(d_inode(old_dentry)->i_mode)) + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, LOOKUP_DIRECTORY); + else + dentry = lookup_multi_dir(sbi->sb->s_root, absolute_path_buf_tmp, 0); + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in do_rename_merge lookup_multi_dir FAILED!"); + } else if (d_is_positive(dentry)) { + hmdfs_err("flt :: in do_rename_merge EXIST!"); + dput(dentry); + } else { + tmp_dentry = dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in do_rename_merge AFTER dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + dput(dentry); + } + kfree(absolute_path_buf_tmp); lo_d_new_dir = dget_parent(lo_d_new); lo_i_new_dir = d_inode(lo_d_new_dir); @@ -1316,6 +1434,16 @@ int do_rename_merge(struct inode *old_dir, struct dentry *old_dentry, rename_data.flags = flags; ret = vfs_rename(&rename_data); + tmp_dentry = lo_p_new.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in rename goto alloc 111111 dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); + tmp_dentry = lo_d_new_dir; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in rename goto alloc 222222 dentry_name = %s, node = %lu, d_parent = %x, parent_name = %s", + tmp_dentry->d_name.name, tmp_dentry->d_inode->i_ino, + p_dentry, p_dentry->d_name.name); new_comrade = alloc_comrade(lo_p_new.dentry, comrade->dev_id); if (IS_ERR(new_comrade)) { ret = PTR_ERR(new_comrade);