• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * fs/hmdfs/hmdfs_server.c
4  *
5  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6  */
7 
8 #include "hmdfs_server.h"
9 
10 #include <linux/file.h>
11 #include <linux/xattr.h>
12 #include <linux/namei.h>
13 #include <linux/statfs.h>
14 #include <linux/mount.h>
15 
16 #include "authority/authentication.h"
17 #include "hmdfs.h"
18 #include "hmdfs_dentryfile.h"
19 #include "hmdfs_share.h"
20 #include "hmdfs_trace.h"
21 #include "server_writeback.h"
22 #include "comm/node_cb.h"
23 
24 #define HMDFS_MAX_HIDDEN_DIR	1
25 
26 struct hmdfs_open_info {
27 	struct file *file;
28 	struct inode *inode;
29 	bool stat_valid;
30 	struct kstat stat;
31 	uint64_t real_ino;
32 	int file_id;
33 };
34 
insert_file_into_conn(struct hmdfs_peer * conn,struct file * file)35 static int insert_file_into_conn(struct hmdfs_peer *conn, struct file *file)
36 {
37 	struct idr *idr = &(conn->file_id_idr);
38 	int ret;
39 
40 	idr_preload(GFP_KERNEL);
41 	spin_lock(&(conn->file_id_lock));
42 	ret = idr_alloc_cyclic(idr, file, 0, 0, GFP_NOWAIT);
43 	spin_unlock(&(conn->file_id_lock));
44 	idr_preload_end();
45 	return ret;
46 }
47 
48 /*
49  * get_file_from_conn - get file from conn by file_id. It should be noted that
50  * an additional reference will be acquired for returned file, the called should
51  * put it after the file is not used anymore.
52  */
get_file_from_conn(struct hmdfs_peer * conn,__u32 file_id)53 static struct file *get_file_from_conn(struct hmdfs_peer *conn, __u32 file_id)
54 {
55 	struct file *file;
56 	struct idr *idr = &(conn->file_id_idr);
57 
58 	rcu_read_lock();
59 	file = idr_find(idr, file_id);
60 	if (file && !get_file_rcu(file))
61 		file = NULL;
62 	rcu_read_unlock();
63 	return file;
64 }
65 
remove_file_from_conn(struct hmdfs_peer * conn,__u32 file_id)66 void remove_file_from_conn(struct hmdfs_peer *conn, __u32 file_id)
67 {
68 	spinlock_t *lock = &(conn->file_id_lock);
69 	struct idr *idr = &(conn->file_id_idr);
70 
71 	spin_lock(lock);
72 	idr_remove(idr, file_id);
73 	spin_unlock(lock);
74 }
75 
hmdfs_open_path(struct hmdfs_sb_info * sbi,const char * path)76 struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path)
77 {
78 	struct path root_path;
79 	struct file *file;
80 	int err;
81 	const char *root_name = sbi->local_dst;
82 
83 	err = kern_path(root_name, 0, &root_path);
84 	if (err) {
85 		hmdfs_info("kern_path failed: %d", err);
86 		return ERR_PTR(err);
87 	}
88 	file = file_open_root(&root_path, path,
89 			      O_RDWR | O_LARGEFILE, 0644);
90 	path_put(&root_path);
91 	if (IS_ERR(file)) {
92 		hmdfs_err(
93 			"GRAPERR sb->s_readonly_remount %d sb_flag %lu",
94 			sbi->sb->s_readonly_remount, sbi->sb->s_flags);
95 		hmdfs_info("file_open_root failed: %ld", PTR_ERR(file));
96 	} else {
97 		hmdfs_info("get file with magic %lu",
98 			   file->f_inode->i_sb->s_magic);
99 	}
100 	return file;
101 }
102 
hmdfs_close_path(struct file * file)103 inline void hmdfs_close_path(struct file *file)
104 {
105 	fput(file);
106 }
107 
108 /* After offline server close all files opened by client */
hmdfs_server_offline_notify(struct hmdfs_peer * conn,int evt,unsigned int seq)109 void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt,
110 				 unsigned int seq)
111 {
112 	int id;
113 	int count = 0;
114 	unsigned int next;
115 	struct file *filp = NULL;
116 	struct idr *idr = &conn->file_id_idr;
117 
118 	/* wait all async work complete */
119 	flush_workqueue(conn->req_handle_wq);
120 	flush_workqueue(conn->async_wq);
121 
122 	/* If there is some open requests in processing,
123 	 * Maybe, we need to close file when peer offline
124 	 */
125 	idr_for_each_entry(idr, filp, id) {
126 		hmdfs_debug("[%d]Server close: id=%d", count, id);
127 		hmdfs_close_path(filp);
128 		count++;
129 		if (count % HMDFS_IDR_RESCHED_COUNT == 0)
130 			cond_resched();
131 	}
132 
133 	hmdfs_clear_share_item_offline(conn);
134 
135 	/* Reinitialize idr */
136 	next = idr_get_cursor(idr);
137 	idr_destroy(idr);
138 
139 	idr_init(idr);
140 	idr_set_cursor(idr, next);
141 
142 	/* Make old file id to be stale */
143 	conn->fid_cookie++;
144 }
145 
146 static struct hmdfs_node_cb_desc server_cb[] = {
147 	{
148 		.evt = NODE_EVT_OFFLINE,
149 		.sync = true,
150 		.min_version = DFS_2_0,
151 		.fn = hmdfs_server_offline_notify
152 	},
153 };
154 
hmdfs_server_add_node_evt_cb(void)155 void __init hmdfs_server_add_node_evt_cb(void)
156 {
157 	hmdfs_node_add_evt_cb(server_cb, ARRAY_SIZE(server_cb));
158 }
159 
160 static const char *datasl_str[] = {
161 	"s0", "s1", "s2", "s3", "s4"
162 };
163 
parse_data_sec_level(const char * sl_value,size_t sl_value_len)164 static int parse_data_sec_level(const char *sl_value, size_t sl_value_len)
165 {
166 	int i;
167 
168 	for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) {
169 		if (!strncmp(sl_value, datasl_str[i], strlen(datasl_str[i])))
170 			return i + DATA_SEC_LEVEL0;
171 	}
172 
173 	return DATA_SEC_LEVEL3;
174 }
175 
check_sec_level(struct hmdfs_peer * node,const char * file_name)176 static int check_sec_level(struct hmdfs_peer *node, const char *file_name)
177 {
178 	int err;
179 	int ret = 0;
180 	struct path root_path;
181 	struct path file_path;
182 	char *value = NULL;
183 	size_t value_len = DATA_SEC_LEVEL_LENGTH;
184 
185 	if (node->devsl <= 0) {
186 		ret = -EACCES;
187 		goto out_free;
188 	}
189 
190 	value = kzalloc(value_len, GFP_KERNEL);
191 	if (!value) {
192 		ret = -ENOMEM;
193 		goto out_free;
194 	}
195 
196 	err = kern_path(node->sbi->local_dst, LOOKUP_DIRECTORY, &root_path);
197 	if (err) {
198 		hmdfs_err("get root path error");
199 		ret = err;
200 		goto out_free;
201 	}
202 
203 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, file_name, 0,
204 		&file_path);
205 	if (err) {
206 		hmdfs_err("get file path error");
207 		ret = err;
208 		goto out_err;
209 	}
210 
211 	err = vfs_getxattr(file_path.dentry, DATA_SEC_LEVEL_LABEL, value,
212 		value_len);
213 	if (err <= 0 && node->devsl >= DATA_SEC_LEVEL3)
214 		goto out;
215 	if (err > 0 && node->devsl >= parse_data_sec_level(value, err))
216 		goto out;
217 
218 	ret = -EACCES;
219 out:
220 	path_put(&file_path);
221 out_err:
222 	path_put(&root_path);
223 out_free:
224 	kfree(value);
225 	return ret;
226 }
227 
hmdfs_open_file(struct hmdfs_peer * con,const char * filename,uint8_t file_type,int * file_id)228 static struct file *hmdfs_open_file(struct hmdfs_peer *con,
229 				    const char *filename, uint8_t file_type,
230 				    int *file_id)
231 {
232 	struct file *file = NULL;
233 	int err = 0;
234 	int id;
235 
236 	if (!filename) {
237 		hmdfs_err("filename is NULL");
238 		return ERR_PTR(-EINVAL);
239 	}
240 
241 	if (check_sec_level(con, filename)) {
242 		hmdfs_err("devsl permission denied");
243 		return ERR_PTR(-EACCES);
244 	}
245 
246 	if (hm_isshare(file_type)) {
247 		err = hmdfs_check_share_access_permission(con->sbi,
248 							filename, con->cid);
249 		if (err)
250 			return ERR_PTR(err);
251 	}
252 	file = hmdfs_open_path(con->sbi, filename);
253 
254 	if (IS_ERR(file)) {
255 		reset_item_opened_status(con->sbi, filename);
256 		return file;
257 	}
258 
259 	id = insert_file_into_conn(con, file);
260 	if (id < 0) {
261 		hmdfs_err("file_id alloc failed! err=%d", id);
262 		reset_item_opened_status(con->sbi, filename);
263 		hmdfs_close_path(file);
264 		return ERR_PTR(id);
265 	}
266 	*file_id = id;
267 
268 	return file;
269 }
270 
msec_to_timespec(unsigned int msec)271 static struct hmdfs_time_t msec_to_timespec(unsigned int msec)
272 {
273 	struct hmdfs_time_t timespec = {
274 		.tv_sec = msec / MSEC_PER_SEC,
275 		.tv_nsec = (msec % MSEC_PER_SEC) * NSEC_PER_MSEC,
276 	};
277 
278 	return timespec;
279 }
280 
hmdfs_current_kernel_time(void)281 static struct hmdfs_time_t hmdfs_current_kernel_time(void)
282 {
283 	struct hmdfs_time_t time;
284 
285 #if KERNEL_VERSION(4, 18, 0) < LINUX_VERSION_CODE
286 	ktime_get_coarse_real_ts64(&time);
287 #else
288 	time = current_kernel_time();
289 #endif
290 	return time;
291 }
292 
293 /*
294  * Generate fid version like following format:
295  *
296  * |     boot cookie     |  con cookie |
297  * |---------------------|-------------|
298  *           49                15       (bits)
299  */
hmdfs_server_pack_fid_ver(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd)300 static uint64_t hmdfs_server_pack_fid_ver(struct hmdfs_peer *con,
301 					  struct hmdfs_head_cmd *cmd)
302 {
303 	uint64_t boot_cookie = con->sbi->boot_cookie;
304 	uint16_t con_cookie = con->fid_cookie;
305 
306 	return (boot_cookie |
307 		(con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1)));
308 }
309 
get_file_by_fid_and_ver(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,__u32 file_id,__u64 file_ver)310 static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con,
311 					    struct hmdfs_head_cmd *cmd,
312 					    __u32 file_id, __u64 file_ver)
313 {
314 	struct file *file = NULL;
315 	__u64 cur_file_ver = hmdfs_server_pack_fid_ver(con, cmd);
316 
317 	if (file_ver != cur_file_ver) {
318 		hmdfs_warning("Stale file version %llu for fid %u",
319 			      file_ver, file_id);
320 		return ERR_PTR(-EBADF);
321 	}
322 
323 	file = get_file_from_conn(con, file_id);
324 	if (!file)
325 		return ERR_PTR(-EBADF);
326 
327 	return file;
328 }
329 
hmdfs_update_open_response(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,struct hmdfs_open_info * info,struct open_response * resp)330 static void hmdfs_update_open_response(struct hmdfs_peer *con,
331 				       struct hmdfs_head_cmd *cmd,
332 				       struct hmdfs_open_info *info,
333 				       struct open_response *resp)
334 {
335 	struct hmdfs_time_t current_time = hmdfs_current_kernel_time();
336 	struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime :
337 						       info->inode->i_ctime;
338 	struct hmdfs_time_t precision =
339 		msec_to_timespec(con->sbi->dcache_precision);
340 	loff_t size = info->stat_valid ? info->stat.size :
341 					 i_size_read(info->inode);
342 
343 	resp->ino = cpu_to_le64(info->real_ino);
344 	resp->file_ver = cpu_to_le64(hmdfs_server_pack_fid_ver(con, cmd));
345 	resp->file_id = cpu_to_le32(info->file_id);
346 	resp->file_size = cpu_to_le64(size);
347 	resp->ctime = cpu_to_le64(ctime.tv_sec);
348 	resp->ctime_nsec = cpu_to_le32(ctime.tv_nsec);
349 
350 	/*
351 	 * In server, ctime might stay the same after coverwrite. We introduce a
352 	 * new value stable_ctime to handle the problem.
353 	 * - if open rpc time < ctime, stable_ctime = 0;
354 	 * - if ctime <= open rpc time < ctime + dcache_precision, stable_ctime
355 	 *   = ctime
356 	 * - else, stable_ctime = ctime + dcache_precision;
357 	 */
358 	precision = hmdfs_time_add(ctime, precision);
359 	if (hmdfs_time_compare(&current_time, &ctime) < 0) {
360 		resp->stable_ctime = cpu_to_le64(0);
361 		resp->stable_ctime_nsec = cpu_to_le32(0);
362 	} else if (hmdfs_time_compare(&current_time, &ctime) >= 0 &&
363 		   hmdfs_time_compare(&current_time, &precision) < 0) {
364 		resp->stable_ctime = resp->ctime;
365 		resp->stable_ctime_nsec = resp->ctime_nsec;
366 	} else {
367 		resp->stable_ctime = cpu_to_le64(precision.tv_sec);
368 		resp->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec);
369 	}
370 }
371 
hmdfs_get_open_info(struct hmdfs_peer * con,uint8_t file_type,const char * filename,struct hmdfs_open_info * info)372 static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type,
373 			       const char *filename,
374 			       struct hmdfs_open_info *info)
375 {
376 	int ret = 0;
377 
378 	info->inode = file_inode(info->file);
379 	info->stat_valid = false;
380 	if (con->sbi->sb == info->inode->i_sb) {
381 		/* if open a regular file */
382 		info->inode = hmdfs_i(info->inode)->lower_inode;
383 	} else if (con->sbi->lower_sb != info->inode->i_sb) {
384 		/* It's possible that inode is not from lower, for example:
385 		 * 1. touch /f2fs/file
386 		 * 2. ln -s /sdcard_fs/file /f2fs/link
387 		 * 3. cat /hmdfs/link -> generate dentry cache in sdcard_fs
388 		 * 4. echo hi >> /hmdfs/file -> append write not through
389 		 *    sdcard_fs
390 		 * 5. cat /hmdfs/link -> got inode in sdcard, which size is
391 		 *    still 0
392 		 *
393 		 * If src file isn't in lower, use getattr to get
394 		 * information.
395 		 */
396 		ret = vfs_getattr(&info->file->f_path, &info->stat, STATX_BASIC_STATS | STATX_BTIME,
397 				  0);
398 		if (ret) {
399 			hmdfs_err("call vfs_getattr failed, err %d", ret);
400 			return ret;
401 		}
402 		info->stat_valid = true;
403 	}
404 
405 	info->real_ino = generate_u64_ino(info->inode->i_ino,
406 						  info->inode->i_generation);
407 
408 	return 0;
409 }
410 
hmdfs_server_open(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)411 void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
412 		       void *data)
413 {
414 	struct open_request *recv = data;
415 	int sizeread = sizeof(struct open_response);
416 	struct open_response *resp = NULL;
417 	struct hmdfs_open_info *info = NULL;
418 	int ret = 0;
419 
420 	trace_hmdfs_server_open_enter(con, recv);
421 
422 	resp = kzalloc(sizeread, GFP_KERNEL);
423 	info = kmalloc(sizeof(*info), GFP_KERNEL);
424 	if (!resp || !info) {
425 		ret = -ENOMEM;
426 		goto err_free;
427 	}
428 
429 	info->file = hmdfs_open_file(con, recv->buf, recv->file_type,
430 				     &info->file_id);
431 	if (IS_ERR(info->file)) {
432 		ret = PTR_ERR(info->file);
433 		goto err_free;
434 	}
435 
436 	ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info);
437 	if (ret)
438 		goto err_close;
439 
440 	hmdfs_update_open_response(con, cmd, info, resp);
441 
442 	trace_hmdfs_server_open_exit(con, resp, info->file, 0);
443 	ret = hmdfs_sendmessage_response(con, cmd, sizeread, resp, 0);
444 	if (ret) {
445 		hmdfs_err("sending msg response failed, file_id %d, err %d",
446 			  info->file_id, ret);
447 		remove_file_from_conn(con, info->file_id);
448 		hmdfs_close_path(info->file);
449 	}
450 	kfree(resp);
451 	kfree(info);
452 	return;
453 
454 err_close:
455 	remove_file_from_conn(con, info->file_id);
456 	hmdfs_close_path(info->file);
457 err_free:
458 	kfree(resp);
459 	kfree(info);
460 	trace_hmdfs_server_open_exit(con, NULL, NULL, ret);
461 	hmdfs_send_err_response(con, cmd, ret);
462 }
463 
hmdfs_check_and_create(struct path * path_parent,struct dentry * dentry,uint64_t device_id,umode_t mode,bool is_excl)464 static int hmdfs_check_and_create(struct path *path_parent,
465 				  struct dentry *dentry, uint64_t device_id,
466 				  umode_t mode, bool is_excl)
467 {
468 	int err = 0;
469 
470 	/* if inode doesn't exist, create it */
471 	if (d_is_negative(dentry)) {
472 		hmdfs_mark_drop_flag(device_id, path_parent->dentry);
473 		err = vfs_create(d_inode(path_parent->dentry), dentry, mode,
474 				 is_excl);
475 		if (err)
476 			hmdfs_err("create failed, err %d", err);
477 	} else {
478 		if (is_excl)
479 			err = -EEXIST;
480 		else if (S_ISLNK(d_inode(dentry)->i_mode))
481 			err = -EINVAL;
482 		else if (S_ISDIR(d_inode(dentry)->i_mode))
483 			err = -EISDIR;
484 	}
485 
486 	return err;
487 }
hmdfs_lookup_create(struct hmdfs_peer * con,struct atomic_open_request * recv,struct path * child_path,bool * truncate)488 static int hmdfs_lookup_create(struct hmdfs_peer *con,
489 			       struct atomic_open_request *recv,
490 			       struct path *child_path, bool *truncate)
491 {
492 	int err = 0;
493 	struct path path_root;
494 	struct path path_parent;
495 	uint32_t open_flags = le32_to_cpu(recv->open_flags);
496 	char *path = recv->buf;
497 	char *filename = recv->buf + le32_to_cpu(recv->path_len) + 1;
498 	struct dentry *dentry = NULL;
499 
500 	err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &path_root);
501 	if (err) {
502 		hmdfs_err("no path for %s, err %d", con->sbi->local_dst, err);
503 		return err;
504 	}
505 
506 	err = vfs_path_lookup(path_root.dentry, path_root.mnt, path,
507 			      LOOKUP_DIRECTORY, &path_parent);
508 	if (err) {
509 		hmdfs_info("no dir in %s, err %d", con->sbi->local_dst, err);
510 		goto put_path_root;
511 	}
512 
513 	inode_lock(d_inode(path_parent.dentry));
514 	dentry = lookup_one_len(filename, path_parent.dentry, strlen(filename));
515 	if (IS_ERR(dentry)) {
516 		err = PTR_ERR(dentry);
517 		inode_unlock(d_inode(path_parent.dentry));
518 		goto put_path_parent;
519 	}
520 	/* only truncate if inode already exists */
521 	*truncate = ((open_flags & HMDFS_O_TRUNC) && d_is_positive(dentry));
522 	err = hmdfs_check_and_create(&path_parent, dentry, con->device_id,
523 				     le16_to_cpu(recv->mode),
524 				     open_flags & HMDFS_O_EXCL);
525 	inode_unlock(d_inode(path_parent.dentry));
526 	if (err) {
527 		dput(dentry);
528 	} else {
529 		child_path->dentry = dentry;
530 		child_path->mnt = mntget(path_parent.mnt);
531 	}
532 
533 put_path_parent:
534 	path_put(&path_parent);
535 put_path_root:
536 	path_put(&path_root);
537 	return err;
538 }
539 
hmdfs_dentry_open(struct hmdfs_peer * con,const struct path * path,struct hmdfs_open_info * info)540 static int hmdfs_dentry_open(struct hmdfs_peer *con,
541 			     const struct path *path,
542 			     struct hmdfs_open_info *info)
543 {
544 	int err = 0;
545 
546 	info->file = dentry_open(path, O_RDWR | O_LARGEFILE, current_cred());
547 	if (IS_ERR(info->file)) {
548 		err = PTR_ERR(info->file);
549 		hmdfs_err("open file failed, err %d", err);
550 		return err;
551 	}
552 
553 	info->file_id = insert_file_into_conn(con, info->file);
554 	if (info->file_id < 0) {
555 		err = info->file_id;
556 		hmdfs_err("file_id alloc failed! err %d", err);
557 		hmdfs_close_path(info->file);
558 		return err;
559 	}
560 
561 	return 0;
562 }
563 
hmdfs_server_do_atomic_open(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,struct atomic_open_request * recv,struct hmdfs_open_info * info,struct atomic_open_response * resp)564 static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con,
565 				       struct hmdfs_head_cmd *cmd,
566 				       struct atomic_open_request *recv,
567 				       struct hmdfs_open_info *info,
568 				       struct atomic_open_response *resp)
569 {
570 	struct path child_path;
571 	bool truncate = false;
572 	int err = 0;
573 
574 	err = hmdfs_lookup_create(con, recv, &child_path, &truncate);
575 	if (err)
576 		return err;
577 
578 	err = hmdfs_dentry_open(con, &child_path, info);
579 	if (err)
580 		goto put_child;
581 
582 	err = hmdfs_get_open_info(con, HM_REG, NULL, info);
583 	if (err)
584 		goto fail_close;
585 
586 	if (truncate) {
587 		err = vfs_truncate(&child_path, 0);
588 		if (err) {
589 			hmdfs_err("truncate failed, err %d", err);
590 			goto fail_close;
591 		}
592 	}
593 	hmdfs_update_open_response(con, cmd, info, &resp->open_resp);
594 	resp->i_mode = cpu_to_le16(file_inode(info->file)->i_mode);
595 
596 fail_close:
597 	if (err) {
598 		remove_file_from_conn(con, info->file_id);
599 		hmdfs_close_path(info->file);
600 	}
601 put_child:
602 	path_put(&child_path);
603 	return err;
604 }
605 
hmdfs_server_atomic_open(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)606 void hmdfs_server_atomic_open(struct hmdfs_peer *con,
607 			      struct hmdfs_head_cmd *cmd, void *data)
608 {
609 	int err;
610 	struct atomic_open_request *recv = data;
611 	struct atomic_open_response *resp = NULL;
612 	struct hmdfs_open_info *info = NULL;
613 
614 	info = kmalloc(sizeof(*info), GFP_KERNEL);
615 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
616 	if (!resp || !info) {
617 		err = -ENOMEM;
618 		goto out;
619 	}
620 
621 	err = hmdfs_server_do_atomic_open(con, cmd, recv, info, resp);
622 
623 out:
624 	if (err) {
625 		hmdfs_send_err_response(con, cmd, err);
626 	} else {
627 		err = hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp,
628 						 0);
629 		if (err) {
630 			hmdfs_err("sending msg response failed, file_id %d, err %d",
631 				  info->file_id, err);
632 			remove_file_from_conn(con, info->file_id);
633 			hmdfs_close_path(info->file);
634 		}
635 	}
636 	kfree(info);
637 	kfree(resp);
638 }
639 
hmdfs_server_release(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)640 void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
641 			  void *data)
642 {
643 	struct release_request *release_recv = data;
644 	struct file *file = NULL;
645 	__u32 file_id;
646 	__u64 file_ver;
647 	int ret = 0;
648 
649 	file_id = le32_to_cpu(release_recv->file_id);
650 	file_ver = le64_to_cpu(release_recv->file_ver);
651 	file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver);
652 	if (IS_ERR(file)) {
653 		hmdfs_err("cannot find %u", file_id);
654 		ret = PTR_ERR(file);
655 		goto out;
656 	}
657 
658 	if (hmdfs_is_share_file(file))
659 		hmdfs_close_share_item(con->sbi, file, con->cid);
660 
661 	/* put the reference acquired by get_file_by_fid_and_ver() */
662 	hmdfs_close_path(file);
663 	hmdfs_info("close %u", file_id);
664 	remove_file_from_conn(con, file_id);
665 
666 	hmdfs_close_path(file);
667 
668 out:
669 	trace_hmdfs_server_release(con, file_id, file_ver, ret);
670 	set_conn_sock_quickack(con);
671 }
672 
hmdfs_server_fsync(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)673 void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
674 			void *data)
675 {
676 	struct fsync_request *fsync_recv = data;
677 	__s32 datasync = le32_to_cpu(fsync_recv->datasync);
678 	__s64 start = le64_to_cpu(fsync_recv->start);
679 	__s64 end = le64_to_cpu(fsync_recv->end);
680 	struct file *file = NULL;
681 	__u32 file_id;
682 	__u64 file_ver;
683 	int ret = 0;
684 
685 	file_id = le32_to_cpu(fsync_recv->file_id);
686 	file_ver = le64_to_cpu(fsync_recv->file_ver);
687 	file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver);
688 	if (IS_ERR(file)) {
689 		hmdfs_err("cannot find %u", file_id);
690 		ret = PTR_ERR(file);
691 		goto out;
692 	}
693 
694 	ret = vfs_fsync_range(file, start, end, datasync);
695 	if (ret)
696 		hmdfs_err("fsync fail, ret %d", ret);
697 
698 	hmdfs_close_path(file);
699 out:
700 	hmdfs_send_err_response(con, cmd, ret);
701 }
702 
hmdfs_server_readpage(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)703 void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
704 			   void *data)
705 {
706 	struct readpage_request *readpage_recv = data;
707 	__u64 file_ver;
708 	__u32 file_id;
709 	struct file *file = NULL;
710 	loff_t pos;
711 	struct readpage_response *readpage = NULL;
712 	int ret = 0;
713 	size_t read_len;
714 
715 	file_id = le32_to_cpu(readpage_recv->file_id);
716 	file_ver = le64_to_cpu(readpage_recv->file_ver);
717 	file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver);
718 	if (IS_ERR(file)) {
719 		hmdfs_info(
720 			"file with id %u does not exist, pgindex %llu, devid %llu",
721 			file_id, le64_to_cpu(readpage_recv->index),
722 			con->device_id);
723 		ret = PTR_ERR(file);
724 		goto fail;
725 	}
726 
727 	read_len = (size_t)le32_to_cpu(readpage_recv->size);
728 	if (read_len == 0)
729 		goto fail_put_file;
730 
731 	readpage = kmalloc(read_len, GFP_KERNEL);
732 	if (!readpage) {
733 		ret = -ENOMEM;
734 		goto fail_put_file;
735 	}
736 
737 	pos = (loff_t)le64_to_cpu(readpage_recv->index) << HMDFS_PAGE_OFFSET;
738 	ret = kernel_read(file, readpage->buf, read_len, &pos);
739 	if (ret < 0) {
740 		hmdfs_send_err_response(con, cmd, -EIO);
741 	} else {
742 		if (ret != read_len)
743 			memset(readpage->buf + ret, 0, read_len - ret);
744 		hmdfs_sendmessage_response(con, cmd, read_len, readpage, 0);
745 	}
746 
747 	hmdfs_close_path(file);
748 	kfree(readpage);
749 	return;
750 
751 fail_put_file:
752 	hmdfs_close_path(file);
753 fail:
754 	hmdfs_send_err_response(con, cmd, ret);
755 }
756 
alloc_readpages_resp(unsigned int len)757 static struct readpages_response *alloc_readpages_resp(unsigned int len)
758 {
759 	struct readpages_response *resp = NULL;
760 
761 	if (len > HMDFS_PAGE_SIZE)
762 		resp = vmalloc(len);
763 	else
764 		resp = kmalloc(len, GFP_KERNEL);
765 
766 	return resp;
767 }
768 
free_readpages_resp(struct readpages_response * resp,unsigned int len)769 static void free_readpages_resp(struct readpages_response *resp,
770 				unsigned int len)
771 {
772 	if (len > HMDFS_PAGE_SIZE)
773 		vfree(resp);
774 	else
775 		kfree(resp);
776 }
777 
hmdfs_server_readpages(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)778 void hmdfs_server_readpages(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
779 			    void *data)
780 {
781 	struct readpages_request *req = data;
782 	__u64 file_ver;
783 	__u32 file_id;
784 	struct file *file = NULL;
785 	loff_t pos;
786 	struct readpages_response *resp = NULL;
787 	ssize_t ret = 0;
788 	size_t read_len;
789 
790 	file_id = le32_to_cpu(req->file_id);
791 	file_ver = le64_to_cpu(req->file_ver);
792 	file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver);
793 	if (IS_ERR(file)) {
794 		ret = PTR_ERR(file);
795 		goto fail;
796 	}
797 
798 	read_len = (size_t)le32_to_cpu(req->size);
799 	if (read_len == 0)
800 		goto fail_put_file;
801 
802 	resp = alloc_readpages_resp(read_len);
803 	if (!resp) {
804 		ret = -ENOMEM;
805 		goto fail_put_file;
806 	}
807 
808 	pos = (loff_t)le64_to_cpu(req->index) << HMDFS_PAGE_OFFSET;
809 	ret = kernel_read(file, resp->buf, read_len, &pos);
810 	if (ret < 0) {
811 		ret = -EIO;
812 		goto fail_free_resp;
813 	}
814 
815 	hmdfs_sendmessage_response(con, cmd, ret, resp, 0);
816 	hmdfs_close_path(file);
817 	free_readpages_resp(resp, read_len);
818 	return;
819 
820 fail_free_resp:
821 	free_readpages_resp(resp, read_len);
822 fail_put_file:
823 	hmdfs_close_path(file);
824 fail:
825 	hmdfs_send_err_response(con, cmd, ret);
826 }
827 
hmdfs_do_readpages_open(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,struct readpages_open_request * recv,struct hmdfs_open_info * info,struct readpages_open_response * resp)828 static int hmdfs_do_readpages_open(struct hmdfs_peer *con,
829 				   struct hmdfs_head_cmd *cmd,
830 				   struct readpages_open_request *recv,
831 				   struct hmdfs_open_info *info,
832 				   struct readpages_open_response *resp)
833 {
834 	int ret = 0;
835 	loff_t pos = 0;
836 
837 	info->file = hmdfs_open_file(con, recv->buf, recv->file_type,
838 				     &info->file_id);
839 	if (IS_ERR(info->file))
840 		return PTR_ERR(info->file);
841 
842 	ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info);
843 	if (ret)
844 		goto fail_close;
845 
846 	pos = (loff_t)le64_to_cpu(recv->index) << HMDFS_PAGE_OFFSET;
847 	ret = kernel_read(info->file, resp->buf, le32_to_cpu(recv->size), &pos);
848 	if (ret < 0)
849 		goto fail_close;
850 
851 	hmdfs_update_open_response(con, cmd, info, &resp->open_resp);
852 	memset(resp->reserved, 0, sizeof(resp->reserved));
853 	ret = hmdfs_sendmessage_response(con, cmd, sizeof(*resp) + ret, resp,
854 					 0);
855 	if (ret) {
856 		hmdfs_err("sending msg response failed, file_id %d, err %d",
857 			  info->file_id, ret);
858 		ret = 0;
859 		goto fail_close;
860 	}
861 	return 0;
862 
863 fail_close:
864 	remove_file_from_conn(con, info->file_id);
865 	hmdfs_close_path(info->file);
866 	return ret;
867 }
868 
hmdfs_server_readpages_open(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)869 void hmdfs_server_readpages_open(struct hmdfs_peer *con,
870 				 struct hmdfs_head_cmd *cmd, void *data)
871 {
872 	struct readpages_open_request *recv = data;
873 	struct readpages_open_response *resp = NULL;
874 	int ret = -EINVAL;
875 	size_t read_len = 0;
876 	size_t resp_len = 0;
877 	struct hmdfs_open_info *info = NULL;
878 
879 	info = kmalloc(sizeof(*info), GFP_KERNEL);
880 	if (!info) {
881 		ret = -ENOMEM;
882 		goto fail;
883 	}
884 
885 	read_len = (size_t)le32_to_cpu(recv->size);
886 	if (read_len == 0) {
887 		ret = -EINVAL;
888 		goto fail_free_info;
889 	}
890 	resp_len = read_len + sizeof(*resp);
891 	resp = vmalloc(resp_len);
892 	if (!resp) {
893 		ret = -ENOMEM;
894 		goto fail_free_info;
895 	}
896 
897 	ret = hmdfs_do_readpages_open(con, cmd, recv, info, resp);
898 
899 	vfree(resp);
900 fail_free_info:
901 	kfree(info);
902 fail:
903 	if (ret)
904 		hmdfs_send_err_response(con, cmd, ret);
905 }
906 
need_rebuild_dcache(struct hmdfs_dcache_header * h,struct hmdfs_time_t time,unsigned int precision)907 static bool need_rebuild_dcache(struct hmdfs_dcache_header *h,
908 				struct hmdfs_time_t time,
909 				unsigned int precision)
910 {
911 	struct hmdfs_time_t crtime = { .tv_sec = le64_to_cpu(h->dcache_crtime),
912 				       .tv_nsec = le64_to_cpu(
913 					       h->dcache_crtime_nsec) };
914 	struct hmdfs_time_t ctime = { .tv_sec = le64_to_cpu(h->dentry_ctime),
915 				      .tv_nsec = le64_to_cpu(
916 					      h->dentry_ctime_nsec) };
917 	struct hmdfs_time_t pre_time = { .tv_sec = precision / MSEC_PER_SEC,
918 					 .tv_nsec = precision % MSEC_PER_SEC *
919 						    NSEC_PER_MSEC };
920 
921 	if (hmdfs_time_compare(&time, &ctime) != 0)
922 		return true;
923 
924 	pre_time = hmdfs_time_add(time, pre_time);
925 	if (hmdfs_time_compare(&crtime, &pre_time) < 0)
926 		return true;
927 
928 	return false;
929 }
930 
hmdfs_server_cache_validate(struct file * filp,struct inode * inode,unsigned long precision)931 static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode,
932 					unsigned long precision)
933 {
934 	struct hmdfs_dcache_header header;
935 	int overallpage;
936 	ssize_t bytes;
937 	loff_t pos = 0;
938 
939 	overallpage = get_dentry_group_cnt(file_inode(filp));
940 	if (overallpage == 0) {
941 		hmdfs_err("cache file size is 0");
942 		return false;
943 	}
944 
945 	bytes = kernel_read(filp, &header, sizeof(header), &pos);
946 	if (bytes != sizeof(header)) {
947 		hmdfs_err("read file failed, err:%zd", bytes);
948 		return false;
949 	}
950 
951 	return !need_rebuild_dcache(&header, inode->i_ctime, precision);
952 }
953 
hmdfs_server_cache_revalidate(struct hmdfs_sb_info * sbi,const char * recvpath,struct path * path)954 struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi,
955 					   const char *recvpath,
956 					   struct path *path)
957 {
958 	struct cache_file_node *cfn = NULL;
959 	struct file *file;
960 
961 	cfn = find_cfn(sbi, HMDFS_SERVER_CID, recvpath, true);
962 	if (!cfn)
963 		return NULL;
964 
965 	if (!hmdfs_server_cache_validate(cfn->filp, path->dentry->d_inode,
966 					 sbi->dcache_precision)) {
967 		remove_cfn(cfn);
968 		release_cfn(cfn);
969 		return NULL;
970 	}
971 	file = cfn->filp;
972 	get_file(cfn->filp);
973 	release_cfn(cfn);
974 
975 	return file;
976 }
977 
hmdfs_client_cache_validate(struct hmdfs_sb_info * sbi,struct readdir_request * readdir_recv,struct path * path)978 bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi,
979 				 struct readdir_request *readdir_recv,
980 				 struct path *path)
981 {
982 	struct inode *inode = path->dentry->d_inode;
983 	struct hmdfs_dcache_header header;
984 
985 	/* always rebuild dentryfile for small dir */
986 	if (le64_to_cpu(readdir_recv->num) < sbi->dcache_threshold)
987 		return false;
988 
989 	header.dcache_crtime = readdir_recv->dcache_crtime;
990 	header.dcache_crtime_nsec = readdir_recv->dcache_crtime_nsec;
991 	header.dentry_ctime = readdir_recv->dentry_ctime;
992 	header.dentry_ctime_nsec = readdir_recv->dentry_ctime_nsec;
993 
994 	return !need_rebuild_dcache(&header, inode->i_ctime,
995 				    sbi->dcache_precision);
996 }
997 
server_lower_dentry_path_raw(struct hmdfs_peer * peer,struct dentry * lo_d)998 static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer,
999 					  struct dentry *lo_d)
1000 {
1001 	struct hmdfs_dentry_info *di = hmdfs_d(peer->sbi->sb->s_root);
1002 	struct dentry *lo_d_root = di->lower_path.dentry;
1003 	struct dentry *lo_d_tmp = NULL;
1004 	char *lo_p_buf = NULL;
1005 	char *buf_head = NULL;
1006 	char *buf_tail = NULL;
1007 	size_t path_len = 0;
1008 
1009 	lo_p_buf = kzalloc(PATH_MAX, GFP_KERNEL);
1010 	if (unlikely(!lo_p_buf))
1011 		return ERR_PTR(-ENOMEM);
1012 
1013 	/* To generate a reversed path str */
1014 	for (lo_d_tmp = lo_d; lo_d_tmp != lo_d_root && !IS_ROOT(lo_d_tmp);
1015 	     lo_d_tmp = lo_d_tmp->d_parent) {
1016 		u32 dlen = lo_d_tmp->d_name.len;
1017 		int reverse_index = dlen - 1;
1018 
1019 		/* Considering the appended slash and '\0' */
1020 		if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) {
1021 			kfree(lo_p_buf);
1022 			return ERR_PTR(-ENAMETOOLONG);
1023 		}
1024 		for (; reverse_index >= 0; --reverse_index)
1025 			lo_p_buf[path_len++] =
1026 				lo_d_tmp->d_name.name[reverse_index];
1027 		lo_p_buf[path_len++] = '/';
1028 	}
1029 
1030 	/* Reverse the reversed path str to get the real path str */
1031 	for (buf_head = lo_p_buf, buf_tail = lo_p_buf + path_len - 1;
1032 	     buf_head < buf_tail; ++buf_head, --buf_tail)
1033 		swap(*buf_head, *buf_tail);
1034 
1035 	if (path_len == 0)
1036 		lo_p_buf[0] = '/';
1037 	return lo_p_buf;
1038 }
1039 
server_lookup(struct hmdfs_peer * peer,const char * req_path,struct path * path)1040 static int server_lookup(struct hmdfs_peer *peer, const char *req_path,
1041 			 struct path *path)
1042 {
1043 	struct path root_path;
1044 	int err = 0;
1045 
1046 	err = kern_path(peer->sbi->local_dst, 0, &root_path);
1047 	if (err)
1048 		goto out_noroot;
1049 
1050 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, req_path,
1051 			      LOOKUP_DIRECTORY, path);
1052 	path_put(&root_path);
1053 out_noroot:
1054 	return err;
1055 }
1056 
1057 /**
1058  * server_lookup_lower - lookup lower file-system
1059  * @peer: target device node
1060  * @req_path: abs path (mount point as the root) from the request
1061  * @lo_o: the lower path to return
1062  *
1063  * return the lower path's name, with characters' cases matched
1064  */
server_lookup_lower(struct hmdfs_peer * peer,const char * req_path,struct path * lo_p)1065 static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path,
1066 				 struct path *lo_p)
1067 {
1068 	char *lo_p_name = ERR_PTR(-ENOENT);
1069 	struct path up_p;
1070 	int err = 0;
1071 
1072 	err = server_lookup(peer, req_path, &up_p);
1073 	if (err)
1074 		goto out;
1075 
1076 	hmdfs_get_lower_path(up_p.dentry, lo_p);
1077 	path_put(&up_p);
1078 
1079 	lo_p_name = server_lower_dentry_path_raw(peer, lo_p->dentry);
1080 	if (IS_ERR(lo_p_name)) {
1081 		err = PTR_ERR(lo_p_name);
1082 		path_put(lo_p);
1083 	}
1084 out:
1085 	return err ? ERR_PTR(err) : lo_p_name;
1086 }
1087 
hmdfs_server_readdir(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1088 void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1089 			  void *data)
1090 {
1091 	struct readdir_request *readdir_recv = data;
1092 	struct path lo_p;
1093 	struct file *filp = NULL;
1094 	int err = 0;
1095 	unsigned long long num = 0;
1096 	char *lo_p_name = NULL;
1097 
1098 	trace_hmdfs_server_readdir(readdir_recv);
1099 
1100 	lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p);
1101 	if (IS_ERR(lo_p_name)) {
1102 		err = PTR_ERR(lo_p_name);
1103 		hmdfs_info("Failed to get lower path: %d", err);
1104 		goto send_err;
1105 	}
1106 
1107 	if (le32_to_cpu(readdir_recv->verify_cache)) {
1108 		if (hmdfs_client_cache_validate(con->sbi, readdir_recv, &lo_p))
1109 			goto out_response;
1110 	}
1111 
1112 	filp = hmdfs_server_cache_revalidate(con->sbi, lo_p_name, &lo_p);
1113 	if (IS_ERR_OR_NULL(filp)) {
1114 		filp = hmdfs_server_rebuild_dents(con->sbi, &lo_p, &num,
1115 						  lo_p_name);
1116 		if (IS_ERR_OR_NULL(filp)) {
1117 			err = PTR_ERR(filp);
1118 			goto err_lookup_path;
1119 		}
1120 	}
1121 
1122 out_response:
1123 	err = hmdfs_readfile_response(con, cmd, filp);
1124 	if (!err)
1125 		hmdfs_add_remote_cache_list(con, lo_p_name);
1126 	if (num >= con->sbi->dcache_threshold)
1127 		cache_file_persistent(con, filp, lo_p_name, true);
1128 	if (filp)
1129 		fput(filp);
1130 err_lookup_path:
1131 	path_put(&lo_p);
1132 	kfree(lo_p_name);
1133 send_err:
1134 	if (err)
1135 		hmdfs_send_err_response(con, cmd, err);
1136 }
1137 
hmdfs_server_mkdir(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1138 void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1139 			void *data)
1140 {
1141 	int err = 0;
1142 	struct mkdir_request *mkdir_recv = data;
1143 	struct inode *child_inode = NULL;
1144 	struct dentry *dent = NULL;
1145 	char *mkdir_dir = NULL;
1146 	char *mkdir_name = NULL;
1147 	struct hmdfs_inodeinfo_response *mkdir_resp = NULL;
1148 	int respsize = sizeof(struct hmdfs_inodeinfo_response);
1149 	int path_len = le32_to_cpu(mkdir_recv->path_len);
1150 
1151 	mkdir_resp = kzalloc(respsize, GFP_KERNEL);
1152 	if (!mkdir_resp) {
1153 		err = -ENOMEM;
1154 		goto mkdir_out;
1155 	}
1156 
1157 	mkdir_dir = mkdir_recv->path;
1158 	mkdir_name = mkdir_recv->path + path_len + 1;
1159 
1160 	dent = hmdfs_root_mkdir(con->device_id, con->sbi->local_dst,
1161 				mkdir_dir, mkdir_name,
1162 				le16_to_cpu(mkdir_recv->mode));
1163 	if (IS_ERR(dent)) {
1164 		err = PTR_ERR(dent);
1165 		hmdfs_err("hmdfs_root_mkdir failed err = %d", err);
1166 		goto mkdir_out;
1167 	}
1168 	child_inode = d_inode(dent);
1169 	mkdir_resp->i_mode = cpu_to_le16(child_inode->i_mode);
1170 	mkdir_resp->i_size = cpu_to_le64(child_inode->i_size);
1171 	mkdir_resp->i_mtime = cpu_to_le64(child_inode->i_mtime.tv_sec);
1172 	mkdir_resp->i_mtime_nsec = cpu_to_le32(child_inode->i_mtime.tv_nsec);
1173 	mkdir_resp->i_ino = cpu_to_le64(child_inode->i_ino);
1174 	dput(dent);
1175 mkdir_out:
1176 	hmdfs_sendmessage_response(con, cmd, respsize, mkdir_resp, err);
1177 	kfree(mkdir_resp);
1178 }
1179 
hmdfs_server_create(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1180 void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1181 			 void *data)
1182 {
1183 	int err = 0;
1184 	struct create_request *create_recv = data;
1185 	struct inode *child_inode = NULL;
1186 	struct dentry *dent = NULL;
1187 	char *create_dir = NULL;
1188 	char *create_name = NULL;
1189 	struct hmdfs_inodeinfo_response *create_resp = NULL;
1190 	int respsize = sizeof(struct hmdfs_inodeinfo_response);
1191 	int path_len = le32_to_cpu(create_recv->path_len);
1192 
1193 	create_resp = kzalloc(respsize, GFP_KERNEL);
1194 	if (!create_resp) {
1195 		err = -ENOMEM;
1196 		goto create_out;
1197 	}
1198 
1199 	create_dir = create_recv->path;
1200 	create_name = create_recv->path + path_len + 1;
1201 
1202 	dent = hmdfs_root_create(con->device_id, con->sbi->local_dst,
1203 				 create_dir, create_name,
1204 				 le16_to_cpu(create_recv->mode),
1205 				 create_recv->want_excl);
1206 	if (IS_ERR(dent)) {
1207 		err = PTR_ERR(dent);
1208 		hmdfs_err("hmdfs_root_create failed err = %d", err);
1209 		goto create_out;
1210 	}
1211 	child_inode = d_inode(dent);
1212 	create_resp->i_mode = cpu_to_le16(child_inode->i_mode);
1213 	create_resp->i_size = cpu_to_le64(child_inode->i_size);
1214 	create_resp->i_mtime = cpu_to_le64(child_inode->i_mtime.tv_sec);
1215 	create_resp->i_mtime_nsec = cpu_to_le32(child_inode->i_mtime.tv_nsec);
1216 	/*
1217 	 * keep same as hmdfs_server_open,
1218 	 * to prevent hmdfs_open_final_remote from judging ino errors.
1219 	 */
1220 	create_resp->i_ino = cpu_to_le64(
1221 		generate_u64_ino(hmdfs_i(child_inode)->lower_inode->i_ino,
1222 				 child_inode->i_generation));
1223 	dput(dent);
1224 create_out:
1225 	hmdfs_sendmessage_response(con, cmd, respsize, create_resp, err);
1226 	kfree(create_resp);
1227 }
1228 
hmdfs_server_rmdir(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1229 void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1230 			void *data)
1231 {
1232 	int err = 0;
1233 	struct path root_path;
1234 	char *path = NULL;
1235 	char *name = NULL;
1236 	struct rmdir_request *rmdir_recv = data;
1237 
1238 	path = rmdir_recv->path;
1239 	name = rmdir_recv->path + le32_to_cpu(rmdir_recv->path_len) + 1;
1240 	err = kern_path(con->sbi->local_dst, 0, &root_path);
1241 	if (!err) {
1242 		err = hmdfs_root_rmdir(con->device_id, &root_path, path, name);
1243 		path_put(&root_path);
1244 	}
1245 
1246 	hmdfs_send_err_response(con, cmd, err);
1247 }
1248 
hmdfs_server_unlink(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1249 void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1250 			 void *data)
1251 {
1252 	int err = 0;
1253 	struct path root_path;
1254 	char *path = NULL;
1255 	char *name = NULL;
1256 	struct unlink_request *unlink_recv = data;
1257 
1258 	path = unlink_recv->path;
1259 	name = unlink_recv->path + le32_to_cpu(unlink_recv->path_len) + 1;
1260 	err = kern_path(con->sbi->local_dst, 0, &root_path);
1261 	if (!err) {
1262 		err = hmdfs_root_unlink(con->device_id, &root_path, path, name);
1263 		path_put(&root_path);
1264 	}
1265 
1266 	hmdfs_send_err_response(con, cmd, err);
1267 }
1268 
hmdfs_server_rename(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1269 void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1270 			 void *data)
1271 {
1272 	int err = 0;
1273 	int old_path_len;
1274 	int new_path_len;
1275 	int old_name_len;
1276 	int new_name_len;
1277 	unsigned int flags;
1278 	char *path_old = NULL;
1279 	char *name_old = NULL;
1280 	char *path_new = NULL;
1281 	char *name_new = NULL;
1282 	struct rename_request *recv = data;
1283 
1284 	old_path_len = le32_to_cpu(recv->old_path_len);
1285 	new_path_len = le32_to_cpu(recv->new_path_len);
1286 	old_name_len = le32_to_cpu(recv->old_name_len);
1287 	new_name_len = le32_to_cpu(recv->new_name_len);
1288 	flags = le32_to_cpu(recv->flags);
1289 
1290 	path_old = recv->path;
1291 	path_new = recv->path + old_path_len + 1;
1292 	name_old = recv->path + old_path_len + 1 + new_path_len + 1;
1293 	name_new = recv->path + old_path_len + 1 + new_path_len + 1 +
1294 		   old_name_len + 1;
1295 
1296 	err = hmdfs_root_rename(con->sbi, con->device_id, path_old, name_old,
1297 				path_new, name_new, flags);
1298 
1299 	hmdfs_send_err_response(con, cmd, err);
1300 }
1301 
hmdfs_filldir_real(struct dir_context * ctx,const char * name,int name_len,loff_t offset,u64 ino,unsigned int d_type)1302 static int hmdfs_filldir_real(struct dir_context *ctx, const char *name,
1303 			      int name_len, loff_t offset, u64 ino,
1304 			      unsigned int d_type)
1305 {
1306 	int res = 0;
1307 	char namestr[NAME_MAX + 1];
1308 	struct getdents_callback_real *gc = NULL;
1309 	struct dentry *child = NULL;
1310 
1311 	if (name_len > NAME_MAX) {
1312 		hmdfs_err("name_len:%d NAME_MAX:%u", name_len, NAME_MAX);
1313 		goto out;
1314 	}
1315 
1316 	gc = container_of(ctx, struct getdents_callback_real, ctx);
1317 
1318 	memcpy(namestr, name, name_len);
1319 	namestr[name_len] = '\0';
1320 
1321 	if (hmdfs_file_type(namestr) != HMDFS_TYPE_COMMON)
1322 		goto out;
1323 
1324 	/* parent lock already hold by iterate_dir */
1325 	child = lookup_one_len(name, gc->parent_path->dentry, name_len);
1326 	if (IS_ERR(child)) {
1327 		res = PTR_ERR(child);
1328 		hmdfs_err("lookup failed because %d", res);
1329 		goto out;
1330 	}
1331 
1332 	if (d_really_is_negative(child)) {
1333 		dput(child);
1334 		hmdfs_err("lookup failed because negative dentry");
1335 		/* just do not fill this entry and continue for next entry */
1336 		goto out;
1337 	}
1338 
1339 	if (d_type == DT_REG || d_type == DT_DIR) {
1340 		create_dentry(child, d_inode(child), gc->file, gc->sbi);
1341 		gc->num++;
1342 	}
1343 
1344 	dput(child);
1345 
1346 out:
1347 	/*
1348 	 * we always return 0 here, so that the caller can continue to next
1349 	 * dentry even if failed on this dentry somehow.
1350 	 */
1351 	return 0;
1352 }
1353 
hmdfs_server_set_header(struct hmdfs_dcache_header * header,struct file * file,struct file * dentry_file)1354 static void hmdfs_server_set_header(struct hmdfs_dcache_header *header,
1355 				    struct file *file, struct file *dentry_file)
1356 {
1357 	struct inode *inode = NULL;
1358 	struct hmdfs_time_t cur_time;
1359 
1360 	inode = file_inode(file);
1361 	cur_time = current_time(file_inode(dentry_file));
1362 	header->dcache_crtime = cpu_to_le64(cur_time.tv_sec);
1363 	header->dcache_crtime_nsec = cpu_to_le64(cur_time.tv_nsec);
1364 	header->dentry_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
1365 	header->dentry_ctime_nsec = cpu_to_le64(inode->i_ctime.tv_nsec);
1366 }
1367 
1368 // Get the dentries of target directory
hmdfs_server_rebuild_dents(struct hmdfs_sb_info * sbi,struct path * path,loff_t * num,const char * dir)1369 struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi,
1370 					struct path *path, loff_t *num,
1371 					const char *dir)
1372 {
1373 	int err = 0;
1374 	struct getdents_callback_real gc = {
1375 		.ctx.actor = hmdfs_filldir_real,
1376 		.ctx.pos = 0,
1377 		.num = 0,
1378 		.sbi = sbi,
1379 		.dir = dir,
1380 	};
1381 	struct file *file = NULL;
1382 	struct file *dentry_file = NULL;
1383 	struct hmdfs_dcache_header header;
1384 
1385 	dentry_file = create_local_dentry_file_cache(sbi);
1386 	if (IS_ERR(dentry_file)) {
1387 		hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file));
1388 		return dentry_file;
1389 	}
1390 
1391 	file = dentry_open(path, O_RDONLY | O_DIRECTORY, current_cred());
1392 	if (IS_ERR(file)) {
1393 		err = PTR_ERR(file);
1394 		hmdfs_err("dentry_open failed");
1395 		goto out;
1396 	}
1397 
1398 	hmdfs_server_set_header(&header, file, dentry_file);
1399 
1400 	gc.parent_path = path;
1401 	gc.file = dentry_file;
1402 
1403 	err = iterate_dir(file, &(gc.ctx));
1404 	if (err) {
1405 		hmdfs_err("iterate_dir failed");
1406 		goto out;
1407 	}
1408 
1409 	header.case_sensitive = sbi->s_case_sensitive;
1410 	header.num = cpu_to_le64(gc.num);
1411 	if (num)
1412 		*num = gc.num;
1413 
1414 	err = write_header(dentry_file, &header);
1415 out:
1416 	if (!IS_ERR_OR_NULL(file))
1417 		fput(file);
1418 
1419 	if (err) {
1420 		fput(dentry_file);
1421 		dentry_file = ERR_PTR(err);
1422 	}
1423 
1424 	trace_hmdfs_server_rebuild_dents(&header, err);
1425 	return dentry_file;
1426 }
1427 
hmdfs_server_writepage(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1428 void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1429 			    void *data)
1430 {
1431 	struct writepage_request *writepage_recv = data;
1432 	struct hmdfs_server_writeback *hswb = NULL;
1433 	__u64 file_ver;
1434 	__u32 file_id;
1435 	struct file *file = NULL;
1436 	loff_t pos;
1437 	__u32 count;
1438 	ssize_t ret;
1439 	int err = 0;
1440 
1441 	file_id = le32_to_cpu(writepage_recv->file_id);
1442 	file_ver = le64_to_cpu(writepage_recv->file_ver);
1443 	file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver);
1444 	if (IS_ERR(file)) {
1445 		hmdfs_info(
1446 			"file with id %u does not exist, pgindex %llu, devid %llu",
1447 			file_id, le64_to_cpu(writepage_recv->index),
1448 			con->device_id);
1449 		err = PTR_ERR(file);
1450 		goto out;
1451 	}
1452 
1453 	pos = (loff_t)le64_to_cpu(writepage_recv->index) << HMDFS_PAGE_OFFSET;
1454 	count = le32_to_cpu(writepage_recv->count);
1455 	ret = kernel_write(file, writepage_recv->buf, count, &pos);
1456 	if (ret != count)
1457 		err = -EIO;
1458 
1459 	hmdfs_close_path(file);
1460 out:
1461 	hmdfs_send_err_response(con, cmd, err);
1462 
1463 	hswb = con->sbi->h_swb;
1464 	if (!err && hswb->dirty_writeback_control)
1465 		hmdfs_server_check_writeback(hswb);
1466 }
1467 
hmdfs_verify_path(struct dentry * dentry,char * recv_buf,struct super_block * sb)1468 static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf,
1469 				       struct super_block *sb)
1470 {
1471 	struct inode *inode = d_inode(dentry);
1472 	struct hmdfs_inode_info *info = NULL;
1473 
1474 	/* if we found path from wrong fs */
1475 	if (inode->i_sb != sb) {
1476 		hmdfs_err("super block do not match");
1477 		return NULL;
1478 	}
1479 
1480 	info = hmdfs_i(inode);
1481 	/* make sure lower inode is not NULL */
1482 	if (info->lower_inode)
1483 		return info->lower_inode;
1484 
1485 	/*
1486 	 * we don't expect lower inode to be NULL in server. However, it's
1487 	 * possible because dentry cache can contain stale data.
1488 	 */
1489 	hmdfs_info("lower inode is NULL, is remote file: %d",
1490 		   info->conn != NULL);
1491 	return NULL;
1492 }
1493 
hmdfs_notify_change(struct vfsmount * mnt,struct dentry * dentry,struct iattr * attr,struct inode ** delegated_inode)1494 static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry,
1495 			       struct iattr *attr,
1496 			       struct inode **delegated_inode)
1497 {
1498 #ifdef CONFIG_SDCARD_FS
1499 	/* sdcard_fs need to call setattr2, notify_change will call setattr */
1500 	return notify_change2(mnt, dentry, attr, delegated_inode);
1501 #else
1502 	return notify_change(dentry, attr, delegated_inode);
1503 #endif
1504 }
1505 
hmdfs_server_setattr(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1506 void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1507 			  void *data)
1508 {
1509 	int err = 0;
1510 	struct dentry *dentry = NULL;
1511 	struct inode *inode = NULL;
1512 	struct setattr_request *recv = data;
1513 	struct path root_path, dst_path;
1514 	struct iattr attr;
1515 	__u32 valid = le32_to_cpu(recv->valid);
1516 
1517 	err = kern_path(con->sbi->local_dst, 0, &root_path);
1518 	if (err) {
1519 		hmdfs_err("kern_path failed err = %d", err);
1520 		goto out;
1521 	}
1522 
1523 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, 0,
1524 			      &dst_path);
1525 	if (err)
1526 		goto out_put_root;
1527 
1528 	inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb);
1529 	if (!inode) {
1530 		err = -ENOENT;
1531 		goto out_put_dst;
1532 	}
1533 
1534 	if (S_ISLNK(inode->i_mode)) {
1535 		err = -EPERM;
1536 		goto out_put_dst;
1537 	}
1538 
1539 	dentry = dst_path.dentry;
1540 	memset(&attr, 0, sizeof(attr));
1541 	/* only support size and mtime */
1542 	if (valid & (ATTR_SIZE | ATTR_MTIME))
1543 		attr.ia_valid =
1544 			(valid & (ATTR_MTIME | ATTR_MTIME_SET | ATTR_SIZE));
1545 	attr.ia_size = le64_to_cpu(recv->size);
1546 	attr.ia_mtime.tv_sec = le64_to_cpu(recv->mtime);
1547 	attr.ia_mtime.tv_nsec = le32_to_cpu(recv->mtime_nsec);
1548 
1549 	inode_lock(dentry->d_inode);
1550 	err = hmdfs_notify_change(dst_path.mnt, dentry, &attr, NULL);
1551 	inode_unlock(dentry->d_inode);
1552 
1553 out_put_dst:
1554 	path_put(&dst_path);
1555 out_put_root:
1556 	path_put(&root_path);
1557 out:
1558 	hmdfs_send_err_response(con, cmd, err);
1559 }
1560 
update_getattr_response(struct hmdfs_peer * con,struct inode * inode,struct kstat * ks,struct getattr_response * resp)1561 static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode,
1562 				    struct kstat *ks,
1563 				    struct getattr_response *resp)
1564 {
1565 	/* if getattr for link, get ino and mode from actual lower inode */
1566 	resp->ino = cpu_to_le64(
1567 		generate_u64_ino(inode->i_ino, inode->i_generation));
1568 	resp->mode = cpu_to_le16(inode->i_mode);
1569 
1570 	/* get other information from vfs_getattr() */
1571 	resp->result_mask = cpu_to_le32(STATX_BASIC_STATS | STATX_BTIME);
1572 	resp->fsid = cpu_to_le64(ks->dev);
1573 	resp->nlink = cpu_to_le32(ks->nlink);
1574 	resp->uid = cpu_to_le32(ks->uid.val);
1575 	resp->gid = cpu_to_le32(ks->gid.val);
1576 	resp->size = cpu_to_le64(ks->size);
1577 	resp->blocks = cpu_to_le64(ks->blocks);
1578 	resp->blksize = cpu_to_le32(ks->blksize);
1579 	resp->atime = cpu_to_le64(ks->atime.tv_sec);
1580 	resp->atime_nsec = cpu_to_le32(ks->atime.tv_nsec);
1581 	resp->mtime = cpu_to_le64(ks->mtime.tv_sec);
1582 	resp->mtime_nsec = cpu_to_le32(ks->mtime.tv_nsec);
1583 	resp->ctime = cpu_to_le64(ks->ctime.tv_sec);
1584 	resp->ctime_nsec = cpu_to_le32(ks->ctime.tv_nsec);
1585 	resp->crtime = cpu_to_le64(ks->btime.tv_sec);
1586 	resp->crtime_nsec = cpu_to_le32(ks->btime.tv_nsec);
1587 }
1588 
hmdfs_server_getattr(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1589 void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1590 			  void *data)
1591 {
1592 	int err = 0;
1593 	struct getattr_request *recv = data;
1594 	int size_read = sizeof(struct getattr_response);
1595 	struct getattr_response *resp = NULL;
1596 	struct kstat ks;
1597 	struct path root_path, dst_path;
1598 	struct inode *inode = NULL;
1599 	unsigned int recv_flags = le32_to_cpu(recv->lookup_flags);
1600 	unsigned int lookup_flags = 0;
1601 
1602 	err = hmdfs_convert_lookup_flags(recv_flags, &lookup_flags);
1603 	if (err)
1604 		goto err;
1605 
1606 	resp = kzalloc(size_read, GFP_KERNEL);
1607 	if (!resp) {
1608 		err = -ENOMEM;
1609 		goto err;
1610 	}
1611 	err = kern_path(con->sbi->local_dst, 0, &root_path);
1612 	if (err) {
1613 		hmdfs_err("kern_path failed err = %d", err);
1614 		goto err_free_resp;
1615 	}
1616 
1617 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf,
1618 			      lookup_flags, &dst_path);
1619 	if (err)
1620 		goto out_put_root;
1621 
1622 	inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb);
1623 	if (!inode) {
1624 		err = -ENOENT;
1625 		goto out_put_dst;
1626 	}
1627 
1628 	if (S_ISLNK(inode->i_mode)) {
1629 		err = -EPERM;
1630 		goto out_put_dst;
1631 	}
1632 
1633 	err = vfs_getattr(&dst_path, &ks, STATX_BASIC_STATS | STATX_BTIME, 0);
1634 	if (err)
1635 		goto err_put_dst;
1636 	update_getattr_response(con, inode, &ks, resp);
1637 
1638 out_put_dst:
1639 	path_put(&dst_path);
1640 out_put_root:
1641 	/*
1642 	 * if path lookup failed, we return with result_mask setting to
1643 	 * zero. So we can be aware of such situation in caller.
1644 	 */
1645 	if (err)
1646 		resp->result_mask = cpu_to_le32(0);
1647 	path_put(&root_path);
1648 	hmdfs_sendmessage_response(con, cmd, size_read, resp, err);
1649 	kfree(resp);
1650 	return;
1651 
1652 err_put_dst:
1653 	path_put(&dst_path);
1654 	path_put(&root_path);
1655 err_free_resp:
1656 	kfree(resp);
1657 err:
1658 	hmdfs_send_err_response(con, cmd, err);
1659 }
1660 
init_statfs_response(struct statfs_response * resp,struct kstatfs * st)1661 static void init_statfs_response(struct statfs_response *resp,
1662 				 struct kstatfs *st)
1663 {
1664 	resp->f_type = cpu_to_le64(HMDFS_SUPER_MAGIC);
1665 	resp->f_bsize = cpu_to_le64(st->f_bsize);
1666 	resp->f_blocks = cpu_to_le64(st->f_blocks);
1667 	resp->f_bfree = cpu_to_le64(st->f_bfree);
1668 	resp->f_bavail = cpu_to_le64(st->f_bavail);
1669 	resp->f_files = cpu_to_le64(st->f_files);
1670 	resp->f_ffree = cpu_to_le64(st->f_ffree);
1671 	resp->f_fsid_0 = cpu_to_le32(st->f_fsid.val[0]);
1672 	resp->f_fsid_1 = cpu_to_le32(st->f_fsid.val[1]);
1673 	resp->f_namelen = cpu_to_le64(st->f_namelen);
1674 	resp->f_frsize = cpu_to_le64(st->f_frsize);
1675 	resp->f_flags = cpu_to_le64(st->f_flags);
1676 	/* f_spare is not used in f2fs or ext4 */
1677 	resp->f_spare_0 = cpu_to_le64(st->f_spare[0]);
1678 	resp->f_spare_1 = cpu_to_le64(st->f_spare[1]);
1679 	resp->f_spare_2 = cpu_to_le64(st->f_spare[2]);
1680 	resp->f_spare_3 = cpu_to_le64(st->f_spare[3]);
1681 }
1682 
hmdfs_server_statfs(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1683 void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1684 			 void *data)
1685 {
1686 	struct statfs_request *recv = data;
1687 	struct statfs_response *resp = NULL;
1688 	struct path root_path, path;
1689 	struct kstatfs *st = NULL;
1690 	int err = 0;
1691 
1692 	st = kzalloc(sizeof(*st), GFP_KERNEL);
1693 	if (!st) {
1694 		err = -ENOMEM;
1695 		goto out;
1696 	}
1697 
1698 	resp = kmalloc(sizeof(*resp), GFP_KERNEL);
1699 	if (!resp) {
1700 		err = -ENOMEM;
1701 		goto free_st;
1702 	}
1703 
1704 	err = kern_path(con->sbi->local_src, 0, &root_path);
1705 	if (err) {
1706 		hmdfs_info("kern_path failed err = %d", err);
1707 		goto free_st;
1708 	}
1709 
1710 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->path, 0,
1711 			      &path);
1712 	if (err) {
1713 		hmdfs_info("recv->path found failed err = %d", err);
1714 		goto put_root;
1715 	}
1716 
1717 	err = vfs_statfs(&path, st);
1718 	if (err)
1719 		hmdfs_info("statfs local dentry failed, err = %d", err);
1720 	init_statfs_response(resp, st);
1721 	path_put(&path);
1722 
1723 put_root:
1724 	path_put(&root_path);
1725 free_st:
1726 	kfree(st);
1727 out:
1728 	if (err)
1729 		hmdfs_send_err_response(con, cmd, err);
1730 	else
1731 		hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp, 0);
1732 
1733 	kfree(resp);
1734 }
1735 
hmdfs_server_syncfs(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1736 void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd,
1737 			 void *data)
1738 {
1739 	/*
1740 	 * Reserved interface. There is a difference compared with traditional
1741 	 * syncfs process. Remote syncfs process in client:
1742 	 * 1. Remote writepages by async call
1743 	 * 2. Remote syncfs calling
1744 	 * 3. Wait all remote async calls(writepages) return in step 1
1745 	 */
1746 	int ret = 0;
1747 
1748 	hmdfs_send_err_response(con, cmd, ret);
1749 }
1750 
hmdfs_server_getxattr(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1751 void hmdfs_server_getxattr(struct hmdfs_peer *con,
1752 			   struct hmdfs_head_cmd *cmd, void *data)
1753 {
1754 	struct getxattr_request *recv = data;
1755 	size_t size = le32_to_cpu(recv->size);
1756 	size_t size_read = sizeof(struct getxattr_response) + size;
1757 	struct getxattr_response *resp = NULL;
1758 	struct path root_path;
1759 	struct path path;
1760 	char *file_path = recv->buf;
1761 	char *name = recv->buf + recv->path_len + 1;
1762 	int err = -ENOMEM;
1763 
1764 	resp = kzalloc(size_read, GFP_KERNEL);
1765 	if (!resp)
1766 		goto err;
1767 
1768 	err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path);
1769 	if (err) {
1770 		hmdfs_info("kern_path failed err = %d", err);
1771 		goto err_free_resp;
1772 	}
1773 
1774 	err = vfs_path_lookup(root_path.dentry, root_path.mnt,
1775 			      file_path, 0, &path);
1776 	if (err) {
1777 		hmdfs_info("path found failed err = %d", err);
1778 		goto err_put_root;
1779 	}
1780 
1781 	if (!size)
1782 		err = vfs_getxattr(path.dentry, name, NULL, size);
1783 	else
1784 		err = vfs_getxattr(path.dentry, name, resp->value, size);
1785 	if (err < 0) {
1786 		hmdfs_info("getxattr failed err %d", err);
1787 		goto err_put_path;
1788 	}
1789 
1790 	resp->size = cpu_to_le32(err);
1791 	hmdfs_sendmessage_response(con, cmd, size_read, resp, 0);
1792 	path_put(&path);
1793 	path_put(&root_path);
1794 	kfree(resp);
1795 	return;
1796 
1797 err_put_path:
1798 	path_put(&path);
1799 err_put_root:
1800 	path_put(&root_path);
1801 err_free_resp:
1802 	kfree(resp);
1803 err:
1804 	hmdfs_send_err_response(con, cmd, err);
1805 }
1806 
hmdfs_server_setxattr(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1807 void hmdfs_server_setxattr(struct hmdfs_peer *con,
1808 			   struct hmdfs_head_cmd *cmd, void *data)
1809 {
1810 	struct setxattr_request *recv = data;
1811 	size_t size = le32_to_cpu(recv->size);
1812 	int flags = le32_to_cpu(recv->flags);
1813 	bool del = recv->del;
1814 	struct path root_path;
1815 	struct path path;
1816 	const char *file_path = NULL;
1817 	const char *name = NULL;
1818 	const void *value = NULL;
1819 	int err;
1820 
1821 	err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path);
1822 	if (err) {
1823 		hmdfs_info("kern_path failed err = %d", err);
1824 		goto err;
1825 	}
1826 
1827 	file_path = recv->buf;
1828 	name = recv->buf + recv->path_len + 1;
1829 	value = name + recv->name_len + 1;
1830 	err = vfs_path_lookup(root_path.dentry, root_path.mnt,
1831 			      file_path, 0, &path);
1832 	if (err) {
1833 		hmdfs_info("path found failed err = %d", err);
1834 		goto err_put_root;
1835 	}
1836 
1837 	if (del) {
1838 		WARN_ON(flags != XATTR_REPLACE);
1839 		err = vfs_removexattr(path.dentry, name);
1840 	} else {
1841 		err = vfs_setxattr(path.dentry, name, value, size, flags);
1842 	}
1843 
1844 	path_put(&path);
1845 err_put_root:
1846 	path_put(&root_path);
1847 err:
1848 	hmdfs_send_err_response(con, cmd, err);
1849 }
1850 
hmdfs_server_listxattr(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1851 void hmdfs_server_listxattr(struct hmdfs_peer *con,
1852 			    struct hmdfs_head_cmd *cmd, void *data)
1853 {
1854 	struct listxattr_request *recv = data;
1855 	size_t size = le32_to_cpu(recv->size);
1856 	int size_read = sizeof(struct listxattr_response) + size;
1857 	struct listxattr_response *resp = NULL;
1858 	const char *file_path = NULL;
1859 	struct path root_path;
1860 	struct path path;
1861 	int err = 0;
1862 
1863 	resp = kzalloc(size_read, GFP_KERNEL);
1864 	if (!resp) {
1865 		err = -ENOMEM;
1866 		goto err;
1867 	}
1868 
1869 	err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path);
1870 	if (err) {
1871 		hmdfs_info("kern_path failed err = %d", err);
1872 		goto err_free_resp;
1873 	}
1874 
1875 	file_path = recv->buf;
1876 	err = vfs_path_lookup(root_path.dentry, root_path.mnt,
1877 			      file_path, 0, &path);
1878 	if (err) {
1879 		hmdfs_info("path found failed err = %d", err);
1880 		goto err_put_root;
1881 	}
1882 
1883 	if (!size)
1884 		err = vfs_listxattr(path.dentry, NULL, size);
1885 	else
1886 		err = vfs_listxattr(path.dentry, resp->list, size);
1887 	if (err < 0) {
1888 		hmdfs_info("listxattr failed err = %d", err);
1889 		goto err_put_path;
1890 	}
1891 
1892 	resp->size = cpu_to_le32(err);
1893 	hmdfs_sendmessage_response(con, cmd, size_read, resp, 0);
1894 	path_put(&root_path);
1895 	path_put(&path);
1896 	kfree(resp);
1897 	return;
1898 
1899 err_put_path:
1900 	path_put(&path);
1901 err_put_root:
1902 	path_put(&root_path);
1903 err_free_resp:
1904 	kfree(resp);
1905 err:
1906 	hmdfs_send_err_response(con, cmd, err);
1907 }
1908 
hmdfs_server_get_drop_push(struct hmdfs_peer * con,struct hmdfs_head_cmd * cmd,void * data)1909 void hmdfs_server_get_drop_push(struct hmdfs_peer *con,
1910 				struct hmdfs_head_cmd *cmd, void *data)
1911 {
1912 	struct drop_push_request *dp_recv = data;
1913 	struct path root_path, path;
1914 	int err;
1915 	char *tmp_path = NULL;
1916 
1917 	err = kern_path(con->sbi->real_dst, 0, &root_path);
1918 	if (err) {
1919 		hmdfs_err("kern_path failed err = %d", err);
1920 		goto quickack;
1921 	}
1922 	tmp_path = kzalloc(PATH_MAX, GFP_KERNEL);
1923 	if (!tmp_path)
1924 		goto out;
1925 	snprintf(tmp_path, PATH_MAX, "/" DEVICE_VIEW_ROOT "/%s%s",
1926 		 con->cid, dp_recv->path);
1927 
1928 	err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0,
1929 			      &path);
1930 	if (err) {
1931 		hmdfs_info("path found failed err = %d", err);
1932 		goto free;
1933 	}
1934 	hmdfs_remove_cache_filp(con, path.dentry);
1935 
1936 	path_put(&path);
1937 free:
1938 	kfree(tmp_path);
1939 out:
1940 	path_put(&root_path);
1941 quickack:
1942 	set_conn_sock_quickack(con);
1943 }
1944