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