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(¤t_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(¤t_time, &ctime) >= 0 &&
482 hmdfs_time_compare(¤t_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