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