diff --git a/fs/hmdfs/inode.c b/fs/hmdfs/inode.c index 33cc8c7419d5c89ee3292df056f6164907b65972..d244446368fef6762b3df4e19d9b25e8d5edaa36 100644 --- a/fs/hmdfs/inode.c +++ b/fs/hmdfs/inode.c @@ -354,4 +354,38 @@ 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)) { + dput(current_dentry); + hmdfs_err("flt :: lookup_one_len failed!"); + return ret_dentry; + } + dput(current_dentry); + current_dentry = ret_dentry; + while (*end == '/') { + end = end + 1; + } + 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..c37d82d098c3c7de4f571986da56d0ed66804692 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -350,7 +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) { comrade = ERR_PTR(err); @@ -362,9 +366,35 @@ 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); - comrade = alloc_comrade(path.dentry, devid); + 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)"); + } + dput(dentry); + path_put(&root); + path_put(&path); + 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(dentry, devid); + dput(dentry); path_put(&path); root_put: path_put(&root);