162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/hmdfs/inode_root.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/fs_stack.h>
962306a36Sopenharmony_ci#include <linux/mount.h>
1062306a36Sopenharmony_ci#include <linux/namei.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "authority/authentication.h"
1362306a36Sopenharmony_ci#include "comm/socket_adapter.h"
1462306a36Sopenharmony_ci#include "comm/transport.h"
1562306a36Sopenharmony_ci#include "hmdfs_dentryfile.h"
1662306a36Sopenharmony_ci#include "hmdfs_device_view.h"
1762306a36Sopenharmony_ci#include "hmdfs_merge_view.h"
1862306a36Sopenharmony_ci#include "hmdfs_trace.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic struct inode *fill_device_local_inode(struct super_block *sb,
2162306a36Sopenharmony_ci					     struct inode *lower_inode)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	struct inode *inode = NULL;
2462306a36Sopenharmony_ci	struct hmdfs_inode_info *info = NULL;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	if (!igrab(lower_inode))
2762306a36Sopenharmony_ci		return ERR_PTR(-ESTALE);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_LOCAL, lower_inode,
3062306a36Sopenharmony_ci				       NULL);
3162306a36Sopenharmony_ci	if (!inode) {
3262306a36Sopenharmony_ci		hmdfs_err("iget5_locked get inode NULL");
3362306a36Sopenharmony_ci		iput(lower_inode);
3462306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
3562306a36Sopenharmony_ci	}
3662306a36Sopenharmony_ci	if (!(inode->i_state & I_NEW)) {
3762306a36Sopenharmony_ci		iput(lower_inode);
3862306a36Sopenharmony_ci		return inode;
3962306a36Sopenharmony_ci	}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	info = hmdfs_i(inode);
4262306a36Sopenharmony_ci	info->inode_type = HMDFS_LAYER_SECOND_LOCAL;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	inode->i_mode =
4562306a36Sopenharmony_ci		(lower_inode->i_mode & S_IFMT) | S_IRWXU | S_IRWXG | S_IXOTH;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	inode->i_uid = KUIDT_INIT((uid_t)1000);
4862306a36Sopenharmony_ci	inode->i_gid = KGIDT_INIT((gid_t)1000);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	inode->i_atime = lower_inode->i_atime;
5162306a36Sopenharmony_ci	inode->__i_ctime = lower_inode->__i_ctime;
5262306a36Sopenharmony_ci	inode->i_mtime = lower_inode->i_mtime;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	inode->i_op = &hmdfs_dir_inode_ops_local;
5562306a36Sopenharmony_ci	inode->i_fop = &hmdfs_dir_ops_local;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	fsstack_copy_inode_size(inode, lower_inode);
5862306a36Sopenharmony_ci	unlock_new_inode(inode);
5962306a36Sopenharmony_ci	return inode;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic struct inode *fill_device_inode_remote(struct super_block *sb,
6362306a36Sopenharmony_ci					      uint64_t dev_id)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	struct inode *inode = NULL;
6662306a36Sopenharmony_ci	struct hmdfs_inode_info *info = NULL;
6762306a36Sopenharmony_ci	struct hmdfs_peer *con = NULL;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	con = hmdfs_lookup_from_devid(sb->s_fs_info, dev_id);
7062306a36Sopenharmony_ci	if (!con)
7162306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_REMOTE, NULL, con);
7462306a36Sopenharmony_ci	if (!inode) {
7562306a36Sopenharmony_ci		hmdfs_err("get inode NULL");
7662306a36Sopenharmony_ci		inode = ERR_PTR(-ENOMEM);
7762306a36Sopenharmony_ci		goto out;
7862306a36Sopenharmony_ci	}
7962306a36Sopenharmony_ci	if (!(inode->i_state & I_NEW))
8062306a36Sopenharmony_ci		goto out;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	info = hmdfs_i(inode);
8362306a36Sopenharmony_ci	info->inode_type = HMDFS_LAYER_SECOND_REMOTE;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	inode->i_uid = KUIDT_INIT((uid_t)1000);
8862306a36Sopenharmony_ci	inode->i_gid = KGIDT_INIT((gid_t)1000);
8962306a36Sopenharmony_ci	inode->i_op = &hmdfs_dev_dir_inode_ops_remote;
9062306a36Sopenharmony_ci	inode->i_fop = &hmdfs_dev_dir_ops_remote;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	unlock_new_inode(inode);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciout:
9562306a36Sopenharmony_ci	peer_put(con);
9662306a36Sopenharmony_ci	return inode;
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_cistatic struct inode *fill_device_inode_cloud(struct super_block *sb)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	struct inode *inode = NULL;
10262306a36Sopenharmony_ci	struct hmdfs_inode_info *info = NULL;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_CLOUD, NULL, NULL);
10562306a36Sopenharmony_ci	if (!inode) {
10662306a36Sopenharmony_ci		hmdfs_err("get inode NULL");
10762306a36Sopenharmony_ci		inode = ERR_PTR(-ENOMEM);
10862306a36Sopenharmony_ci		goto out;
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci	if (!(inode->i_state & I_NEW))
11162306a36Sopenharmony_ci		goto out;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	info = hmdfs_i(inode);
11462306a36Sopenharmony_ci	info->inode_type = HMDFS_LAYER_SECOND_CLOUD;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	inode->i_uid = KUIDT_INIT((uid_t)1000);
11962306a36Sopenharmony_ci	inode->i_gid = KGIDT_INIT((gid_t)1000);
12062306a36Sopenharmony_ci	inode->i_op = &hmdfs_dev_dir_inode_ops_cloud;
12162306a36Sopenharmony_ci	inode->i_fop = &hmdfs_dev_dir_ops_cloud;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	unlock_new_inode(inode);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ciout:
12662306a36Sopenharmony_ci	return inode;
12762306a36Sopenharmony_ci}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistruct dentry *hmdfs_device_lookup(struct inode *parent_inode,
13062306a36Sopenharmony_ci				   struct dentry *child_dentry,
13162306a36Sopenharmony_ci				   unsigned int flags)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	const char *d_name = child_dentry->d_name.name;
13462306a36Sopenharmony_ci	struct inode *root_inode = NULL;
13562306a36Sopenharmony_ci	struct super_block *sb = parent_inode->i_sb;
13662306a36Sopenharmony_ci	struct hmdfs_sb_info *sbi = sb->s_fs_info;
13762306a36Sopenharmony_ci	struct dentry *ret_dentry = NULL;
13862306a36Sopenharmony_ci	int err = 0;
13962306a36Sopenharmony_ci	struct hmdfs_peer *con = NULL;
14062306a36Sopenharmony_ci	struct hmdfs_dentry_info *di = NULL;
14162306a36Sopenharmony_ci	uint8_t *cid = NULL;
14262306a36Sopenharmony_ci	struct path *root_lower_path = NULL;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	trace_hmdfs_device_lookup(parent_inode, child_dentry, flags);
14562306a36Sopenharmony_ci	if (!strncmp(d_name, DEVICE_VIEW_LOCAL,
14662306a36Sopenharmony_ci		     sizeof(DEVICE_VIEW_LOCAL))) {
14762306a36Sopenharmony_ci		err = init_hmdfs_dentry_info(sbi, child_dentry,
14862306a36Sopenharmony_ci					     HMDFS_LAYER_SECOND_LOCAL);
14962306a36Sopenharmony_ci		if (err) {
15062306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
15162306a36Sopenharmony_ci			goto out;
15262306a36Sopenharmony_ci		}
15362306a36Sopenharmony_ci		di = hmdfs_d(sb->s_root);
15462306a36Sopenharmony_ci		root_lower_path = &(di->lower_path);
15562306a36Sopenharmony_ci		hmdfs_set_lower_path(child_dentry, root_lower_path);
15662306a36Sopenharmony_ci		path_get(root_lower_path);
15762306a36Sopenharmony_ci		root_inode = fill_device_local_inode(
15862306a36Sopenharmony_ci			sb, d_inode(root_lower_path->dentry));
15962306a36Sopenharmony_ci		if (IS_ERR(root_inode)) {
16062306a36Sopenharmony_ci			err = PTR_ERR(root_inode);
16162306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
16262306a36Sopenharmony_ci			hmdfs_put_reset_lower_path(child_dentry);
16362306a36Sopenharmony_ci			goto out;
16462306a36Sopenharmony_ci		}
16562306a36Sopenharmony_ci		ret_dentry = d_splice_alias(root_inode, child_dentry);
16662306a36Sopenharmony_ci		if (IS_ERR(ret_dentry)) {
16762306a36Sopenharmony_ci			err = PTR_ERR(ret_dentry);
16862306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
16962306a36Sopenharmony_ci			hmdfs_put_reset_lower_path(child_dentry);
17062306a36Sopenharmony_ci			goto out;
17162306a36Sopenharmony_ci		}
17262306a36Sopenharmony_ci	} else if (!strncmp(d_name, DEVICE_VIEW_CLOUD,
17362306a36Sopenharmony_ci		     sizeof(DEVICE_VIEW_CLOUD))) {
17462306a36Sopenharmony_ci		err = init_hmdfs_dentry_info(sbi, child_dentry,
17562306a36Sopenharmony_ci					     HMDFS_LAYER_SECOND_CLOUD);
17662306a36Sopenharmony_ci		if (err) {
17762306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
17862306a36Sopenharmony_ci			goto out;
17962306a36Sopenharmony_ci		}
18062306a36Sopenharmony_ci		di = hmdfs_d(sb->s_root);
18162306a36Sopenharmony_ci		root_inode = fill_device_inode_cloud(sb);
18262306a36Sopenharmony_ci		if (IS_ERR(root_inode)) {
18362306a36Sopenharmony_ci			err = PTR_ERR(root_inode);
18462306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
18562306a36Sopenharmony_ci			goto out;
18662306a36Sopenharmony_ci		}
18762306a36Sopenharmony_ci		ret_dentry = d_splice_alias(root_inode, child_dentry);
18862306a36Sopenharmony_ci		if (IS_ERR(ret_dentry)) {
18962306a36Sopenharmony_ci			err = PTR_ERR(ret_dentry);
19062306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
19162306a36Sopenharmony_ci			goto out;
19262306a36Sopenharmony_ci		}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	} else {
19562306a36Sopenharmony_ci		err = init_hmdfs_dentry_info(sbi, child_dentry,
19662306a36Sopenharmony_ci					     HMDFS_LAYER_SECOND_REMOTE);
19762306a36Sopenharmony_ci		di = hmdfs_d(child_dentry);
19862306a36Sopenharmony_ci		if (err) {
19962306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
20062306a36Sopenharmony_ci			goto out;
20162306a36Sopenharmony_ci		}
20262306a36Sopenharmony_ci		cid = kzalloc(HMDFS_CID_SIZE + 1, GFP_KERNEL);
20362306a36Sopenharmony_ci		if (!cid) {
20462306a36Sopenharmony_ci			err = -ENOMEM;
20562306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
20662306a36Sopenharmony_ci			goto out;
20762306a36Sopenharmony_ci		}
20862306a36Sopenharmony_ci		strncpy(cid, d_name, HMDFS_CID_SIZE);
20962306a36Sopenharmony_ci		cid[HMDFS_CID_SIZE] = '\0';
21062306a36Sopenharmony_ci		con = hmdfs_lookup_from_cid(sbi, cid);
21162306a36Sopenharmony_ci		if (!con) {
21262306a36Sopenharmony_ci			kfree(cid);
21362306a36Sopenharmony_ci			err = -ENOENT;
21462306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
21562306a36Sopenharmony_ci			goto out;
21662306a36Sopenharmony_ci		}
21762306a36Sopenharmony_ci		di->device_id = con->device_id;
21862306a36Sopenharmony_ci		root_inode = fill_device_inode_remote(sb, di->device_id);
21962306a36Sopenharmony_ci		if (IS_ERR(root_inode)) {
22062306a36Sopenharmony_ci			kfree(cid);
22162306a36Sopenharmony_ci			err = PTR_ERR(root_inode);
22262306a36Sopenharmony_ci			ret_dentry = ERR_PTR(err);
22362306a36Sopenharmony_ci			goto out;
22462306a36Sopenharmony_ci		}
22562306a36Sopenharmony_ci		ret_dentry = d_splice_alias(root_inode, child_dentry);
22662306a36Sopenharmony_ci		kfree(cid);
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci	if (root_inode)
22962306a36Sopenharmony_ci		hmdfs_root_inode_perm_init(root_inode);
23062306a36Sopenharmony_ci	if (!err)
23162306a36Sopenharmony_ci		hmdfs_set_time(child_dentry, jiffies);
23262306a36Sopenharmony_ciout:
23362306a36Sopenharmony_ci	if (con)
23462306a36Sopenharmony_ci		peer_put(con);
23562306a36Sopenharmony_ci	trace_hmdfs_device_lookup_end(parent_inode, child_dentry, err);
23662306a36Sopenharmony_ci	return ret_dentry;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistruct dentry *hmdfs_root_lookup(struct inode *parent_inode,
24062306a36Sopenharmony_ci				 struct dentry *child_dentry,
24162306a36Sopenharmony_ci				 unsigned int flags)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	const char *d_name = child_dentry->d_name.name;
24462306a36Sopenharmony_ci	struct inode *root_inode = NULL;
24562306a36Sopenharmony_ci	struct super_block *sb = parent_inode->i_sb;
24662306a36Sopenharmony_ci	struct hmdfs_sb_info *sbi = sb->s_fs_info;
24762306a36Sopenharmony_ci	struct dentry *ret = ERR_PTR(-ENOENT);
24862306a36Sopenharmony_ci	struct path root_path;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	trace_hmdfs_root_lookup(parent_inode, child_dentry, flags);
25162306a36Sopenharmony_ci	if (sbi->s_merge_switch && !strcmp(d_name, MERGE_VIEW_ROOT)) {
25262306a36Sopenharmony_ci		ret = hmdfs_lookup_merge(parent_inode, child_dentry, flags);
25362306a36Sopenharmony_ci		if (ret && !IS_ERR(ret))
25462306a36Sopenharmony_ci			child_dentry = ret;
25562306a36Sopenharmony_ci		root_inode = d_inode(child_dentry);
25662306a36Sopenharmony_ci	} else if (sbi->s_merge_switch && !strcmp(d_name, CLOUD_MERGE_VIEW_ROOT)) {
25762306a36Sopenharmony_ci		ret = hmdfs_lookup_cloud_merge(parent_inode, child_dentry, flags);
25862306a36Sopenharmony_ci		if (ret && !IS_ERR(ret))
25962306a36Sopenharmony_ci			child_dentry = ret;
26062306a36Sopenharmony_ci		root_inode = d_inode(child_dentry);
26162306a36Sopenharmony_ci	} else if (!strcmp(d_name, DEVICE_VIEW_ROOT)) {
26262306a36Sopenharmony_ci		ret = ERR_PTR(init_hmdfs_dentry_info(
26362306a36Sopenharmony_ci			sbi, child_dentry, HMDFS_LAYER_FIRST_DEVICE));
26462306a36Sopenharmony_ci		if (IS_ERR(ret))
26562306a36Sopenharmony_ci			goto out;
26662306a36Sopenharmony_ci		ret = ERR_PTR(kern_path(sbi->local_src, 0, &root_path));
26762306a36Sopenharmony_ci		if (IS_ERR(ret))
26862306a36Sopenharmony_ci			goto out;
26962306a36Sopenharmony_ci		root_inode = fill_device_inode(sb, d_inode(root_path.dentry));
27062306a36Sopenharmony_ci		ret = d_splice_alias(root_inode, child_dentry);
27162306a36Sopenharmony_ci		path_put(&root_path);
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci	if (!IS_ERR(ret) && root_inode)
27462306a36Sopenharmony_ci		hmdfs_root_inode_perm_init(root_inode);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ciout:
27762306a36Sopenharmony_ci	trace_hmdfs_root_lookup_end(parent_inode, child_dentry,
27862306a36Sopenharmony_ci				    PTR_ERR_OR_ZERO(ret));
27962306a36Sopenharmony_ci	return ret;
28062306a36Sopenharmony_ci}
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ciconst struct inode_operations hmdfs_device_ops = {
28362306a36Sopenharmony_ci	.lookup = hmdfs_device_lookup,
28462306a36Sopenharmony_ci};
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ciconst struct inode_operations hmdfs_root_ops = {
28762306a36Sopenharmony_ci	.lookup = hmdfs_root_lookup,
28862306a36Sopenharmony_ci};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistruct inode *fill_device_inode(struct super_block *sb,
29162306a36Sopenharmony_ci				struct inode *lower_inode)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	struct inode *inode = NULL;
29462306a36Sopenharmony_ci	struct hmdfs_inode_info *info = NULL;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV, NULL, NULL);
29762306a36Sopenharmony_ci	if (!inode) {
29862306a36Sopenharmony_ci		hmdfs_err("iget5_locked get inode NULL");
29962306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
30062306a36Sopenharmony_ci	}
30162306a36Sopenharmony_ci	if (!(inode->i_state & I_NEW))
30262306a36Sopenharmony_ci		return inode;
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	info = hmdfs_i(inode);
30562306a36Sopenharmony_ci	info->inode_type = HMDFS_LAYER_FIRST_DEVICE;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	inode->i_atime = lower_inode->i_atime;
30862306a36Sopenharmony_ci	inode->__i_ctime = lower_inode->__i_ctime;
30962306a36Sopenharmony_ci	inode->i_mtime = lower_inode->i_mtime;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | S_IXUSR |
31262306a36Sopenharmony_ci			S_IRGRP | S_IXGRP | S_IXOTH;
31362306a36Sopenharmony_ci	inode->i_uid = KUIDT_INIT((uid_t)1000);
31462306a36Sopenharmony_ci	inode->i_gid = KGIDT_INIT((gid_t)1000);
31562306a36Sopenharmony_ci	inode->i_op = &hmdfs_device_ops;
31662306a36Sopenharmony_ci	inode->i_fop = &hmdfs_device_fops;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	fsstack_copy_inode_size(inode, lower_inode);
31962306a36Sopenharmony_ci	unlock_new_inode(inode);
32062306a36Sopenharmony_ci	return inode;
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistruct inode *fill_root_inode(struct super_block *sb, struct hmdfs_sb_info *sbi, struct inode *lower_inode)
32462306a36Sopenharmony_ci{
32562306a36Sopenharmony_ci	struct inode *inode = NULL;
32662306a36Sopenharmony_ci	struct hmdfs_inode_info *info = NULL;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	if (!igrab(lower_inode))
32962306a36Sopenharmony_ci		return ERR_PTR(-ESTALE);
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	if (sbi->s_cloud_disk_switch) {
33262306a36Sopenharmony_ci		inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_LOCAL, lower_inode,
33362306a36Sopenharmony_ci				       NULL);
33462306a36Sopenharmony_ci	} else {
33562306a36Sopenharmony_ci		inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_ANCESTOR, lower_inode,
33662306a36Sopenharmony_ci				       NULL);
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	if (!inode) {
34062306a36Sopenharmony_ci		hmdfs_err("iget5_locked get inode NULL");
34162306a36Sopenharmony_ci		iput(lower_inode);
34262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
34362306a36Sopenharmony_ci	}
34462306a36Sopenharmony_ci	if (!(inode->i_state & I_NEW)) {
34562306a36Sopenharmony_ci		iput(lower_inode);
34662306a36Sopenharmony_ci		return inode;
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	info = hmdfs_i(inode);
35062306a36Sopenharmony_ci	if (sbi->s_cloud_disk_switch) {
35162306a36Sopenharmony_ci		info->inode_type = HMDFS_LAYER_SECOND_LOCAL;
35262306a36Sopenharmony_ci		inode->i_op = &hmdfs_dir_inode_ops_local;
35362306a36Sopenharmony_ci		inode->i_fop = &hmdfs_dir_ops_local;
35462306a36Sopenharmony_ci	} else {
35562306a36Sopenharmony_ci		info->inode_type = HMDFS_LAYER_ZERO;
35662306a36Sopenharmony_ci		inode->i_op = &hmdfs_root_ops;
35762306a36Sopenharmony_ci		inode->i_fop = &hmdfs_root_fops;
35862306a36Sopenharmony_ci	}
35962306a36Sopenharmony_ci	inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | S_IXUSR |
36062306a36Sopenharmony_ci			S_IRGRP | S_IXGRP | S_IXOTH;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci#ifdef CONFIG_HMDFS_FS_PERMISSION
36362306a36Sopenharmony_ci	inode->i_uid = lower_inode->i_uid;
36462306a36Sopenharmony_ci	inode->i_gid = lower_inode->i_gid;
36562306a36Sopenharmony_ci#else
36662306a36Sopenharmony_ci	inode->i_uid = KUIDT_INIT((uid_t)1000);
36762306a36Sopenharmony_ci	inode->i_gid = KGIDT_INIT((gid_t)1000);
36862306a36Sopenharmony_ci#endif
36962306a36Sopenharmony_ci	inode->i_atime = lower_inode->i_atime;
37062306a36Sopenharmony_ci	inode->__i_ctime = lower_inode->__i_ctime;
37162306a36Sopenharmony_ci	inode->i_mtime = lower_inode->i_mtime;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	fsstack_copy_inode_size(inode, lower_inode);
37462306a36Sopenharmony_ci	unlock_new_inode(inode);
37562306a36Sopenharmony_ci	return inode;
37662306a36Sopenharmony_ci}
377