diff --git a/fs/hmdfs/inode.c b/fs/hmdfs/inode.c index 33cc8c7419d5c89ee3292df056f6164907b65972..19124f0ce550548ba6c1e34933fde9f3275c6a88 100644 --- a/fs/hmdfs/inode.c +++ b/fs/hmdfs/inode.c @@ -354,4 +354,37 @@ 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) { + if (*start == '/') { + start = start + 1; + continue; + } + end = strchr(start, '/'); + if (!end) + end = start + strlen(start); + hmdfs_err("flt 0714 :: 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)) { + dput(current_dentry); + return ret_dentry; + } + dput(current_dentry); + current_dentry = ret_dentry; + start = end; + } + return ret_dentry; } \ No newline at end of file diff --git a/fs/hmdfs/inode.h b/fs/hmdfs/inode.h index fb9bd2929d581e6e48dee17bd369962869440e02..aace1392678424fa9f125a9659d10b0733601386 100644 --- a/fs/hmdfs/inode.h +++ b/fs/hmdfs/inode.h @@ -261,4 +261,7 @@ 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_merge.c b/fs/hmdfs/inode_merge.c index 7c1e1e4f8539adf339c4633ddbf0b0dc8f54833a..ece1e46383b0bbe70cc17374b60a7699c5e21b52 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -225,12 +225,40 @@ struct hmdfs_dentry_comrade *lookup_comrade(struct path lower_path, struct path path; struct hmdfs_dentry_comrade *comrade = NULL; int err; + struct dentry *tmp_dentry = NULL; + struct dentry *p_dentry = NULL; + struct dentry *dentry = NULL; err = vfs_path_lookup(lower_path.dentry, lower_path.mnt, d_name, flags, &path); if (err) return ERR_PTR(err); - + tmp_dentry = path.dentry; + p_dentry = tmp_dentry->d_parent; + hmdfs_err("flt :: in 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(lower_path.dentry, d_name, flags); + if (d_is_negative(dentry)) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in 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 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, dev_id); path_put(&path); return comrade; @@ -350,21 +378,58 @@ 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) { comrade = ERR_PTR(err); + hmdfs_err("flt :: kern_path failed, err = %d", err); goto out; } err = vfs_path_lookup(root.dentry, root.mnt, name, flags, &path); if (err) { comrade = ERR_PTR(err); + hmdfs_err("flt :: vfs_path_lookup failed, err = %d", 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 (d_is_negative(dentry)) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } + 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)"); + } + dput(dentry); + path_put(&root); + path_put(&path); + hmdfs_revert_creds(old_cred); + return ERR_PTR(PTR_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); + } - comrade = alloc_comrade(path.dentry, devid); + comrade = alloc_comrade(dentry, devid); + dput(dentry); path_put(&path); root_put: path_put(&root); @@ -646,6 +711,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); @@ -662,6 +730,32 @@ static int lookup_merge_root(struct inode *root_inode, &path_dev); 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 (d_is_negative(dentry)) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } + if (dentry == NULL || IS_ERR(dentry)) { + hmdfs_err("flt :: in lookup_merge_root 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 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 +1031,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,7 +1054,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, &path, LOOKUP_DIRECTORY); @@ -967,7 +1066,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 +1386,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 +1428,9 @@ 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 +1442,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 +1480,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);