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