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