diff --git a/fs/hmdfs/authority/authentication.c b/fs/hmdfs/authority/authentication.c index 076e738c92e71b95281a157d3788ae631dee0ccf..cfbb4f19bf0f5481a713b5e529c5dfd9d31ae262 100644 --- a/fs/hmdfs/authority/authentication.c +++ b/fs/hmdfs/authority/authentication.c @@ -358,14 +358,17 @@ void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child) } void check_and_fixup_ownership_remote(struct inode *dir, + struct inode *dinode, struct dentry *dentry) { struct hmdfs_inode_info *hii = hmdfs_i(dir); - struct inode *dinode = d_inode(dentry); struct hmdfs_inode_info *dinfo = hmdfs_i(dinode); __u16 level = hmdfs_perm_get_next_level(hii->perm); __u16 perm = 0; + if (IS_ERR_OR_NULL(dinode)) + return; + hmdfs_debug("level:0x%X", level); switch (level) { case HMDFS_PERM_MNT: diff --git a/fs/hmdfs/authority/authentication.h b/fs/hmdfs/authority/authentication.h index a36636a782865672089d8fd46c45bea78315917d..d66c19898abaf5cdc33b5806da33576164356866 100644 --- a/fs/hmdfs/authority/authentication.h +++ b/fs/hmdfs/authority/authentication.h @@ -261,6 +261,7 @@ int hmdfs_override_dir_id_fs(struct cache_fs_override *or, __u16 *perm); void hmdfs_revert_dir_id_fs(struct cache_fs_override *or); void check_and_fixup_ownership_remote(struct inode *dir, + struct inode *dinode, struct dentry *dentry); extern int get_bid(const char *bname); extern int __init hmdfs_init_configfs(void); @@ -322,6 +323,7 @@ void hmdfs_revert_creds(const struct cred *old) static inline void check_and_fixup_ownership_remote(struct inode *dir, + struct inode *inode, struct dentry *dentry) { } diff --git a/fs/hmdfs/dentry.c b/fs/hmdfs/dentry.c index d12ef45f3071152c31a193587c9d722a02469cfe..040d698e17850bcb70ce65c816441ae6ae0f584f 100644 --- a/fs/hmdfs/dentry.c +++ b/fs/hmdfs/dentry.c @@ -289,6 +289,8 @@ static int d_revalidate_merge(struct dentry *direntry, unsigned int flags) struct hmdfs_dentry_comrade *comrade = NULL; struct dentry *parent_dentry = NULL; struct dentry *lower_cur_parent_dentry = NULL; + struct inode *dinode = NULL; + struct hmdfs_inode_info *info = NULL; int ret = 1; if (flags & LOOKUP_RCU) { @@ -299,6 +301,14 @@ static int d_revalidate_merge(struct dentry *direntry, unsigned int flags) return 0; } + dinode = d_inode(direntry); + if (!dinode) + return 0; + + info = hmdfs_i(dinode); + if (info->inode_type == HMDFS_LAYER_FIRST_MERGE_CLOUD) + return 1; + parent_dentry = dget_parent(direntry); mutex_lock(&dim->comrade_list_lock); list_for_each_entry(comrade, &(dim->comrade_list), list) { diff --git a/fs/hmdfs/file_root.c b/fs/hmdfs/file_root.c index 73c026de04f9fcabaf7e0da2589162ca27e44843..02f331511da8f43cb47900e71553598da541e977 100644 --- a/fs/hmdfs/file_root.c +++ b/fs/hmdfs/file_root.c @@ -150,12 +150,14 @@ int hmdfs_root_iterate(struct file *file, struct dir_context *ctx) if (!dir_emit(ctx, MERGE_VIEW_ROOT, sizeof(MERGE_VIEW_ROOT) - 1, ino_start, DT_DIR)) return 0; + ino_start++; (ctx->pos)++; } if (sbi->s_merge_switch && ctx->pos == CLOUD_MERGE_VIEW_CTX_POS) { if (!dir_emit(ctx, CLOUD_MERGE_VIEW_ROOT, sizeof(CLOUD_MERGE_VIEW_ROOT) - 1, ino_start, DT_DIR)) return 0; + ino_start++; (ctx->pos)++; } return 0; diff --git a/fs/hmdfs/hmdfs_dentryfile.c b/fs/hmdfs/hmdfs_dentryfile.c index 0541308ffd0902c1819a237ffce52bb34d32e322..01efcba2f6cebe9bc44a4b67117903f19e2ef17d 100644 --- a/fs/hmdfs/hmdfs_dentryfile.c +++ b/fs/hmdfs/hmdfs_dentryfile.c @@ -294,7 +294,8 @@ static char *hmdfs_merge_dentry_path_raw(struct dentry *d, char *buf, int buflen retval = end - 1; *retval = '/'; read_seqbegin_or_lock(&rename_lock, &seq); - while (mdi->dentry_type != HMDFS_LAYER_FIRST_MERGE) { + while (mdi->dentry_type != HMDFS_LAYER_FIRST_MERGE && + mdi->dentry_type != HMDFS_LAYER_FIRST_MERGE_CLOUD) { struct dentry *parent = dentry->d_parent; prefetch(parent); diff --git a/fs/hmdfs/hmdfs_device_view.h b/fs/hmdfs/hmdfs_device_view.h index 2e306fe99de8cc03c8967a6b52dc8e13a8229298..5c525a9c7622905d3860f0ff5349c920e591c44e 100644 --- a/fs/hmdfs/hmdfs_device_view.h +++ b/fs/hmdfs/hmdfs_device_view.h @@ -246,7 +246,8 @@ static inline bool hmdfs_support_xattr(struct dentry *dentry) if (info->inode_type != HMDFS_LAYER_OTHER_LOCAL && info->inode_type != HMDFS_LAYER_OTHER_REMOTE && - info->inode_type != HMDFS_LAYER_OTHER_MERGE) + info->inode_type != HMDFS_LAYER_OTHER_MERGE && + info->inode_type != HMDFS_LAYER_OTHER_MERGE_CLOUD) return false; if (!S_ISREG(inode->i_mode)) diff --git a/fs/hmdfs/hmdfs_merge_view.h b/fs/hmdfs/hmdfs_merge_view.h index 13c2666a91eea40c3ef2c53f6d2120c80640f4aa..2e87b91361158eb9dcccef6db7cbde438d5328ce 100644 --- a/fs/hmdfs/hmdfs_merge_view.h +++ b/fs/hmdfs/hmdfs_merge_view.h @@ -216,7 +216,9 @@ static inline bool is_merge_lookup_end(struct hmdfs_dentry_info_merge *mdi) static inline bool hmdfs_i_merge(struct hmdfs_inode_info *hii) { __u8 t = hii->inode_type; - return t == HMDFS_LAYER_FIRST_MERGE || t == HMDFS_LAYER_OTHER_MERGE; + return t == HMDFS_LAYER_FIRST_MERGE || t == HMDFS_LAYER_OTHER_MERGE || + t == HMDFS_LAYER_FIRST_MERGE_CLOUD || + t == HMDFS_LAYER_OTHER_MERGE_CLOUD; } struct dentry *hmdfs_get_lo_d(struct dentry *dentry, int dev_id); diff --git a/fs/hmdfs/inode_cloud.c b/fs/hmdfs/inode_cloud.c index a34f598914e2bc9c39b2ab621c6ec378db1430ad..868f918345a7066887e197ddf09bc04425213b30 100644 --- a/fs/hmdfs/inode_cloud.c +++ b/fs/hmdfs/inode_cloud.c @@ -302,12 +302,13 @@ static struct dentry *hmdfs_lookup_cloud_dentry(struct inode *parent_inode, if (in_share_dir(child_dentry)) gdi->file_type = HM_SHARE; inode = fill_inode_cloud(sb, lookup_result, parent_inode); + + check_and_fixup_ownership_remote(parent_inode, + inode, + child_dentry); ret = d_splice_alias(inode, child_dentry); if (!IS_ERR_OR_NULL(ret)) child_dentry = ret; - if (!IS_ERR(ret)) - check_and_fixup_ownership_remote(parent_inode, - child_dentry); } else { ret = ERR_PTR(-ENOENT); } diff --git a/fs/hmdfs/inode_cloud_merge.c b/fs/hmdfs/inode_cloud_merge.c index 14f20a6da41eb185292a4a774fbfa5808ef3db7a..92c2af826cc249db9678bf37753dda3086430ed1 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -41,7 +41,7 @@ static struct inode *fill_inode_merge(struct super_block *sb, goto out; } if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) - inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_MERGE, NULL, + inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_MERGE_CLOUD, NULL, NULL); else inode = hmdfs_iget5_locked_merge(sb, fst_lo_d); @@ -54,9 +54,9 @@ static struct inode *fill_inode_merge(struct super_block *sb, goto out; info = hmdfs_i(inode); if (hmdfs_i(parent_inode)->inode_type == HMDFS_LAYER_ZERO) - info->inode_type = HMDFS_LAYER_FIRST_MERGE; + info->inode_type = HMDFS_LAYER_FIRST_MERGE_CLOUD; else - info->inode_type = HMDFS_LAYER_OTHER_MERGE; + info->inode_type = HMDFS_LAYER_OTHER_MERGE_CLOUD; inode->i_uid = USER_DATA_RW_UID; inode->i_gid = USER_DATA_RW_GID; @@ -182,7 +182,7 @@ static int do_lookup_cloud_merge_root(struct path path_dev, buf[5] = '\0'; comrade = lookup_comrade(path_dev, buf, CLOUD_DEVICE, flags); if (IS_ERR(comrade)) { - ret = PTR_ERR(comrade); + ret = 0; goto out; } @@ -264,10 +264,10 @@ struct dentry *hmdfs_lookup_cloud_merge(struct inode *parent_inode, goto out; if (pii->inode_type == HMDFS_LAYER_ZERO) { - hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_FIRST_MERGE; + hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_FIRST_MERGE_CLOUD; err = lookup_cloud_merge_root(parent_inode, child_dentry, flags); } else { - hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_OTHER_MERGE; + hmdfs_dm(child_dentry)->dentry_type = HMDFS_LAYER_OTHER_MERGE_CLOUD; err = lookup_merge_normal(child_dentry, flags); } @@ -276,6 +276,14 @@ struct dentry *hmdfs_lookup_cloud_merge(struct inode *parent_inode, child_inode = fill_inode_merge(parent_inode->i_sb, parent_inode, child_dentry, NULL); + info = hmdfs_i(child_inode); + if (info->inode_type == HMDFS_LAYER_FIRST_MERGE) + hmdfs_root_inode_perm_init(child_inode); + else + check_and_fixup_ownership_remote(parent_inode, + child_inode, + child_dentry); + ret_dentry = d_splice_alias(child_inode, child_dentry); if (IS_ERR(ret_dentry)) { clear_comrades(child_dentry); @@ -285,13 +293,6 @@ struct dentry *hmdfs_lookup_cloud_merge(struct inode *parent_inode, if (ret_dentry) { child_dentry = ret_dentry; } - info = hmdfs_i(child_inode); - if (info->inode_type == HMDFS_LAYER_FIRST_MERGE) - hmdfs_root_inode_perm_init(child_inode); - else - check_and_fixup_ownership_remote(parent_inode, - child_dentry); - goto out; } @@ -299,8 +300,6 @@ struct dentry *hmdfs_lookup_cloud_merge(struct inode *parent_inode, err = 0; out: - hmdfs_trace_merge(trace_hmdfs_lookup_merge_end, parent_inode, - child_dentry, err); return err ? ERR_PTR(err) : ret_dentry; } diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index 17a7af217d8d48eb16eef6c99e67e1492f9ca388..5b4b9c288ca7f69d8208695da9d5f4c38ea2410b 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -739,6 +739,14 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, child_inode = fill_inode_merge(parent_inode->i_sb, parent_inode, child_dentry, NULL); + info = hmdfs_i(child_inode); + if (info->inode_type == HMDFS_LAYER_FIRST_MERGE) + hmdfs_root_inode_perm_init(child_inode); + else + check_and_fixup_ownership_remote(parent_inode, + child_inode, + child_dentry); + ret_dentry = d_splice_alias(child_inode, child_dentry); if (IS_ERR(ret_dentry)) { clear_comrades(child_dentry); @@ -748,13 +756,6 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, if (ret_dentry) { child_dentry = ret_dentry; } - info = hmdfs_i(child_inode); - if (info->inode_type == HMDFS_LAYER_FIRST_MERGE) - hmdfs_root_inode_perm_init(child_inode); - else - check_and_fixup_ownership_remote(parent_inode, - child_dentry); - goto out; } @@ -762,8 +763,6 @@ struct dentry *hmdfs_lookup_merge(struct inode *parent_inode, err = 0; out: - hmdfs_trace_merge(trace_hmdfs_lookup_merge_end, parent_inode, - child_dentry, err); return err ? ERR_PTR(err) : ret_dentry; } diff --git a/fs/hmdfs/inode_remote.c b/fs/hmdfs/inode_remote.c index 2670e3e8189145465c95ce76547cf08b5cb30474..d3298131c0b1f18aed950b34c0a46cb5ad92ded8 100644 --- a/fs/hmdfs/inode_remote.c +++ b/fs/hmdfs/inode_remote.c @@ -449,12 +449,12 @@ static struct dentry *hmdfs_lookup_remote_dentry(struct inode *parent_inode, if (in_share_dir(child_dentry)) gdi->file_type = HM_SHARE; inode = fill_inode_remote(sb, con, lookup_result, parent_inode); + check_and_fixup_ownership_remote(parent_inode, + inode, + child_dentry); ret = d_splice_alias(inode, child_dentry); if (!IS_ERR_OR_NULL(ret)) child_dentry = ret; - if (!IS_ERR(ret)) - check_and_fixup_ownership_remote(parent_inode, - child_dentry); } else { ret = ERR_PTR(-ENOENT); } @@ -559,11 +559,13 @@ int hmdfs_mkdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry, } if (mkdir_ret) { inode = fill_inode_remote(sb, conn, mkdir_ret, parent_inode); + check_and_fixup_ownership_remote(parent_inode, + inode, + dentry); if (!IS_ERR(inode)) d_add(dentry, inode); else err = PTR_ERR(inode); - check_and_fixup_ownership_remote(parent_inode, dentry); } else { err = -ENOENT; } @@ -629,11 +631,13 @@ int hmdfs_create_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry, } if (create_ret) { inode = fill_inode_remote(sb, conn, create_ret, parent_inode); + check_and_fixup_ownership_remote(parent_inode, + inode, + dentry); if (!IS_ERR(inode)) d_add(dentry, inode); else err = PTR_ERR(inode); - check_and_fixup_ownership_remote(parent_inode, dentry); } else { err = -ENOENT; hmdfs_err("get remote inode info failed err = %d", err); diff --git a/fs/hmdfs/main.c b/fs/hmdfs/main.c index b3bd822842554b119cff1d2830dfafd65dee9d9e..179ddfa7821824e0f9ce5bacc93976f603ce7321 100644 --- a/fs/hmdfs/main.c +++ b/fs/hmdfs/main.c @@ -197,7 +197,8 @@ static int hmdfs_xattr_set(const struct xattr_handler *handler, if (info->inode_type == HMDFS_LAYER_OTHER_LOCAL) return hmdfs_xattr_local_set(dentry, name, value, size, flags); - else if (info->inode_type == HMDFS_LAYER_OTHER_MERGE) + else if (info->inode_type == HMDFS_LAYER_OTHER_MERGE || + info->inode_type == HMDFS_LAYER_OTHER_MERGE_CLOUD) return hmdfs_xattr_merge_set(dentry, name, value, size, flags); return hmdfs_xattr_remote_set(dentry, name, value, size, flags);