xref: /kernel/linux/linux-6.6/fs/hmdfs/inode_root.c (revision 62306a36)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/hmdfs/inode_root.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8#include <linux/fs_stack.h>
9#include <linux/mount.h>
10#include <linux/namei.h>
11
12#include "authority/authentication.h"
13#include "comm/socket_adapter.h"
14#include "comm/transport.h"
15#include "hmdfs_dentryfile.h"
16#include "hmdfs_device_view.h"
17#include "hmdfs_merge_view.h"
18#include "hmdfs_trace.h"
19
20static struct inode *fill_device_local_inode(struct super_block *sb,
21					     struct inode *lower_inode)
22{
23	struct inode *inode = NULL;
24	struct hmdfs_inode_info *info = NULL;
25
26	if (!igrab(lower_inode))
27		return ERR_PTR(-ESTALE);
28
29	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_LOCAL, lower_inode,
30				       NULL);
31	if (!inode) {
32		hmdfs_err("iget5_locked get inode NULL");
33		iput(lower_inode);
34		return ERR_PTR(-ENOMEM);
35	}
36	if (!(inode->i_state & I_NEW)) {
37		iput(lower_inode);
38		return inode;
39	}
40
41	info = hmdfs_i(inode);
42	info->inode_type = HMDFS_LAYER_SECOND_LOCAL;
43
44	inode->i_mode =
45		(lower_inode->i_mode & S_IFMT) | S_IRWXU | S_IRWXG | S_IXOTH;
46
47	inode->i_uid = KUIDT_INIT((uid_t)1000);
48	inode->i_gid = KGIDT_INIT((gid_t)1000);
49
50	inode->i_atime = lower_inode->i_atime;
51	inode->__i_ctime = lower_inode->__i_ctime;
52	inode->i_mtime = lower_inode->i_mtime;
53
54	inode->i_op = &hmdfs_dir_inode_ops_local;
55	inode->i_fop = &hmdfs_dir_ops_local;
56
57	fsstack_copy_inode_size(inode, lower_inode);
58	unlock_new_inode(inode);
59	return inode;
60}
61
62static struct inode *fill_device_inode_remote(struct super_block *sb,
63					      uint64_t dev_id)
64{
65	struct inode *inode = NULL;
66	struct hmdfs_inode_info *info = NULL;
67	struct hmdfs_peer *con = NULL;
68
69	con = hmdfs_lookup_from_devid(sb->s_fs_info, dev_id);
70	if (!con)
71		return ERR_PTR(-ENOENT);
72
73	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_REMOTE, NULL, con);
74	if (!inode) {
75		hmdfs_err("get inode NULL");
76		inode = ERR_PTR(-ENOMEM);
77		goto out;
78	}
79	if (!(inode->i_state & I_NEW))
80		goto out;
81
82	info = hmdfs_i(inode);
83	info->inode_type = HMDFS_LAYER_SECOND_REMOTE;
84
85	inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
86
87	inode->i_uid = KUIDT_INIT((uid_t)1000);
88	inode->i_gid = KGIDT_INIT((gid_t)1000);
89	inode->i_op = &hmdfs_dev_dir_inode_ops_remote;
90	inode->i_fop = &hmdfs_dev_dir_ops_remote;
91
92	unlock_new_inode(inode);
93
94out:
95	peer_put(con);
96	return inode;
97}
98
99static struct inode *fill_device_inode_cloud(struct super_block *sb)
100{
101	struct inode *inode = NULL;
102	struct hmdfs_inode_info *info = NULL;
103
104	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_CLOUD, NULL, NULL);
105	if (!inode) {
106		hmdfs_err("get inode NULL");
107		inode = ERR_PTR(-ENOMEM);
108		goto out;
109	}
110	if (!(inode->i_state & I_NEW))
111		goto out;
112
113	info = hmdfs_i(inode);
114	info->inode_type = HMDFS_LAYER_SECOND_CLOUD;
115
116	inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
117
118	inode->i_uid = KUIDT_INIT((uid_t)1000);
119	inode->i_gid = KGIDT_INIT((gid_t)1000);
120	inode->i_op = &hmdfs_dev_dir_inode_ops_cloud;
121	inode->i_fop = &hmdfs_dev_dir_ops_cloud;
122
123	unlock_new_inode(inode);
124
125out:
126	return inode;
127}
128
129struct dentry *hmdfs_device_lookup(struct inode *parent_inode,
130				   struct dentry *child_dentry,
131				   unsigned int flags)
132{
133	const char *d_name = child_dentry->d_name.name;
134	struct inode *root_inode = NULL;
135	struct super_block *sb = parent_inode->i_sb;
136	struct hmdfs_sb_info *sbi = sb->s_fs_info;
137	struct dentry *ret_dentry = NULL;
138	int err = 0;
139	struct hmdfs_peer *con = NULL;
140	struct hmdfs_dentry_info *di = NULL;
141	uint8_t *cid = NULL;
142	struct path *root_lower_path = NULL;
143
144	trace_hmdfs_device_lookup(parent_inode, child_dentry, flags);
145	if (!strncmp(d_name, DEVICE_VIEW_LOCAL,
146		     sizeof(DEVICE_VIEW_LOCAL))) {
147		err = init_hmdfs_dentry_info(sbi, child_dentry,
148					     HMDFS_LAYER_SECOND_LOCAL);
149		if (err) {
150			ret_dentry = ERR_PTR(err);
151			goto out;
152		}
153		di = hmdfs_d(sb->s_root);
154		root_lower_path = &(di->lower_path);
155		hmdfs_set_lower_path(child_dentry, root_lower_path);
156		path_get(root_lower_path);
157		root_inode = fill_device_local_inode(
158			sb, d_inode(root_lower_path->dentry));
159		if (IS_ERR(root_inode)) {
160			err = PTR_ERR(root_inode);
161			ret_dentry = ERR_PTR(err);
162			hmdfs_put_reset_lower_path(child_dentry);
163			goto out;
164		}
165		ret_dentry = d_splice_alias(root_inode, child_dentry);
166		if (IS_ERR(ret_dentry)) {
167			err = PTR_ERR(ret_dentry);
168			ret_dentry = ERR_PTR(err);
169			hmdfs_put_reset_lower_path(child_dentry);
170			goto out;
171		}
172	} else if (!strncmp(d_name, DEVICE_VIEW_CLOUD,
173		     sizeof(DEVICE_VIEW_CLOUD))) {
174		err = init_hmdfs_dentry_info(sbi, child_dentry,
175					     HMDFS_LAYER_SECOND_CLOUD);
176		if (err) {
177			ret_dentry = ERR_PTR(err);
178			goto out;
179		}
180		di = hmdfs_d(sb->s_root);
181		root_inode = fill_device_inode_cloud(sb);
182		if (IS_ERR(root_inode)) {
183			err = PTR_ERR(root_inode);
184			ret_dentry = ERR_PTR(err);
185			goto out;
186		}
187		ret_dentry = d_splice_alias(root_inode, child_dentry);
188		if (IS_ERR(ret_dentry)) {
189			err = PTR_ERR(ret_dentry);
190			ret_dentry = ERR_PTR(err);
191			goto out;
192		}
193
194	} else {
195		err = init_hmdfs_dentry_info(sbi, child_dentry,
196					     HMDFS_LAYER_SECOND_REMOTE);
197		di = hmdfs_d(child_dentry);
198		if (err) {
199			ret_dentry = ERR_PTR(err);
200			goto out;
201		}
202		cid = kzalloc(HMDFS_CID_SIZE + 1, GFP_KERNEL);
203		if (!cid) {
204			err = -ENOMEM;
205			ret_dentry = ERR_PTR(err);
206			goto out;
207		}
208		strncpy(cid, d_name, HMDFS_CID_SIZE);
209		cid[HMDFS_CID_SIZE] = '\0';
210		con = hmdfs_lookup_from_cid(sbi, cid);
211		if (!con) {
212			kfree(cid);
213			err = -ENOENT;
214			ret_dentry = ERR_PTR(err);
215			goto out;
216		}
217		di->device_id = con->device_id;
218		root_inode = fill_device_inode_remote(sb, di->device_id);
219		if (IS_ERR(root_inode)) {
220			kfree(cid);
221			err = PTR_ERR(root_inode);
222			ret_dentry = ERR_PTR(err);
223			goto out;
224		}
225		ret_dentry = d_splice_alias(root_inode, child_dentry);
226		kfree(cid);
227	}
228	if (root_inode)
229		hmdfs_root_inode_perm_init(root_inode);
230	if (!err)
231		hmdfs_set_time(child_dentry, jiffies);
232out:
233	if (con)
234		peer_put(con);
235	trace_hmdfs_device_lookup_end(parent_inode, child_dentry, err);
236	return ret_dentry;
237}
238
239struct dentry *hmdfs_root_lookup(struct inode *parent_inode,
240				 struct dentry *child_dentry,
241				 unsigned int flags)
242{
243	const char *d_name = child_dentry->d_name.name;
244	struct inode *root_inode = NULL;
245	struct super_block *sb = parent_inode->i_sb;
246	struct hmdfs_sb_info *sbi = sb->s_fs_info;
247	struct dentry *ret = ERR_PTR(-ENOENT);
248	struct path root_path;
249
250	trace_hmdfs_root_lookup(parent_inode, child_dentry, flags);
251	if (sbi->s_merge_switch && !strcmp(d_name, MERGE_VIEW_ROOT)) {
252		ret = hmdfs_lookup_merge(parent_inode, child_dentry, flags);
253		if (ret && !IS_ERR(ret))
254			child_dentry = ret;
255		root_inode = d_inode(child_dentry);
256	} else if (sbi->s_merge_switch && !strcmp(d_name, CLOUD_MERGE_VIEW_ROOT)) {
257		ret = hmdfs_lookup_cloud_merge(parent_inode, child_dentry, flags);
258		if (ret && !IS_ERR(ret))
259			child_dentry = ret;
260		root_inode = d_inode(child_dentry);
261	} else if (!strcmp(d_name, DEVICE_VIEW_ROOT)) {
262		ret = ERR_PTR(init_hmdfs_dentry_info(
263			sbi, child_dentry, HMDFS_LAYER_FIRST_DEVICE));
264		if (IS_ERR(ret))
265			goto out;
266		ret = ERR_PTR(kern_path(sbi->local_src, 0, &root_path));
267		if (IS_ERR(ret))
268			goto out;
269		root_inode = fill_device_inode(sb, d_inode(root_path.dentry));
270		ret = d_splice_alias(root_inode, child_dentry);
271		path_put(&root_path);
272	}
273	if (!IS_ERR(ret) && root_inode)
274		hmdfs_root_inode_perm_init(root_inode);
275
276out:
277	trace_hmdfs_root_lookup_end(parent_inode, child_dentry,
278				    PTR_ERR_OR_ZERO(ret));
279	return ret;
280}
281
282const struct inode_operations hmdfs_device_ops = {
283	.lookup = hmdfs_device_lookup,
284};
285
286const struct inode_operations hmdfs_root_ops = {
287	.lookup = hmdfs_root_lookup,
288};
289
290struct inode *fill_device_inode(struct super_block *sb,
291				struct inode *lower_inode)
292{
293	struct inode *inode = NULL;
294	struct hmdfs_inode_info *info = NULL;
295
296	inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV, NULL, NULL);
297	if (!inode) {
298		hmdfs_err("iget5_locked get inode NULL");
299		return ERR_PTR(-ENOMEM);
300	}
301	if (!(inode->i_state & I_NEW))
302		return inode;
303
304	info = hmdfs_i(inode);
305	info->inode_type = HMDFS_LAYER_FIRST_DEVICE;
306
307	inode->i_atime = lower_inode->i_atime;
308	inode->__i_ctime = lower_inode->__i_ctime;
309	inode->i_mtime = lower_inode->i_mtime;
310
311	inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | S_IXUSR |
312			S_IRGRP | S_IXGRP | S_IXOTH;
313	inode->i_uid = KUIDT_INIT((uid_t)1000);
314	inode->i_gid = KGIDT_INIT((gid_t)1000);
315	inode->i_op = &hmdfs_device_ops;
316	inode->i_fop = &hmdfs_device_fops;
317
318	fsstack_copy_inode_size(inode, lower_inode);
319	unlock_new_inode(inode);
320	return inode;
321}
322
323struct inode *fill_root_inode(struct super_block *sb, struct hmdfs_sb_info *sbi, struct inode *lower_inode)
324{
325	struct inode *inode = NULL;
326	struct hmdfs_inode_info *info = NULL;
327
328	if (!igrab(lower_inode))
329		return ERR_PTR(-ESTALE);
330
331	if (sbi->s_cloud_disk_switch) {
332		inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_DEV_LOCAL, lower_inode,
333				       NULL);
334	} else {
335		inode = hmdfs_iget_locked_root(sb, HMDFS_ROOT_ANCESTOR, lower_inode,
336				       NULL);
337	}
338
339	if (!inode) {
340		hmdfs_err("iget5_locked get inode NULL");
341		iput(lower_inode);
342		return ERR_PTR(-ENOMEM);
343	}
344	if (!(inode->i_state & I_NEW)) {
345		iput(lower_inode);
346		return inode;
347	}
348
349	info = hmdfs_i(inode);
350	if (sbi->s_cloud_disk_switch) {
351		info->inode_type = HMDFS_LAYER_SECOND_LOCAL;
352		inode->i_op = &hmdfs_dir_inode_ops_local;
353		inode->i_fop = &hmdfs_dir_ops_local;
354	} else {
355		info->inode_type = HMDFS_LAYER_ZERO;
356		inode->i_op = &hmdfs_root_ops;
357		inode->i_fop = &hmdfs_root_fops;
358	}
359	inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | S_IXUSR |
360			S_IRGRP | S_IXGRP | S_IXOTH;
361
362#ifdef CONFIG_HMDFS_FS_PERMISSION
363	inode->i_uid = lower_inode->i_uid;
364	inode->i_gid = lower_inode->i_gid;
365#else
366	inode->i_uid = KUIDT_INIT((uid_t)1000);
367	inode->i_gid = KGIDT_INIT((gid_t)1000);
368#endif
369	inode->i_atime = lower_inode->i_atime;
370	inode->__i_ctime = lower_inode->__i_ctime;
371	inode->i_mtime = lower_inode->i_mtime;
372
373	fsstack_copy_inode_size(inode, lower_inode);
374	unlock_new_inode(inode);
375	return inode;
376}
377