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