xref: /kernel/linux/linux-6.6/fs/hmdfs/inode_remote.c (revision 62306a36)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/hmdfs/inode_remote.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8#include <linux/fs_stack.h>
9#include <linux/namei.h>
10#include <linux/xattr.h>
11#include <linux/string.h>
12
13#include "comm/socket_adapter.h"
14#include "hmdfs.h"
15#include "hmdfs_client.h"
16#include "hmdfs_dentryfile.h"
17#include "hmdfs_share.h"
18#include "hmdfs_trace.h"
19#include "authority/authentication.h"
20#include "stash.h"
21
22struct hmdfs_lookup_ret *lookup_remote_dentry(struct dentry *child_dentry,
23					      const struct qstr *qstr,
24					      uint64_t dev_id)
25{
26	struct hmdfs_lookup_ret *lookup_ret;
27	struct hmdfs_dentry *dentry = NULL;
28	struct clearcache_item *cache_item = NULL;
29	struct hmdfs_dcache_lookup_ctx ctx;
30	struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
31
32	cache_item = hmdfs_find_cache_item(dev_id, child_dentry->d_parent);
33	if (!cache_item)
34		return NULL;
35
36	lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL);
37	if (!lookup_ret)
38		goto out;
39
40	hmdfs_init_dcache_lookup_ctx(&ctx, sbi, qstr, cache_item->filp);
41	dentry = hmdfs_find_dentry(child_dentry, &ctx);
42	if (!dentry) {
43		kfree(lookup_ret);
44		lookup_ret = NULL;
45		goto out;
46	}
47
48	lookup_ret->i_mode = le16_to_cpu(dentry->i_mode);
49	lookup_ret->i_size = le64_to_cpu(dentry->i_size);
50	lookup_ret->i_mtime = le64_to_cpu(dentry->i_mtime);
51	lookup_ret->i_mtime_nsec = le32_to_cpu(dentry->i_mtime_nsec);
52	lookup_ret->i_ino = le64_to_cpu(dentry->i_ino);
53
54	hmdfs_unlock_file(ctx.filp, get_dentry_group_pos(ctx.bidx),
55			  DENTRYGROUP_SIZE);
56	kfree(ctx.page);
57out:
58	kref_put(&cache_item->ref, release_cache_item);
59	return lookup_ret;
60}
61
62/* get_remote_inode_info - fill hmdfs_lookup_ret by info from remote getattr
63 *
64 * @dentry: local dentry
65 * @hmdfs_peer: which remote devcie
66 * @flags: lookup flags
67 *
68 * return allocaed and initialized hmdfs_lookup_ret on success, and NULL on
69 * failure.
70 */
71struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con,
72					       struct dentry *dentry,
73					       unsigned int flags)
74{
75	int err = 0;
76	struct hmdfs_lookup_ret *lookup_ret = NULL;
77	struct hmdfs_getattr_ret *getattr_ret = NULL;
78	unsigned int expected_flags = 0;
79
80	lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL);
81	if (!lookup_ret)
82		return NULL;
83
84	err = hmdfs_remote_getattr(con, dentry, flags, &getattr_ret);
85	if (err) {
86		hmdfs_debug("inode info get failed with err %d", err);
87		kfree(lookup_ret);
88		return NULL;
89	}
90	/* make sure we got everything we need */
91	expected_flags = STATX_INO | STATX_SIZE | STATX_MODE | STATX_MTIME;
92	if ((getattr_ret->stat.result_mask & expected_flags) !=
93	    expected_flags) {
94		hmdfs_debug("remote getattr failed with flag %x",
95			    getattr_ret->stat.result_mask);
96		kfree(lookup_ret);
97		kfree(getattr_ret);
98		return NULL;
99	}
100
101	lookup_ret->i_mode = getattr_ret->stat.mode;
102	lookup_ret->i_size = getattr_ret->stat.size;
103	lookup_ret->i_mtime = getattr_ret->stat.mtime.tv_sec;
104	lookup_ret->i_mtime_nsec = getattr_ret->stat.mtime.tv_nsec;
105	lookup_ret->i_ino = getattr_ret->stat.ino;
106	kfree(getattr_ret);
107	return lookup_ret;
108}
109
110static void hmdfs_remote_readdir_work(struct work_struct *work)
111{
112	struct hmdfs_readdir_work *rw =
113		container_of(to_delayed_work(work), struct hmdfs_readdir_work,
114			     dwork);
115	struct dentry *dentry = rw->dentry;
116	struct hmdfs_peer *con = rw->con;
117	const struct cred *old_cred = hmdfs_override_creds(con->sbi->cred);
118	bool empty = false;
119
120	get_remote_dentry_file(dentry, con);
121	hmdfs_d(dentry)->async_readdir_in_progress = 0;
122	hmdfs_revert_creds(old_cred);
123
124	spin_lock(&con->sbi->async_readdir_work_lock);
125	list_del(&rw->head);
126	empty = list_empty(&con->sbi->async_readdir_work_list);
127	spin_unlock(&con->sbi->async_readdir_work_lock);
128
129	dput(dentry);
130	peer_put(con);
131	kfree(rw);
132
133	if (empty)
134		wake_up_interruptible(&con->sbi->async_readdir_wq);
135}
136
137static void get_remote_dentry_file_in_wq(struct dentry *dentry,
138					 struct hmdfs_peer *con)
139{
140	struct hmdfs_readdir_work *rw = NULL;
141
142	/* do nothing if async readdir is already in progress */
143	if (cmpxchg_relaxed(&hmdfs_d(dentry)->async_readdir_in_progress, 0,
144			     1))
145		return;
146
147	rw = kmalloc(sizeof(*rw), GFP_KERNEL);
148	if (!rw) {
149		hmdfs_d(dentry)->async_readdir_in_progress = 0;
150		return;
151	}
152
153	dget(dentry);
154	peer_get(con);
155	rw->dentry = dentry;
156	rw->con = con;
157	spin_lock(&con->sbi->async_readdir_work_lock);
158	INIT_DELAYED_WORK(&rw->dwork, hmdfs_remote_readdir_work);
159	list_add(&rw->head, &con->sbi->async_readdir_work_list);
160	spin_unlock(&con->sbi->async_readdir_work_lock);
161	queue_delayed_work(con->dentry_wq, &rw->dwork, 0);
162}
163
164void get_remote_dentry_file_sync(struct dentry *dentry, struct hmdfs_peer *con)
165{
166	get_remote_dentry_file_in_wq(dentry, con);
167	flush_workqueue(con->dentry_wq);
168}
169
170struct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con,
171					     struct dentry *dentry,
172					     struct qstr *qstr,
173					     unsigned int flags,
174					     const char *relative_path)
175{
176	struct hmdfs_lookup_ret *result = NULL;
177
178	/*
179		* LOOKUP_REVAL means we found stale info from dentry file, thus
180		* we need to use remote getattr.
181		*/
182	if (flags & LOOKUP_REVAL) {
183		/*
184			* HMDFS_LOOKUP_REVAL means we need to skip dentry cache
185			* in lookup, because dentry cache in server might have
186			* stale data.
187			*/
188		result = get_remote_inode_info(con, dentry,
189						HMDFS_LOOKUP_REVAL);
190		get_remote_dentry_file_in_wq(dentry->d_parent, con);
191		return result;
192	}
193
194	/* If cache file is still valid */
195	if (hmdfs_cache_revalidate(READ_ONCE(con->conn_time),
196					con->device_id, dentry->d_parent)) {
197		result = lookup_remote_dentry(dentry, qstr,
198						con->device_id);
199		/*
200			* If lookup from cache file failed, use getattr to see
201			* if remote have created the file.
202			*/
203		if (!(flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) &&
204			!result)
205			result = get_remote_inode_info(con, dentry, 0);
206		/* If cache file expired, use getattr directly
207			* except create and rename opt
208			*/
209	} else {
210		result = get_remote_inode_info(con, dentry, 0);
211		get_remote_dentry_file_in_wq(dentry->d_parent, con);
212	}
213
214	return result;
215}
216
217/*
218 * hmdfs_update_inode_size - update inode size when finding aready existed
219 * inode.
220 *
221 * First of all, if the file is opened for writing, we don't update inode size
222 * here, because inode size is about to be changed after writing.
223 *
224 * If the file is not opened, simply update getattr_isize(not actual inode size,
225 * just a value showed to user). This is safe because inode size will be
226 * up-to-date after open.
227 *
228 * If the file is opened for read:
229 * a. getattr_isize == HMDFS_STALE_REMOTE_ISIZE
230 *   1) i_size == new_size, nothing need to be done.
231 *   2) i_size > new_size, we keep the i_size and set getattr_isize to new_size,
232 *      stale data might be readed in this case, which is fine because file is
233 *      opened before remote truncate the file.
234 *   3) i_size < new_size, we drop the last page of the file if i_size is not
235 *      aligned to PAGE_SIZE, clear getattr_isize, and update i_size to
236 *      new_size.
237 * b. getattr_isize != HMDFS_STALE_REMOTE_ISIZE, getattr_isize will only be set
238 *    after 2).
239 *   4) getattr_isize > i_size, this situation is impossible.
240 *   5) i_size >= new_size, this case is the same as 2).
241 *   6) i_size < new_size, this case is the same as 3).
242 */
243static void hmdfs_update_inode_size(struct inode *inode, uint64_t new_size)
244{
245	struct hmdfs_inode_info *info = hmdfs_i(inode);
246	int writecount;
247	uint64_t size;
248
249	inode_lock(inode);
250	size = info->getattr_isize;
251	if (size == HMDFS_STALE_REMOTE_ISIZE)
252		size = i_size_read(inode);
253	if (size == new_size) {
254		inode_unlock(inode);
255		return;
256	}
257
258	writecount = atomic_read(&inode->i_writecount);
259	/* check if writing is in progress */
260	if (writecount > 0) {
261		info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
262		inode_unlock(inode);
263		return;
264	}
265
266	/* check if there is no one who opens the file */
267	if (kref_read(&info->ref) == 0)
268		goto update_info;
269
270	/* check if there is someone who opens the file for read */
271	if (writecount == 0) {
272		uint64_t aligned_size;
273
274		/* use inode size here instead of getattr_isize */
275		size = i_size_read(inode);
276		if (new_size <= size)
277			goto update_info;
278		/*
279		 * if the old inode size is not aligned to HMDFS_PAGE_SIZE, we
280		 * need to drop the last page of the inode, otherwise zero will
281		 * be returned while reading the new range in the page after
282		 * chaning inode size.
283		 */
284		aligned_size = round_down(size, HMDFS_PAGE_SIZE);
285		if (aligned_size != size)
286			truncate_inode_pages(inode->i_mapping, aligned_size);
287		i_size_write(inode, new_size);
288		info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
289		inode_unlock(inode);
290		return;
291	}
292
293update_info:
294	info->getattr_isize = new_size;
295	inode_unlock(inode);
296}
297
298static void hmdfs_update_inode(struct inode *inode,
299			       struct hmdfs_lookup_ret *lookup_result)
300{
301	struct hmdfs_time_t remote_mtime = {
302		.tv_sec = lookup_result->i_mtime,
303		.tv_nsec = lookup_result->i_mtime_nsec,
304	};
305
306	/*
307	 * We only update mtime if the file is not opened for writing. If we do
308	 * update it before writing is about to start, user might see the mtime
309	 * up-and-down if system time in server and client do not match. However
310	 * mtime in client will eventually match server after timeout without
311	 * writing.
312	 */
313	if (!inode_is_open_for_write(inode))
314		inode->i_mtime = remote_mtime;
315
316	/*
317	 * We don't care i_size of dir, and lock inode for dir
318	 * might cause deadlock.
319	 */
320	if (S_ISREG(inode->i_mode))
321		hmdfs_update_inode_size(inode, lookup_result->i_size);
322}
323
324static void hmdfs_fill_inode_remote(struct inode *inode, struct inode *dir,
325				     umode_t mode)
326{
327#ifdef CONFIG_HMDFS_FS_PERMISSION
328	inode->i_uid = dir->i_uid;
329	inode->i_gid = dir->i_gid;
330#endif
331}
332
333struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con,
334				struct hmdfs_lookup_ret *res, struct inode *dir)
335{
336	int ret = 0;
337	struct inode *inode = NULL;
338	struct hmdfs_inode_info *info;
339	umode_t mode = res->i_mode;
340
341	inode = hmdfs_iget5_locked_remote(sb, con, res->i_ino);
342	if (!inode)
343		return ERR_PTR(-ENOMEM);
344
345	info = hmdfs_i(inode);
346	info->inode_type = HMDFS_LAYER_OTHER_REMOTE;
347
348	/* the inode was found in cache */
349	if (!(inode->i_state & I_NEW)) {
350		hmdfs_fill_inode_remote(inode, dir, mode);
351		hmdfs_update_inode(inode, res);
352		return inode;
353	}
354
355	hmdfs_remote_init_stash_status(con, inode, mode);
356
357	inode->__i_ctime.tv_sec = 0;
358	inode->__i_ctime.tv_nsec = 0;
359	inode->i_mtime.tv_sec = res->i_mtime;
360	inode->i_mtime.tv_nsec = res->i_mtime_nsec;
361
362	inode->i_uid = KUIDT_INIT((uid_t)1000);
363	inode->i_gid = KGIDT_INIT((gid_t)1000);
364
365	if (S_ISDIR(mode))
366		inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
367	else if (S_ISREG(mode))
368		inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
369	else if (S_ISLNK(mode))
370		inode->i_mode = S_IFREG | S_IRWXU | S_IRWXG;
371	else {
372		ret = -EIO;
373		goto bad_inode;
374	}
375
376	if (S_ISREG(mode) || S_ISLNK(mode)) {
377		inode->i_op = &hmdfs_dev_file_iops_remote;
378		inode->i_fop = &hmdfs_dev_file_fops_remote;
379		inode->i_size = res->i_size;
380		set_nlink(inode, 1);
381	} else if (S_ISDIR(mode)) {
382		inode->i_op = &hmdfs_dev_dir_inode_ops_remote;
383		inode->i_fop = &hmdfs_dev_dir_ops_remote;
384		set_nlink(inode, 2);
385	} else {
386		ret = -EIO;
387		goto bad_inode;
388	}
389
390	inode->i_mapping->a_ops = &hmdfs_dev_file_aops_remote;
391
392	hmdfs_fill_inode_remote(inode, dir, mode);
393	unlock_new_inode(inode);
394	return inode;
395bad_inode:
396	iget_failed(inode);
397	return ERR_PTR(ret);
398}
399
400static struct dentry *hmdfs_lookup_remote_dentry(struct inode *parent_inode,
401						 struct dentry *child_dentry,
402						 int flags)
403{
404	struct dentry *ret = NULL;
405	struct inode *inode = NULL;
406	struct super_block *sb = parent_inode->i_sb;
407	struct hmdfs_sb_info *sbi = sb->s_fs_info;
408	struct hmdfs_lookup_ret *lookup_result = NULL;
409	struct hmdfs_peer *con = NULL;
410	char *file_name = NULL;
411	int file_name_len = child_dentry->d_name.len;
412	struct qstr qstr;
413	struct hmdfs_dentry_info *gdi = hmdfs_d(child_dentry);
414	uint64_t device_id = 0;
415	char *relative_path = NULL;
416
417	file_name = kzalloc(NAME_MAX + 1, GFP_KERNEL);
418	if (!file_name)
419		return ERR_PTR(-ENOMEM);
420	strncpy(file_name, child_dentry->d_name.name, file_name_len);
421
422	qstr.name = file_name;
423	qstr.len = strlen(file_name);
424
425	device_id = gdi->device_id;
426	con = hmdfs_lookup_from_devid(sbi, device_id);
427	if (!con) {
428		ret = ERR_PTR(-ESHUTDOWN);
429		goto done;
430	}
431
432	relative_path = hmdfs_get_dentry_relative_path(child_dentry->d_parent);
433	if (unlikely(!relative_path)) {
434		ret = ERR_PTR(-ENOMEM);
435		hmdfs_err("get relative path failed %d", -ENOMEM);
436		goto done;
437	}
438
439	lookup_result = hmdfs_lookup_by_con(con, child_dentry, &qstr, flags,
440					    relative_path);
441	if (lookup_result != NULL) {
442		if (S_ISLNK(lookup_result->i_mode))
443			gdi->file_type = HM_SYMLINK;
444		else if (in_share_dir(child_dentry))
445			gdi->file_type = HM_SHARE;
446		inode = fill_inode_remote(sb, con, lookup_result, parent_inode);
447		check_and_fixup_ownership_remote(parent_inode,
448						 inode,
449						 child_dentry);
450		ret = d_splice_alias(inode, child_dentry);
451		if (!IS_ERR_OR_NULL(ret))
452			child_dentry = ret;
453	} else {
454		ret = ERR_PTR(-ENOENT);
455	}
456
457done:
458	if (con)
459		peer_put(con);
460	kfree(relative_path);
461	kfree(lookup_result);
462	kfree(file_name);
463	return ret;
464}
465
466struct dentry *hmdfs_lookup_remote(struct inode *parent_inode,
467				   struct dentry *child_dentry,
468				   unsigned int flags)
469{
470	int err = 0;
471	struct dentry *ret = NULL;
472	struct hmdfs_dentry_info *gdi = NULL;
473	struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
474
475	trace_hmdfs_lookup_remote(parent_inode, child_dentry, flags);
476	if (child_dentry->d_name.len > NAME_MAX) {
477		err = -ENAMETOOLONG;
478		ret = ERR_PTR(-ENAMETOOLONG);
479		goto out;
480	}
481
482	err = init_hmdfs_dentry_info(sbi, child_dentry,
483				     HMDFS_LAYER_OTHER_REMOTE);
484	if (err) {
485		ret = ERR_PTR(err);
486		goto out;
487	}
488	gdi = hmdfs_d(child_dentry);
489	gdi->device_id = hmdfs_d(child_dentry->d_parent)->device_id;
490
491	if (is_current_hmdfs_server_ctx())
492		goto out;
493
494	ret = hmdfs_lookup_remote_dentry(parent_inode, child_dentry, flags);
495	/*
496	 * don't return error if inode do not exist, so that vfs can continue
497	 * to create it.
498	 */
499	if (IS_ERR_OR_NULL(ret)) {
500		err = PTR_ERR(ret);
501		if (err == -ENOENT)
502			ret = NULL;
503	} else {
504		child_dentry = ret;
505	}
506
507out:
508	if (!err)
509		hmdfs_set_time(child_dentry, jiffies);
510	trace_hmdfs_lookup_remote_end(parent_inode, child_dentry, err);
511	return ret;
512}
513
514/* delete dentry in cache file */
515void delete_in_cache_file(uint64_t dev_id, struct dentry *dentry)
516{
517	struct clearcache_item *item = NULL;
518
519	item = hmdfs_find_cache_item(dev_id, dentry->d_parent);
520	if (item) {
521		hmdfs_delete_dentry(dentry, item->filp);
522		kref_put(&item->ref, release_cache_item);
523	} else {
524		hmdfs_info("find cache item failed, con:%llu", dev_id);
525	}
526}
527
528int hmdfs_mkdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry,
529			      umode_t mode)
530{
531	int err = 0;
532	char *dir_path = NULL;
533	struct dentry *parent_dentry = dentry->d_parent;
534	struct inode *parent_inode = d_inode(parent_dentry);
535	struct super_block *sb = parent_inode->i_sb;
536	const unsigned char *d_name = dentry->d_name.name;
537	struct hmdfs_lookup_ret *mkdir_ret = NULL;
538	struct inode *inode = NULL;
539
540	mkdir_ret = kmalloc(sizeof(*mkdir_ret), GFP_KERNEL);
541	if (!mkdir_ret) {
542		err = -ENOMEM;
543		return err;
544	}
545	dir_path = hmdfs_get_dentry_relative_path(parent_dentry);
546	if (!dir_path) {
547		err = -EACCES;
548		goto mkdir_out;
549	}
550	err = hmdfs_client_start_mkdir(conn, dir_path, d_name, mode, mkdir_ret);
551	if (err) {
552		hmdfs_err("hmdfs_client_start_mkdir failed err = %d", err);
553		goto mkdir_out;
554	}
555	if (mkdir_ret) {
556		inode = fill_inode_remote(sb, conn, mkdir_ret, parent_inode);
557		check_and_fixup_ownership_remote(parent_inode,
558						 inode,
559						 dentry);
560		if (!IS_ERR(inode))
561			d_add(dentry, inode);
562		else
563			err = PTR_ERR(inode);
564	} else {
565		err = -ENOENT;
566	}
567
568mkdir_out:
569	kfree(dir_path);
570	kfree(mkdir_ret);
571	return err;
572}
573
574int hmdfs_mkdir_remote(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)
575{
576	int err = 0;
577	struct hmdfs_inode_info *info = hmdfs_i(dir);
578	struct hmdfs_peer *con = info->conn;
579
580	if (!con) {
581		hmdfs_warning("qpb_debug: con is null!");
582		goto out;
583	}
584
585	err = hmdfs_mkdir_remote_dentry(con, dentry, mode);
586	if (!err)
587		create_in_cache_file(con->device_id, dentry);
588	else
589		hmdfs_err("remote mkdir failed err = %d", err);
590
591out:
592	trace_hmdfs_mkdir_remote(dir, dentry, err);
593	return err;
594}
595
596int hmdfs_create_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry,
597			       umode_t mode, bool want_excl)
598{
599	int err = 0;
600	char *dir_path = NULL;
601	struct dentry *parent_dentry = dentry->d_parent;
602	struct inode *parent_inode = d_inode(parent_dentry);
603	struct super_block *sb = parent_inode->i_sb;
604	const unsigned char *d_name = dentry->d_name.name;
605	struct hmdfs_lookup_ret *create_ret = NULL;
606	struct inode *inode = NULL;
607
608	create_ret = kmalloc(sizeof(*create_ret), GFP_KERNEL);
609	if (!create_ret) {
610		err = -ENOMEM;
611		return err;
612	}
613	dir_path = hmdfs_get_dentry_relative_path(parent_dentry);
614	if (!dir_path) {
615		err = -EACCES;
616		goto create_out;
617	}
618	err = hmdfs_client_start_create(conn, dir_path, d_name, mode,
619					want_excl, create_ret);
620	if (err) {
621		hmdfs_err("hmdfs_client_start_create failed err = %d", err);
622		goto create_out;
623	}
624	if (create_ret) {
625		inode = fill_inode_remote(sb, conn, create_ret, parent_inode);
626		check_and_fixup_ownership_remote(parent_inode,
627						 inode,
628						 dentry);
629		if (!IS_ERR(inode))
630			d_add(dentry, inode);
631		else
632			err = PTR_ERR(inode);
633	} else {
634		err = -ENOENT;
635		hmdfs_err("get remote inode info failed err = %d", err);
636	}
637
638create_out:
639	kfree(dir_path);
640	kfree(create_ret);
641	return err;
642}
643
644int hmdfs_create_remote(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode,
645			bool want_excl)
646{
647	int err = 0;
648	struct hmdfs_inode_info *info = hmdfs_i(dir);
649	struct hmdfs_peer *con = info->conn;
650
651	if (!con) {
652		hmdfs_warning("qpb_debug: con is null!");
653		goto out;
654	}
655
656	err = hmdfs_create_remote_dentry(con, dentry, mode, want_excl);
657	if (!err)
658		create_in_cache_file(con->device_id, dentry);
659	else
660		hmdfs_err("remote create failed err = %d", err);
661
662out:
663	trace_hmdfs_create_remote(dir, dentry, err);
664	return err;
665}
666
667int hmdfs_rmdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry)
668{
669	int error = 0;
670	char *dir_path = NULL;
671	const char *dentry_name = dentry->d_name.name;
672
673	dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent);
674	if (!dir_path) {
675		error = -EACCES;
676		goto rmdir_out;
677	}
678
679	error = hmdfs_client_start_rmdir(conn, dir_path, dentry_name);
680	if (!error)
681		delete_in_cache_file(conn->device_id, dentry);
682
683rmdir_out:
684	kfree(dir_path);
685	return error;
686}
687
688int hmdfs_rmdir_remote(struct inode *dir, struct dentry *dentry)
689{
690	int err = 0;
691	struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode);
692	struct hmdfs_peer *con = info->conn;
693
694	if (!con)
695		goto out;
696
697	if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) {
698		err = -EACCES;
699		goto out;
700	}
701
702	err = hmdfs_rmdir_remote_dentry(con, dentry);
703	/* drop dentry even remote failed
704	 * it maybe cause that one remote devices disconnect
705	 * when doing remote rmdir
706	 */
707	d_drop(dentry);
708out:
709	/* return connect device's errcode */
710	trace_hmdfs_rmdir_remote(dir, dentry, err);
711	return err;
712}
713
714int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn, struct dentry *dentry)
715{
716	int error = 0;
717	char *dir_path = NULL;
718	const char *dentry_name = dentry->d_name.name;
719
720	dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent);
721	if (!dir_path) {
722		error = -EACCES;
723		goto unlink_out;
724	}
725	error = hmdfs_client_start_unlink(conn, dir_path, dentry_name);
726	if (!error) {
727		delete_in_cache_file(conn->device_id, dentry);
728		drop_nlink(d_inode(dentry));
729		d_drop(dentry);
730	}
731unlink_out:
732	kfree(dir_path);
733	return error;
734}
735
736int hmdfs_unlink_remote(struct inode *dir, struct dentry *dentry)
737{
738	struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode);
739	struct hmdfs_peer *conn = info->conn;
740
741	if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON)
742		return -EACCES;
743
744	if (!conn)
745		return 0;
746
747	if (conn->status != NODE_STAT_ONLINE)
748		return 0;
749
750	return hmdfs_dev_unlink_from_con(conn, dentry);
751}
752
753/* rename dentry in cache file */
754static void rename_in_cache_file(uint64_t dev_id, struct dentry *old_dentry,
755				 struct dentry *new_dentry)
756{
757	struct clearcache_item *old_item = NULL;
758	struct clearcache_item *new_item = NULL;
759
760	old_item = hmdfs_find_cache_item(dev_id, old_dentry->d_parent);
761	new_item = hmdfs_find_cache_item(dev_id, new_dentry->d_parent);
762	if (old_item != NULL && new_item != NULL) {
763		hmdfs_rename_dentry(old_dentry, new_dentry, old_item->filp,
764				    new_item->filp);
765	} else if (old_item != NULL) {
766		hmdfs_err("new cache item find failed!");
767	} else if (new_item != NULL) {
768		hmdfs_err("old cache item find failed!");
769	} else {
770		hmdfs_err("both cache item find failed!");
771	}
772
773	if (old_item)
774		kref_put(&old_item->ref, release_cache_item);
775	if (new_item)
776		kref_put(&new_item->ref, release_cache_item);
777}
778
779int hmdfs_rename_remote(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry,
780			struct inode *new_dir, struct dentry *new_dentry,
781			unsigned int flags)
782{
783	int err = 0;
784	int ret = 0;
785	const char *old_dentry_d_name = old_dentry->d_name.name;
786	char *relative_old_dir_path = 0;
787	const char *new_dentry_d_name = new_dentry->d_name.name;
788	char *relative_new_dir_path = 0;
789	struct hmdfs_inode_info *info = hmdfs_i(old_dentry->d_inode);
790	struct hmdfs_peer *con = info->conn;
791
792	trace_hmdfs_rename_remote(old_dir, old_dentry, new_dir, new_dentry,
793				  flags);
794
795	if (flags & ~RENAME_NOREPLACE)
796		return -EINVAL;
797
798	if (hmdfs_file_type(old_dentry->d_name.name) != HMDFS_TYPE_COMMON ||
799	    hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) {
800		return -EACCES;
801	}
802
803	if (hmdfs_i(old_dir)->inode_type != hmdfs_i(new_dir)->inode_type) {
804		hmdfs_err("in different view");
805		return -EPERM;
806	}
807
808	if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id)
809		return -EXDEV;
810
811	relative_old_dir_path =
812		hmdfs_get_dentry_relative_path(old_dentry->d_parent);
813	relative_new_dir_path =
814		hmdfs_get_dentry_relative_path(new_dentry->d_parent);
815	if (!relative_old_dir_path || !relative_new_dir_path) {
816		err = -EACCES;
817		goto rename_out;
818	}
819	if (S_ISREG(old_dentry->d_inode->i_mode)) {
820		hmdfs_debug("send MSG to remote devID %llu",
821				con->device_id);
822		err = hmdfs_client_start_rename(
823			con, relative_old_dir_path, old_dentry_d_name,
824			relative_new_dir_path, new_dentry_d_name,
825			flags);
826		if (!err)
827			rename_in_cache_file(con->device_id, old_dentry,
828						new_dentry);
829	} else if (S_ISDIR(old_dentry->d_inode->i_mode)) {
830		if (con->status == NODE_STAT_ONLINE) {
831			ret = hmdfs_client_start_rename(
832				con, relative_old_dir_path, old_dentry_d_name,
833				relative_new_dir_path, new_dentry_d_name,
834				flags);
835			if (!ret)
836				rename_in_cache_file(con->device_id, old_dentry,
837						     new_dentry);
838			else
839				err = ret;
840		}
841	}
842	if (!err)
843		d_invalidate(old_dentry);
844rename_out:
845	kfree(relative_old_dir_path);
846	kfree(relative_new_dir_path);
847	return err;
848}
849
850static int hmdfs_dir_setattr_remote(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)
851{
852	// Do not support dir setattr
853	return 0;
854}
855
856const struct inode_operations hmdfs_dev_dir_inode_ops_remote = {
857	.lookup = hmdfs_lookup_remote,
858	.mkdir = hmdfs_mkdir_remote,
859	.create = hmdfs_create_remote,
860	.rmdir = hmdfs_rmdir_remote,
861	.unlink = hmdfs_unlink_remote,
862	.rename = hmdfs_rename_remote,
863	.setattr = hmdfs_dir_setattr_remote,
864	.permission = hmdfs_permission,
865};
866
867static int hmdfs_setattr_remote(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)
868{
869	struct hmdfs_inode_info *info = hmdfs_i(d_inode(dentry));
870	struct hmdfs_peer *conn = info->conn;
871	struct inode *inode = d_inode(dentry);
872	char *send_buf = NULL;
873	int err = 0;
874
875	if (hmdfs_inode_is_stashing(info))
876		return -EAGAIN;
877
878	send_buf = hmdfs_get_dentry_relative_path(dentry);
879	if (!send_buf) {
880		err = -ENOMEM;
881		goto out_free;
882	}
883	if (ia->ia_valid & ATTR_SIZE) {
884		err = inode_newsize_ok(inode, ia->ia_size);
885		if (err)
886			goto out_free;
887		truncate_setsize(inode, ia->ia_size);
888		info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
889	}
890	if (ia->ia_valid & ATTR_MTIME)
891		inode->i_mtime = ia->ia_mtime;
892
893	if ((ia->ia_valid & ATTR_SIZE) || (ia->ia_valid & ATTR_MTIME)) {
894		struct setattr_info send_setattr_info = {
895			.size = cpu_to_le64(ia->ia_size),
896			.valid = cpu_to_le32(ia->ia_valid),
897			.mtime = cpu_to_le64(ia->ia_mtime.tv_sec),
898			.mtime_nsec = cpu_to_le32(ia->ia_mtime.tv_nsec),
899		};
900		err = hmdfs_send_setattr(conn, send_buf, &send_setattr_info);
901	}
902out_free:
903	kfree(send_buf);
904	return err;
905}
906
907int hmdfs_remote_getattr(struct hmdfs_peer *conn, struct dentry *dentry,
908			 unsigned int lookup_flags,
909			 struct hmdfs_getattr_ret **result)
910{
911	char *send_buf = NULL;
912	struct hmdfs_getattr_ret *attr = NULL;
913	int err = 0;
914
915	if (dentry->d_sb != conn->sbi->sb || !result)
916		return -EINVAL;
917
918	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
919	if (!attr)
920		return -ENOMEM;
921
922	send_buf = hmdfs_get_dentry_relative_path(dentry);
923	if (!send_buf) {
924		kfree(attr);
925		return -ENOMEM;
926	}
927
928	err = hmdfs_send_getattr(conn, send_buf, lookup_flags, attr);
929	kfree(send_buf);
930
931	if (err) {
932		kfree(attr);
933		return err;
934	}
935
936	*result = attr;
937	return 0;
938}
939
940static int hmdfs_get_cached_attr_remote(struct mnt_idmap *idmap, const struct path *path,
941					struct kstat *stat, u32 request_mask,
942					unsigned int flags)
943{
944	struct inode *inode = d_inode(path->dentry);
945	struct hmdfs_inode_info *info = hmdfs_i(inode);
946	uint64_t size = info->getattr_isize;
947
948	stat->ino = inode->i_ino;
949	stat->mtime = inode->i_mtime;
950	stat->mode = inode->i_mode;
951	stat->uid.val = inode->i_uid.val;
952	stat->gid.val = inode->i_gid.val;
953	if (size == HMDFS_STALE_REMOTE_ISIZE)
954		size = i_size_read(inode);
955
956	stat->size = size;
957	return 0;
958}
959
960ssize_t hmdfs_remote_listxattr(struct dentry *dentry, char *list, size_t size)
961{
962	struct inode *inode = d_inode(dentry);
963	struct hmdfs_inode_info *info = hmdfs_i(inode);
964	struct hmdfs_peer *conn = info->conn;
965	char *send_buf = NULL;
966	ssize_t res = 0;
967	size_t r_size = size;
968
969	if (!hmdfs_support_xattr(dentry))
970		return -EOPNOTSUPP;
971
972	if (size > HMDFS_LISTXATTR_SIZE_MAX)
973		r_size = HMDFS_LISTXATTR_SIZE_MAX;
974
975	send_buf = hmdfs_get_dentry_relative_path(dentry);
976	if (!send_buf)
977		return -ENOMEM;
978
979	res = hmdfs_send_listxattr(conn, send_buf, list, r_size);
980	kfree(send_buf);
981
982	if (res == -ERANGE && r_size != size) {
983		hmdfs_info("no support listxattr size over than %d",
984			   HMDFS_LISTXATTR_SIZE_MAX);
985		res = -E2BIG;
986	}
987
988	return res;
989}
990
991const struct inode_operations hmdfs_dev_file_iops_remote = {
992	.setattr = hmdfs_setattr_remote,
993	.permission = hmdfs_permission,
994	.getattr = hmdfs_get_cached_attr_remote,
995	.listxattr = hmdfs_remote_listxattr,
996};
997