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