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