1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/hmdfs_dentryfile.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #include "hmdfs_dentryfile.h"
9
10 #include <linux/ctype.h>
11 #include <linux/file.h>
12 #include <linux/mount.h>
13 #include <linux/pagemap.h>
14 #include <linux/slab.h>
15 #include <linux/xattr.h>
16 #include <linux/err.h>
17
18 #include "authority/authentication.h"
19 #include "comm/transport.h"
20 #include "hmdfs_client.h"
21 #include "hmdfs_device_view.h"
22 #include "hmdfs_merge_view.h"
23
24 /* Hashing code copied from f2fs */
25 #define HMDFS_HASH_COL_BIT ((0x1ULL) << 63)
26 #define DELTA 0x9E3779B9
27
is_dot_dotdot(const unsigned char * name,__u32 len)28 static bool is_dot_dotdot(const unsigned char *name, __u32 len)
29 {
30 if (len == 1 && name[0] == '.')
31 return true;
32
33 if (len == 2 && name[0] == '.' && name[1] == '.')
34 return true;
35
36 return false;
37 }
38
str2hashbuf(const unsigned char * msg,size_t len,unsigned int * buf,int num,bool case_sense)39 static void str2hashbuf(const unsigned char *msg, size_t len, unsigned int *buf,
40 int num, bool case_sense)
41 {
42 unsigned int pad, val;
43 int i;
44 unsigned char c;
45
46 pad = (__u32)len | ((__u32)len << 8);
47 pad |= pad << 16;
48
49 val = pad;
50 if (len > (size_t)num * 4)
51 len = (size_t)num * 4;
52 for (i = 0; i < len; i++) {
53 if ((i % 4) == 0)
54 val = pad;
55 c = msg[i];
56 if (!case_sense)
57 c = tolower(c);
58 val = c + (val << 8);
59 if ((i % 4) == 3) {
60 *buf++ = val;
61 val = pad;
62 num--;
63 }
64 }
65 if (--num >= 0)
66 *buf++ = val;
67 while (--num >= 0)
68 *buf++ = pad;
69 }
70
tea_transform(unsigned int buf[4],unsigned int const in[])71 static void tea_transform(unsigned int buf[4], unsigned int const in[])
72 {
73 __u32 sum = 0;
74 __u32 b0 = buf[0], b1 = buf[1];
75 __u32 a = in[0], b = in[1], c = in[2], d = in[3];
76 int n = 16;
77
78 do {
79 sum += DELTA;
80 b0 += ((b1 << 4) + a) ^ (b1 + sum) ^ ((b1 >> 5) + b);
81 b1 += ((b0 << 4) + c) ^ (b0 + sum) ^ ((b0 >> 5) + d);
82 } while (--n);
83
84 buf[0] += b0;
85 buf[1] += b1;
86 }
87
hmdfs_dentry_hash(const struct qstr * qstr,bool case_sense)88 __u32 hmdfs_dentry_hash(const struct qstr *qstr, bool case_sense)
89 {
90 __u32 hash;
91 __u32 hmdfs_hash;
92 const unsigned char *p = qstr->name;
93 __u32 len = qstr->len;
94 __u32 in[8], buf[4];
95
96 if (is_dot_dotdot(p, len))
97 return 0;
98
99 /* Initialize the default seed for the hash checksum functions */
100 buf[0] = 0x67452301;
101 buf[1] = 0xefcdab89;
102 buf[2] = 0x98badcfe;
103 buf[3] = 0x10325476;
104
105 while (1) {
106 str2hashbuf(p, len, in, 4, case_sense);
107 tea_transform(buf, in);
108 p += 16;
109 if (len <= 16)
110 break;
111 len -= 16;
112 }
113 hash = buf[0];
114 hmdfs_hash = hash & ~HMDFS_HASH_COL_BIT;
115 return hmdfs_hash;
116 }
117
118 static atomic_t curr_ino = ATOMIC_INIT(INUNUMBER_START);
get_inonumber(void)119 int get_inonumber(void)
120 {
121 return atomic_inc_return(&curr_ino);
122 }
123
hmdfs_get_root_dentry_type(struct dentry * dentry,int * is_root)124 static int hmdfs_get_root_dentry_type(struct dentry *dentry, int *is_root)
125 {
126 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
127
128 *is_root = 1;
129 switch (d_info->dentry_type) {
130 case HMDFS_LAYER_OTHER_LOCAL:
131 *is_root = 0;
132 fallthrough;
133 case HMDFS_LAYER_SECOND_LOCAL:
134 return HMDFS_LAYER_SECOND_LOCAL;
135 case HMDFS_LAYER_OTHER_CLOUD:
136 *is_root = 0;
137 fallthrough;
138 case HMDFS_LAYER_SECOND_CLOUD:
139 return HMDFS_LAYER_SECOND_CLOUD;
140 case HMDFS_LAYER_OTHER_REMOTE:
141 *is_root = 0;
142 fallthrough;
143 case HMDFS_LAYER_SECOND_REMOTE:
144 return HMDFS_LAYER_SECOND_REMOTE;
145 default:
146 hmdfs_info("Unexpected dentry type %d", d_info->dentry_type);
147 return -EINVAL;
148 }
149 }
150
prepend(char ** buffer,int * buflen,const char * str,int namelen)151 static int prepend(char **buffer, int *buflen, const char *str, int namelen)
152 {
153 *buflen -= namelen;
154 if (*buflen < 0)
155 return -ENAMETOOLONG;
156 *buffer -= namelen;
157 memcpy(*buffer, str, namelen);
158 return 0;
159 }
160
prepend_name(char ** buffer,int * buflen,const struct qstr * name)161 static int prepend_name(char **buffer, int *buflen, const struct qstr *name)
162 {
163 const char *dname = name->name;
164 u32 dlen = name->len;
165 char *p = NULL;
166
167 *buflen -= dlen + 1;
168 if (*buflen < 0)
169 return -ENAMETOOLONG;
170 p = *buffer -= dlen + 1;
171 *p++ = '/';
172 while (dlen--) {
173 char c = *dname++;
174
175 if (!c)
176 break;
177 *p++ = c;
178 }
179 return 0;
180 }
181
hmdfs_dentry_path_raw(struct dentry * d,char * buf,int buflen)182 static char *hmdfs_dentry_path_raw(struct dentry *d, char *buf, int buflen)
183 {
184 struct dentry *dentry = NULL;
185 char *end = NULL;
186 char *retval = NULL;
187 unsigned int len;
188 unsigned int seq = 0;
189 int root_flag = 0;
190 int error = 0;
191 struct hmdfs_dentry_info *di = hmdfs_d(d);
192 int hmdfs_root_dentry_type = 0;
193
194 di->time = jiffies;
195 hmdfs_root_dentry_type = hmdfs_get_root_dentry_type(d, &root_flag);
196 if (hmdfs_root_dentry_type < 0)
197 return NULL;
198 if (root_flag) {
199 strcpy(buf, "/");
200 return buf;
201 }
202 rcu_read_lock();
203 restart:
204 dentry = d;
205 di = hmdfs_d(dentry);
206 di->time = jiffies;
207 end = buf + buflen;
208 len = buflen;
209 prepend(&end, &len, "\0", 1);
210 retval = end - 1;
211 *retval = '/';
212 read_seqbegin_or_lock(&rename_lock, &seq);
213 while (di->dentry_type != hmdfs_root_dentry_type) {
214 struct dentry *parent = dentry->d_parent;
215
216 prefetch(parent);
217 error = prepend_name(&end, &len, &dentry->d_name);
218 if (error)
219 break;
220 retval = end;
221 dentry = parent;
222 di = hmdfs_d(dentry);
223 di->time = jiffies;
224 }
225 if (!(seq & 1))
226 rcu_read_unlock();
227 if (need_seqretry(&rename_lock, seq)) {
228 seq = 1;
229 goto restart;
230 }
231 done_seqretry(&rename_lock, seq);
232 if (error)
233 goto Elong;
234 return retval;
235 Elong:
236 return ERR_PTR(-ENAMETOOLONG);
237 }
238
hmdfs_get_dentry_relative_path(struct dentry * dentry)239 char *hmdfs_get_dentry_relative_path(struct dentry *dentry)
240 {
241 char *final_buf = NULL;
242 char *buf = NULL;
243 char *p = NULL;
244
245 buf = kzalloc(PATH_MAX, GFP_KERNEL);
246 if (!buf)
247 return NULL;
248
249 final_buf = kzalloc(PATH_MAX, GFP_KERNEL);
250 if (!final_buf) {
251 kfree(buf);
252 return NULL;
253 }
254
255 /* NULL dentry return root dir */
256 if (!dentry) {
257 strcpy(final_buf, "/");
258 kfree(buf);
259 return final_buf;
260 }
261 p = hmdfs_dentry_path_raw(dentry, buf, PATH_MAX);
262 if (IS_ERR_OR_NULL(p)) {
263 kfree(buf);
264 kfree(final_buf);
265 return NULL;
266 }
267
268 if (strlen(p) >= PATH_MAX) {
269 kfree(buf);
270 kfree(final_buf);
271 return NULL;
272 }
273 strcpy(final_buf, p);
274 kfree(buf);
275 return final_buf;
276 }
277
hmdfs_merge_dentry_path_raw(struct dentry * d,char * buf,int buflen)278 static char *hmdfs_merge_dentry_path_raw(struct dentry *d, char *buf, int buflen)
279 {
280 struct dentry *dentry = NULL;
281 char *end = NULL;
282 char *retval = NULL;
283 unsigned int len;
284 unsigned int seq = 0;
285 int error = 0;
286 struct hmdfs_dentry_info_merge *mdi = hmdfs_dm(d);
287
288 rcu_read_lock();
289 restart:
290 dentry = d;
291 end = buf + buflen;
292 len = buflen;
293 prepend(&end, &len, "\0", 1);
294 retval = end - 1;
295 *retval = '/';
296 read_seqbegin_or_lock(&rename_lock, &seq);
297 while (mdi->dentry_type != HMDFS_LAYER_FIRST_MERGE &&
298 mdi->dentry_type != HMDFS_LAYER_FIRST_MERGE_CLOUD) {
299 struct dentry *parent = dentry->d_parent;
300
301 prefetch(parent);
302 error = prepend_name(&end, &len, &dentry->d_name);
303 if (error)
304 break;
305 retval = end;
306 dentry = parent;
307 mdi = hmdfs_dm(dentry);
308 }
309 if (!(seq & 1))
310 rcu_read_unlock();
311 if (need_seqretry(&rename_lock, seq)) {
312 seq = 1;
313 goto restart;
314 }
315 done_seqretry(&rename_lock, seq);
316 if (error)
317 goto Elong;
318 return retval;
319 Elong:
320 return ERR_PTR(-ENAMETOOLONG);
321 }
322
hmdfs_merge_get_dentry_relative_path(struct dentry * dentry)323 char *hmdfs_merge_get_dentry_relative_path(struct dentry *dentry)
324 {
325 char *final_buf = NULL;
326 char *buf = NULL;
327 char *p = NULL;
328
329 buf = kzalloc(PATH_MAX, GFP_KERNEL);
330 if (!buf)
331 return NULL;
332
333 final_buf = kzalloc(PATH_MAX, GFP_KERNEL);
334 if (!final_buf) {
335 kfree(buf);
336 return NULL;
337 }
338
339 /* NULL dentry return root dir */
340 if (!dentry) {
341 strcpy(final_buf, "/");
342 kfree(buf);
343 return final_buf;
344 }
345 p = hmdfs_merge_dentry_path_raw(dentry, buf, PATH_MAX);
346 if (IS_ERR_OR_NULL(p)) {
347 kfree(buf);
348 kfree(final_buf);
349 return NULL;
350 }
351
352 if (strlen(p) >= PATH_MAX) {
353 kfree(buf);
354 kfree(final_buf);
355 return NULL;
356 }
357 strcpy(final_buf, p);
358 kfree(buf);
359 return final_buf;
360 }
361
hmdfs_get_dentry_absolute_path(const char * rootdir,const char * relative_path)362 char *hmdfs_get_dentry_absolute_path(const char *rootdir,
363 const char *relative_path)
364 {
365 char *buf = 0;
366
367 if (!rootdir || !relative_path)
368 return NULL;
369 if (strlen(rootdir) + strlen(relative_path) >= PATH_MAX)
370 return NULL;
371
372 buf = kzalloc(PATH_MAX, GFP_KERNEL);
373 if (!buf)
374 return NULL;
375
376 strcpy(buf, rootdir);
377 strcat(buf, relative_path);
378 return buf;
379 }
380
hmdfs_connect_path(const char * path,const char * name)381 char *hmdfs_connect_path(const char *path, const char *name)
382 {
383 char *buf = 0;
384
385 if (!path || !name)
386 return NULL;
387
388 if (strlen(path) + strlen(name) + 1 >= PATH_MAX)
389 return NULL;
390
391 buf = kzalloc(PATH_MAX, GFP_KERNEL);
392 if (!buf)
393 return NULL;
394
395 strcpy(buf, path);
396 strcat(buf, "/");
397 strcat(buf, name);
398 return buf;
399 }
400
hmdfs_metainfo_read(struct hmdfs_sb_info * sbi,struct file * filp,void * buffer,int size,int bidx)401 int hmdfs_metainfo_read(struct hmdfs_sb_info *sbi, struct file *filp,
402 void *buffer, int size, int bidx)
403 {
404 loff_t pos = get_dentry_group_pos(bidx);
405
406 return cache_file_read(sbi, filp, buffer, (size_t)size, &pos);
407 }
408
hmdfs_metainfo_write(struct hmdfs_sb_info * sbi,struct file * filp,const void * buffer,int size,int bidx)409 int hmdfs_metainfo_write(struct hmdfs_sb_info *sbi, struct file *filp,
410 const void *buffer, int size, int bidx)
411 {
412 loff_t pos = get_dentry_group_pos(bidx);
413
414 return cache_file_write(sbi, filp, buffer, (size_t)size, &pos);
415 }
416
417 /* for each level */
418 /* bucketseq start offset by 0,for example
419 * level0 bucket0(0)
420 * level1 bucket0(1) bucket1(2)
421 * level2 bucket0(3) bucket1(4) bucket2(5) bucket3(6)
422 * return bucket number.
423 */
get_bucketaddr(unsigned int level,__u64 buckoffset)424 __u64 get_bucketaddr(unsigned int level, __u64 buckoffset)
425 {
426 __u64 all_level_bucketaddr = 0;
427 __u64 curlevelmaxbucks;
428
429 if (level >= MAX_BUCKET_LEVEL) {
430 hmdfs_err("level = %d overflow", level);
431 return all_level_bucketaddr;
432 }
433 curlevelmaxbucks = ((__u64)1 << level);
434 if (buckoffset >= curlevelmaxbucks) {
435 hmdfs_err("buckoffset %llu overflow, level %d has %llu buckets max",
436 buckoffset, level, curlevelmaxbucks);
437 return all_level_bucketaddr;
438 }
439 all_level_bucketaddr = curlevelmaxbucks + buckoffset - 1;
440
441 return all_level_bucketaddr;
442 }
443
get_bucket_by_level(unsigned int level)444 __u64 get_bucket_by_level(unsigned int level)
445 {
446 __u64 buckets = 0;
447
448 if (level >= MAX_BUCKET_LEVEL) {
449 hmdfs_err("level = %d overflow", level);
450 return buckets;
451 }
452
453 buckets = ((__u64)1 << level);
454 return buckets;
455 }
456
get_overall_bucket(unsigned int level)457 static __u64 get_overall_bucket(unsigned int level)
458 {
459 __u64 buckets = 0;
460
461 if (level >= MAX_BUCKET_LEVEL) {
462 hmdfs_err("level = %d overflow", level);
463 return buckets;
464 }
465 buckets = ((__u64)1 << (level + 1)) - 1;
466 return buckets;
467 }
468
get_dcache_file_size(unsigned int level)469 static inline loff_t get_dcache_file_size(unsigned int level)
470 {
471 loff_t buckets = get_overall_bucket(level);
472
473 return buckets * DENTRYGROUP_SIZE * BUCKET_BLOCKS + DENTRYGROUP_HEADER;
474 }
475
get_relative_path(struct hmdfs_sb_info * sbi,char * from)476 static char *get_relative_path(struct hmdfs_sb_info *sbi, char *from)
477 {
478 char *relative;
479
480 if (strncmp(from, sbi->local_src, strlen(sbi->local_src))) {
481 hmdfs_warning("orig path do not start with local_src");
482 return NULL;
483 }
484 relative = from + strlen(sbi->local_src);
485 if (*relative == '/')
486 relative++;
487 return relative;
488 }
489
hmdfs_get_or_create_dents(struct hmdfs_sb_info * sbi,char * name)490 struct file *hmdfs_get_or_create_dents(struct hmdfs_sb_info *sbi, char *name)
491 {
492 struct path root_path, path;
493 struct file *filp = NULL;
494 char *relative;
495 int err;
496
497 err = kern_path(sbi->local_src, 0, &root_path);
498 if (err) {
499 hmdfs_err("kern_path failed err = %d", err);
500 return NULL;
501 }
502 relative = get_relative_path(sbi, name);
503 if (!relative) {
504 hmdfs_err("get relative path failed");
505 goto err_root_path;
506 }
507 err = vfs_path_lookup(root_path.dentry, root_path.mnt, relative, 0,
508 &path);
509 if (err) {
510 hmdfs_err("lookup failed err = %d", err);
511 goto err_root_path;
512 }
513
514 filp = hmdfs_server_cache_revalidate(sbi, relative, &path);
515 if (IS_ERR_OR_NULL(filp)) {
516 filp = hmdfs_server_rebuild_dents(sbi, &path, NULL, relative);
517 if (IS_ERR_OR_NULL(filp))
518 goto err_lookup_path;
519 }
520
521 err_lookup_path:
522 path_put(&path);
523 err_root_path:
524 path_put(&root_path);
525 return filp;
526 }
527
528 /* read all dentry in target path directory */
read_dentry(struct hmdfs_sb_info * sbi,char * file_name,struct dir_context * ctx)529 int read_dentry(struct hmdfs_sb_info *sbi, char *file_name,
530 struct dir_context *ctx)
531 {
532 unsigned long pos = (unsigned long)(ctx->pos);
533 unsigned long group_id = (pos << (1 + DEV_ID_BIT_NUM)) >>
534 (POS_BIT_NUM - GROUP_ID_BIT_NUM);
535 unsigned long offset = pos & OFFSET_BIT_MASK;
536 struct hmdfs_dentry_group *dentry_group = NULL;
537 struct file *handler = NULL;
538 int group_num = 0;
539 int iterate_result = 0;
540 int i, j;
541 const struct cred *saved_cred;
542
543 saved_cred = hmdfs_override_fsids(false);
544 if (!saved_cred) {
545 hmdfs_err("prepare cred failed!");
546 return -ENOMEM;
547 }
548
549
550 if (!file_name)
551 return -EINVAL;
552
553 dentry_group = kzalloc(sizeof(*dentry_group), GFP_KERNEL);
554 if (!dentry_group)
555 return -ENOMEM;
556
557 handler = hmdfs_get_or_create_dents(sbi, file_name);
558 if (IS_ERR_OR_NULL(handler)) {
559 kfree(dentry_group);
560 return -ENOENT;
561 }
562
563 group_num = get_dentry_group_cnt(file_inode(handler));
564
565 for (i = group_id; i < group_num; i++) {
566 hmdfs_metainfo_read(sbi, handler, dentry_group,
567 sizeof(struct hmdfs_dentry_group), i);
568 for (j = offset; j < DENTRY_PER_GROUP; j++) {
569 int len;
570 int file_type = 0;
571 bool is_continue;
572
573 len = le16_to_cpu(dentry_group->nsl[j].namelen);
574 if (!test_bit_le(j, dentry_group->bitmap) || len == 0)
575 continue;
576
577 if (S_ISDIR(le16_to_cpu(dentry_group->nsl[j].i_mode)))
578 file_type = DT_DIR;
579 else if (S_ISREG(le16_to_cpu(
580 dentry_group->nsl[j].i_mode)))
581 file_type = DT_REG;
582 else if (S_ISLNK(le16_to_cpu(
583 dentry_group->nsl[j].i_mode)))
584 file_type = DT_LNK;
585 else
586 continue;
587
588 pos = hmdfs_set_pos(0, i, j);
589 is_continue = dir_emit(
590 ctx, dentry_group->filename[j], len,
591 le64_to_cpu(dentry_group->nsl[j].i_ino),
592 file_type);
593 if (!is_continue) {
594 ctx->pos = pos;
595 iterate_result = 1;
596 goto done;
597 }
598 }
599 offset = 0;
600 }
601
602 done:
603 hmdfs_revert_fsids(saved_cred);
604 kfree(dentry_group);
605 fput(handler);
606 return iterate_result;
607 }
608
get_max_depth(struct file * filp)609 unsigned int get_max_depth(struct file *filp)
610 {
611 size_t isize;
612
613 isize = get_dentry_group_cnt(file_inode(filp)) / BUCKET_BLOCKS;
614
615 return get_count_order(isize + 1);
616 }
617
find_dentry_page(struct hmdfs_sb_info * sbi,pgoff_t index,struct file * filp)618 struct hmdfs_dentry_group *find_dentry_page(struct hmdfs_sb_info *sbi,
619 pgoff_t index, struct file *filp)
620 {
621 int size;
622 struct hmdfs_dentry_group *dentry_blk = NULL;
623 loff_t pos = get_dentry_group_pos(index);
624 int err;
625
626 dentry_blk = kmalloc(sizeof(*dentry_blk), GFP_KERNEL);
627 if (!dentry_blk)
628 return NULL;
629
630 err = hmdfs_wlock_file(filp, pos, DENTRYGROUP_SIZE);
631 if (err) {
632 hmdfs_err("lock file pos %lld failed", pos);
633 kfree(dentry_blk);
634 return NULL;
635 }
636
637 size = cache_file_read(sbi, filp, dentry_blk, (size_t)DENTRYGROUP_SIZE,
638 &pos);
639 if (size != DENTRYGROUP_SIZE) {
640 kfree(dentry_blk);
641 dentry_blk = NULL;
642 }
643
644 return dentry_blk;
645 }
646
write_dentry_page(struct file * filp,const void * buffer,int buffersize,loff_t position)647 static ssize_t write_dentry_page(struct file *filp, const void *buffer,
648 int buffersize, loff_t position)
649 {
650 ssize_t size;
651
652 size = kernel_write(filp, buffer, (size_t)buffersize, &position);
653 if (size != buffersize)
654 hmdfs_err("write failed, ret = %zd", size);
655
656 return size;
657 }
658
find_in_block(struct hmdfs_dentry_group * dentry_blk,__u32 namehash,const struct qstr * qstr,struct hmdfs_dentry ** insense_de,bool case_sense)659 static struct hmdfs_dentry *find_in_block(struct hmdfs_dentry_group *dentry_blk,
660 __u32 namehash,
661 const struct qstr *qstr,
662 struct hmdfs_dentry **insense_de,
663 bool case_sense)
664 {
665 struct hmdfs_dentry *de;
666 unsigned long bit_pos = 0;
667 int max_len = 0;
668
669 while (bit_pos < DENTRY_PER_GROUP) {
670 if (!test_bit_le(bit_pos, dentry_blk->bitmap)) {
671 bit_pos++;
672 max_len++;
673 }
674 de = &dentry_blk->nsl[bit_pos];
675 if (unlikely(!de->namelen)) {
676 bit_pos++;
677 continue;
678 }
679
680 if (le32_to_cpu(de->hash) == namehash &&
681 le16_to_cpu(de->namelen) == qstr->len &&
682 !memcmp(qstr->name, dentry_blk->filename[bit_pos],
683 le16_to_cpu(de->namelen)))
684 goto found;
685 if (!(*insense_de) && !case_sense &&
686 le32_to_cpu(de->hash) == namehash &&
687 le16_to_cpu(de->namelen) == qstr->len &&
688 str_n_case_eq(qstr->name, dentry_blk->filename[bit_pos],
689 le16_to_cpu(de->namelen)))
690 *insense_de = de;
691 max_len = 0;
692 bit_pos += get_dentry_slots(le16_to_cpu(de->namelen));
693 }
694 de = NULL;
695 found:
696 return de;
697 }
698
hmdfs_in_level(struct dentry * child_dentry,unsigned int level,struct hmdfs_dcache_lookup_ctx * ctx)699 static struct hmdfs_dentry *hmdfs_in_level(struct dentry *child_dentry,
700 unsigned int level,
701 struct hmdfs_dcache_lookup_ctx *ctx)
702 {
703 unsigned long nbucket;
704 unsigned long bidx, end_block;
705 struct hmdfs_dentry *de = NULL;
706 struct hmdfs_dentry *tmp_insense_de = NULL;
707 struct hmdfs_dentry_group *dentry_blk;
708
709 nbucket = get_bucket_by_level(level);
710 if (!nbucket)
711 return de;
712
713 bidx = get_bucketaddr(level, ctx->hash % nbucket) * BUCKET_BLOCKS;
714 end_block = bidx + BUCKET_BLOCKS;
715
716 for (; bidx < end_block; bidx++) {
717 dentry_blk = find_dentry_page(ctx->sbi, bidx, ctx->filp);
718 if (!dentry_blk)
719 break;
720
721 de = find_in_block(dentry_blk, ctx->hash, ctx->name,
722 &tmp_insense_de, ctx->sbi->s_case_sensitive);
723 if (!de && !(ctx->insense_de) && tmp_insense_de) {
724 ctx->insense_de = tmp_insense_de;
725 ctx->insense_page = dentry_blk;
726 ctx->insense_bidx = bidx;
727 } else if (!de) {
728 hmdfs_unlock_file(ctx->filp, get_dentry_group_pos(bidx),
729 DENTRYGROUP_SIZE);
730 kfree(dentry_blk);
731 } else {
732 ctx->page = dentry_blk;
733 break;
734 }
735 }
736 ctx->bidx = bidx;
737 return de;
738 }
739
hmdfs_find_dentry(struct dentry * child_dentry,struct hmdfs_dcache_lookup_ctx * ctx)740 struct hmdfs_dentry *hmdfs_find_dentry(struct dentry *child_dentry,
741 struct hmdfs_dcache_lookup_ctx *ctx)
742 {
743 struct hmdfs_dentry *de = NULL;
744 unsigned int max_depth;
745 unsigned int level;
746
747 if (!ctx->filp)
748 return NULL;
749
750 ctx->hash = hmdfs_dentry_hash(ctx->name, ctx->sbi->s_case_sensitive);
751
752 max_depth = get_max_depth(ctx->filp);
753 for (level = 0; level < max_depth; level++) {
754 de = hmdfs_in_level(child_dentry, level, ctx);
755 if (de) {
756 if (ctx->insense_page) {
757 hmdfs_unlock_file(ctx->filp,
758 get_dentry_group_pos(ctx->insense_bidx),
759 DENTRYGROUP_SIZE);
760 kfree(ctx->insense_page);
761 ctx->insense_page = NULL;
762 }
763 return de;
764 }
765 }
766 if (ctx->insense_de) {
767 ctx->bidx = ctx->insense_bidx;
768 ctx->page = ctx->insense_page;
769 ctx->insense_bidx = 0;
770 ctx->insense_page = NULL;
771 }
772 return ctx->insense_de;
773 }
774
update_dentry(struct hmdfs_dentry_group * d,struct dentry * child_dentry,struct inode * inode,struct super_block * hmdfs_sb,__u32 name_hash,unsigned int bit_pos)775 void update_dentry(struct hmdfs_dentry_group *d, struct dentry *child_dentry,
776 struct inode *inode, struct super_block *hmdfs_sb,
777 __u32 name_hash, unsigned int bit_pos)
778 {
779 struct hmdfs_dentry *de;
780 struct hmdfs_dentry_info *gdi;
781 const struct qstr name = child_dentry->d_name;
782 int slots = get_dentry_slots(name.len);
783 int i;
784 unsigned long ino;
785 __u32 igen;
786
787 gdi = hmdfs_sb == child_dentry->d_sb ? hmdfs_d(child_dentry) : NULL;
788 if (!gdi && S_ISLNK(d_inode(child_dentry)->i_mode)) {
789 ino = d_inode(child_dentry)->i_ino;
790 igen = d_inode(child_dentry)->i_generation;
791 } else {
792 ino = inode->i_ino;
793 igen = inode->i_generation;
794 }
795
796 de = &d->nsl[bit_pos];
797 de->hash = cpu_to_le32(name_hash);
798 de->namelen = cpu_to_le16(name.len);
799 memcpy(d->filename[bit_pos], name.name, name.len);
800 de->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
801 de->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
802 de->i_size = cpu_to_le64(inode->i_size);
803 de->i_ino = cpu_to_le64(generate_u64_ino(ino, igen));
804 de->i_flag = 0;
805 if (gdi && hm_islnk(gdi->file_type))
806 de->i_mode = cpu_to_le16(S_IFLNK);
807 else if (!gdi && S_ISLNK(d_inode(child_dentry)->i_mode))
808 de->i_mode = d_inode(child_dentry)->i_mode;
809 else
810 de->i_mode = cpu_to_le16(inode->i_mode);
811
812 for (i = 0; i < slots; i++) {
813 __set_bit_le(bit_pos + i, d->bitmap);
814 /* avoid wrong garbage data for readdir */
815 if (i)
816 (de + i)->namelen = 0;
817 }
818 }
819
room_for_filename(const void * bitmap,int slots,int max_slots)820 int room_for_filename(const void *bitmap, int slots, int max_slots)
821 {
822 int bit_start = 0;
823 int zero_start, zero_end;
824 next:
825 zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start);
826 if (zero_start >= max_slots)
827 return max_slots;
828
829 zero_end = find_next_bit_le(bitmap, max_slots, zero_start);
830 if (zero_end - zero_start >= slots)
831 return zero_start;
832
833 bit_start = zero_end + 1;
834
835 if (zero_end + 1 >= max_slots)
836 return max_slots;
837 goto next;
838 }
839
create_in_cache_file(uint64_t dev_id,struct dentry * dentry)840 void create_in_cache_file(uint64_t dev_id, struct dentry *dentry)
841 {
842 struct clearcache_item *item = NULL;
843
844 item = hmdfs_find_cache_item(dev_id, dentry->d_parent);
845 if (item) {
846 if (d_inode(dentry))
847 create_dentry(dentry, d_inode(dentry), item->filp,
848 hmdfs_sb(dentry->d_sb));
849 else
850 hmdfs_err("inode is null!");
851 kref_put(&item->ref, release_cache_item);
852 } else {
853 hmdfs_info("find cache item failed, device_id:%llu", dev_id);
854 }
855 }
856
create_dentry(struct dentry * child_dentry,struct inode * inode,struct file * file,struct hmdfs_sb_info * sbi)857 int create_dentry(struct dentry *child_dentry, struct inode *inode,
858 struct file *file, struct hmdfs_sb_info *sbi)
859 {
860 unsigned int bit_pos, level;
861 unsigned long bidx, end_block;
862 const struct qstr qstr = child_dentry->d_name;
863 __u32 namehash;
864 loff_t pos;
865 ssize_t size;
866 int ret = 0;
867 struct hmdfs_dentry_group *dentry_blk = NULL;
868
869 level = 0;
870
871 namehash = hmdfs_dentry_hash(&qstr, sbi->s_case_sensitive);
872
873 dentry_blk = kmalloc(sizeof(*dentry_blk), GFP_KERNEL);
874 if (!dentry_blk) {
875 ret = -ENOMEM;
876 goto out_err;
877 }
878 find:
879 if (level == MAX_BUCKET_LEVEL) {
880 ret = -ENOSPC;
881 goto out;
882 }
883 bidx = BUCKET_BLOCKS *
884 get_bucketaddr(level, namehash % get_bucket_by_level(level));
885 end_block = bidx + BUCKET_BLOCKS;
886 if (end_block > get_dentry_group_cnt(file_inode(file))) {
887 if (cache_file_truncate(sbi, &(file->f_path),
888 get_dcache_file_size(level))) {
889 ret = -ENOSPC;
890 goto out;
891 }
892 }
893
894 for (; bidx < end_block; bidx++) {
895 int size;
896
897 pos = get_dentry_group_pos(bidx);
898 ret = hmdfs_wlock_file(file, pos, DENTRYGROUP_SIZE);
899 if (ret)
900 goto out;
901
902 size = cache_file_read(sbi, file, dentry_blk,
903 (size_t)DENTRYGROUP_SIZE, &pos);
904 if (size != DENTRYGROUP_SIZE) {
905 ret = -ENOSPC;
906 hmdfs_unlock_file(file, pos, DENTRYGROUP_SIZE);
907 goto out;
908 }
909
910 bit_pos = room_for_filename(&dentry_blk->bitmap,
911 get_dentry_slots(qstr.len),
912 DENTRY_PER_GROUP);
913 if (bit_pos < DENTRY_PER_GROUP)
914 goto add;
915 hmdfs_unlock_file(file, pos, DENTRYGROUP_SIZE);
916 }
917 ++level;
918 goto find;
919 add:
920 pos = get_dentry_group_pos(bidx);
921 update_dentry(dentry_blk, child_dentry, inode, sbi->sb, namehash,
922 bit_pos);
923 size = cache_file_write(sbi, file, dentry_blk,
924 sizeof(struct hmdfs_dentry_group), &pos);
925 if (size != sizeof(struct hmdfs_dentry_group))
926 hmdfs_err("cache file write failed!, ret = %zd", size);
927 hmdfs_unlock_file(file, pos, DENTRYGROUP_SIZE);
928 out:
929 kfree(dentry_blk);
930 out_err:
931 return ret;
932 }
933
hmdfs_init_dcache_lookup_ctx(struct hmdfs_dcache_lookup_ctx * ctx,struct hmdfs_sb_info * sbi,const struct qstr * qstr,struct file * filp)934 void hmdfs_init_dcache_lookup_ctx(struct hmdfs_dcache_lookup_ctx *ctx,
935 struct hmdfs_sb_info *sbi,
936 const struct qstr *qstr, struct file *filp)
937 {
938 ctx->sbi = sbi;
939 ctx->name = qstr;
940 ctx->filp = filp;
941 ctx->bidx = 0;
942 ctx->page = NULL;
943 ctx->insense_de = NULL;
944 ctx->insense_bidx = 0;
945 ctx->insense_page = NULL;
946 }
947
update_inode_to_dentry(struct dentry * child_dentry,struct inode * inode)948 int update_inode_to_dentry(struct dentry *child_dentry, struct inode *inode)
949 {
950 struct hmdfs_sb_info *sbi = d_inode(child_dentry)->i_sb->s_fs_info;
951 struct hmdfs_dentry *de = NULL;
952 loff_t ipos;
953 struct dentry *parent_dentry;
954 struct cache_file_node *cfn = NULL;
955 char *relative_path = NULL;
956 struct hmdfs_dcache_lookup_ctx ctx;
957
958 parent_dentry = child_dentry->d_parent;
959 if (hmdfs_d(parent_dentry)->dentry_type == HMDFS_LAYER_FIRST_DEVICE)
960 return 0;
961
962 relative_path = hmdfs_get_dentry_relative_path(parent_dentry);
963 if (!relative_path)
964 return -ENOMEM;
965
966 cfn = find_cfn(sbi, HMDFS_SERVER_CID, relative_path, true);
967 if (!cfn)
968 goto out;
969
970 hmdfs_init_dcache_lookup_ctx(&ctx, sbi, &child_dentry->d_name,
971 cfn->filp);
972 de = hmdfs_find_dentry(child_dentry, &ctx);
973 if (!de)
974 goto out_cfn;
975
976 de->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
977 de->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
978 de->i_size = cpu_to_le64(inode->i_size);
979 de->i_ino = cpu_to_le64(
980 generate_u64_ino(inode->i_ino, inode->i_generation));
981 de->i_flag = 0;
982
983 ipos = get_dentry_group_pos(ctx.bidx);
984 write_dentry_page(cfn->filp, ctx.page,
985 sizeof(struct hmdfs_dentry_group), ipos);
986 hmdfs_unlock_file(cfn->filp, ipos, DENTRYGROUP_SIZE);
987 kfree(ctx.page);
988 out_cfn:
989 release_cfn(cfn);
990 out:
991 kfree(relative_path);
992 return 0;
993 }
994
hmdfs_delete_dentry(struct dentry * d,struct file * filp)995 void hmdfs_delete_dentry(struct dentry *d, struct file *filp)
996 {
997 struct hmdfs_dentry *de = NULL;
998 unsigned int bit_pos;
999 int slots, i;
1000 loff_t ipos;
1001 ssize_t size;
1002 struct hmdfs_dcache_lookup_ctx ctx;
1003
1004 hmdfs_init_dcache_lookup_ctx(&ctx, hmdfs_sb(d->d_sb), &d->d_name, filp);
1005
1006 de = hmdfs_find_dentry(d, &ctx);
1007 if (IS_ERR_OR_NULL(de)) {
1008 hmdfs_info("find dentry failed!, err=%ld", PTR_ERR(de));
1009 return;
1010 }
1011 slots = get_dentry_slots(le16_to_cpu(de->namelen));
1012
1013 bit_pos = de - ctx.page->nsl;
1014 for (i = 0; i < slots; i++)
1015 __clear_bit_le(bit_pos + i, &ctx.page->bitmap);
1016
1017 ipos = get_dentry_group_pos(ctx.bidx);
1018 size = cache_file_write(hmdfs_sb(d->d_sb), filp, ctx.page,
1019 sizeof(struct hmdfs_dentry_group), &ipos);
1020 if (size != sizeof(struct hmdfs_dentry_group))
1021 hmdfs_err("cache file write failed!, ret = %zd", size);
1022 hmdfs_unlock_file(filp, ipos, DENTRYGROUP_SIZE);
1023 kfree(ctx.page);
1024 }
1025
hmdfs_get_cache_path(struct hmdfs_sb_info * sbi,struct path * dir)1026 static int hmdfs_get_cache_path(struct hmdfs_sb_info *sbi, struct path *dir)
1027 {
1028 struct hmdfs_dentry_info *di = hmdfs_d(sbi->sb->s_root);
1029 int err;
1030
1031 if (!sbi->s_dentry_cache) {
1032 *dir = di->lower_path;
1033 return 0;
1034 }
1035
1036 err = kern_path(sbi->cache_dir, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, dir);
1037 if (err)
1038 hmdfs_err("open failed, errno = %d", err);
1039
1040 return err;
1041 }
1042
hmdfs_put_cache_path(struct hmdfs_sb_info * sbi,struct path * dir)1043 static void hmdfs_put_cache_path(struct hmdfs_sb_info *sbi, struct path *dir)
1044 {
1045 if (!sbi->s_dentry_cache)
1046 return;
1047 path_put(dir);
1048 }
1049
create_local_dentry_file_cache(struct hmdfs_sb_info * sbi)1050 struct file *create_local_dentry_file_cache(struct hmdfs_sb_info *sbi)
1051 {
1052 struct file *filp = NULL;
1053 const struct cred *old_cred = hmdfs_override_creds(sbi->system_cred);
1054 struct path cache_dir;
1055 int err;
1056
1057 err = hmdfs_get_cache_path(sbi, &cache_dir);
1058 if (err) {
1059 filp = ERR_PTR(err);
1060 goto out;
1061 }
1062
1063 filp = file_open_root(&cache_dir, ".",
1064 O_RDWR | O_LARGEFILE | O_TMPFILE,
1065 DENTRY_FILE_PERM);
1066 if (IS_ERR(filp))
1067 hmdfs_err("dentryfile open failed and exit err=%ld",
1068 PTR_ERR(filp));
1069
1070 hmdfs_put_cache_path(sbi, &cache_dir);
1071 out:
1072 hmdfs_revert_creds(old_cred);
1073 return filp;
1074 }
1075
hmdfs_linkat(struct path * old_path,const char * newname)1076 static int hmdfs_linkat(struct path *old_path, const char *newname)
1077 {
1078 struct dentry *new_dentry = NULL;
1079 struct path new_path;
1080 int error;
1081
1082 new_dentry = kern_path_create(AT_FDCWD, newname, &new_path, 0);
1083 if (IS_ERR(new_dentry)) {
1084 hmdfs_err("create kernel path failed, error: %ld",
1085 PTR_ERR(new_dentry));
1086 return PTR_ERR(new_dentry);
1087 }
1088
1089 error = -EXDEV;
1090 if (old_path->mnt != new_path.mnt)
1091 goto out_dput;
1092
1093 error = vfs_link(old_path->dentry, new_path.dentry->d_inode, new_dentry,
1094 NULL);
1095
1096 out_dput:
1097 done_path_create(&new_path, new_dentry);
1098 return error;
1099 }
1100
cache_file_mkdir(const char * name,umode_t mode)1101 static int cache_file_mkdir(const char *name, umode_t mode)
1102 {
1103 struct dentry *dentry;
1104 struct path path;
1105 int err;
1106
1107 dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
1108 if (IS_ERR(dentry))
1109 return PTR_ERR(dentry);
1110
1111 err = vfs_mkdir(d_inode(path.dentry), dentry, mode);
1112 if (err && err != -EEXIST)
1113 hmdfs_err("vfs_mkdir failed, err = %d", err);
1114
1115 done_path_create(&path, dentry);
1116 return err;
1117 }
1118
cache_file_create_path(const char * fullpath)1119 static int cache_file_create_path(const char *fullpath)
1120 {
1121 char *path;
1122 char *s;
1123 int err = 0;
1124
1125 path = kstrdup(fullpath, GFP_KERNEL);
1126 if (!path)
1127 return -ENOMEM;
1128
1129 s = path + 1;
1130 while (true) {
1131 s = strchr(s, '/');
1132 if (!s)
1133 break;
1134 s[0] = '\0';
1135 err = cache_file_mkdir(path, 0755);
1136 if (err && err != -EEXIST)
1137 break;
1138 s[0] = '/';
1139 s++;
1140 }
1141 kfree(path);
1142 return err;
1143 }
1144
hmdfs_cache_path_create(char * s,const char * dir,bool server)1145 static void hmdfs_cache_path_create(char *s, const char *dir, bool server)
1146 {
1147 if (server)
1148 snprintf(s, PATH_MAX, "%s/dentry_cache/server/", dir);
1149 else
1150 snprintf(s, PATH_MAX, "%s/dentry_cache/client/", dir);
1151 }
1152
concat_cachefile_name(char * s,uint64_t hash,const char * id,bool server)1153 static void concat_cachefile_name(char *s, uint64_t hash, const char *id,
1154 bool server)
1155 {
1156 int offset = strlen(s);
1157
1158 if (server)
1159 snprintf(s + offset, PATH_MAX - offset, "%016llx", hash);
1160 else
1161 snprintf(s + offset, PATH_MAX - offset, "%s_%016llx", id, hash);
1162 }
1163
cache_file_name_generate(char * fullname,struct hmdfs_peer * con,const char * relative_path,bool server)1164 int cache_file_name_generate(char *fullname, struct hmdfs_peer *con,
1165 const char *relative_path, bool server)
1166 {
1167 struct hmdfs_sb_info *sbi = con->sbi;
1168 uint64_t hash;
1169 char cid[HMDFS_CFN_CID_SIZE];
1170 int err;
1171
1172 hmdfs_cache_path_create(fullname, sbi->cache_dir, server);
1173
1174 err = cache_file_create_path(fullname);
1175 if (err && err != -EEXIST) {
1176 hmdfs_err("making dir failed %d", err);
1177 return err;
1178 }
1179
1180 strncpy(cid, con->cid, HMDFS_CFN_CID_SIZE - 1);
1181 cid[HMDFS_CFN_CID_SIZE - 1] = '\0';
1182
1183 hash = path_hash(relative_path, strlen(relative_path),
1184 sbi->s_case_sensitive);
1185 concat_cachefile_name(fullname, hash, cid, server);
1186
1187 return 0;
1188 }
1189
free_cfn(struct cache_file_node * cfn)1190 static void free_cfn(struct cache_file_node *cfn)
1191 {
1192 if (!IS_ERR_OR_NULL(cfn->filp))
1193 filp_close(cfn->filp, NULL);
1194
1195 kfree(cfn->relative_path);
1196 kfree(cfn);
1197 }
1198
path_cmp(const char * path1,const char * path2,bool case_sensitive)1199 static bool path_cmp(const char *path1, const char *path2, bool case_sensitive)
1200 {
1201 int ret;
1202
1203 if (case_sensitive)
1204 ret = strcmp(path1, path2);
1205 else
1206 ret = strcasecmp(path1, path2);
1207
1208 return !ret;
1209 }
1210
dentry_file_match(struct cache_file_node * cfn,const char * id,const char * path)1211 static bool dentry_file_match(struct cache_file_node *cfn, const char *id,
1212 const char *path)
1213 {
1214 return (path_cmp(cfn->relative_path, path, cfn->sbi->s_case_sensitive) &&
1215 !strncmp((cfn)->cid, id, HMDFS_CFN_CID_SIZE - 1));
1216 }
1217
__find_cfn(struct hmdfs_sb_info * sbi,const char * cid,const char * path,bool server)1218 struct cache_file_node *__find_cfn(struct hmdfs_sb_info *sbi, const char *cid,
1219 const char *path, bool server)
1220 {
1221 struct cache_file_node *cfn = NULL;
1222 struct list_head *head = NULL;
1223
1224 head = get_list_head(sbi, server);
1225
1226 list_for_each_entry(cfn, head, list) {
1227 if (dentry_file_match(cfn, cid, path)) {
1228 refcount_inc(&cfn->ref);
1229 return cfn;
1230 }
1231 }
1232 return NULL;
1233 }
1234
create_cfn(struct hmdfs_sb_info * sbi,const char * path,const char * cid,bool server)1235 struct cache_file_node *create_cfn(struct hmdfs_sb_info *sbi, const char *path,
1236 const char *cid, bool server)
1237 {
1238 struct cache_file_node *cfn = kzalloc(sizeof(*cfn), GFP_KERNEL);
1239
1240 if (!cfn)
1241 return NULL;
1242
1243 cfn->relative_path = kstrdup(path, GFP_KERNEL);
1244 if (!cfn->relative_path)
1245 goto out;
1246
1247 refcount_set(&cfn->ref, 1);
1248 strncpy(cfn->cid, cid, HMDFS_CFN_CID_SIZE - 1);
1249 cfn->cid[HMDFS_CFN_CID_SIZE - 1] = '\0';
1250 cfn->sbi = sbi;
1251 cfn->server = server;
1252 return cfn;
1253 out:
1254 free_cfn(cfn);
1255 return NULL;
1256 }
1257
insert_cfn(struct hmdfs_sb_info * sbi,const char * filename,const char * path,const char * cid,bool server)1258 static struct file *insert_cfn(struct hmdfs_sb_info *sbi, const char *filename,
1259 const char *path, const char *cid, bool server)
1260 {
1261 const struct cred *old_cred = NULL;
1262 struct cache_file_node *cfn = NULL;
1263 struct cache_file_node *exist = NULL;
1264 struct list_head *head = NULL;
1265 struct file *filp = NULL;
1266
1267 cfn = create_cfn(sbi, path, cid, server);
1268 if (!cfn)
1269 return ERR_PTR(-ENOMEM);
1270
1271 old_cred = hmdfs_override_creds(sbi->system_cred);
1272 filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
1273 hmdfs_revert_creds(old_cred);
1274 if (IS_ERR(filp)) {
1275 hmdfs_err("open file failed, err=%ld", PTR_ERR(filp));
1276 goto out;
1277 }
1278
1279 head = get_list_head(sbi, server);
1280
1281 mutex_lock(&sbi->cache_list_lock);
1282 exist = __find_cfn(sbi, cid, path, server);
1283 if (!exist) {
1284 cfn->filp = filp;
1285 list_add_tail(&cfn->list, head);
1286 } else {
1287 mutex_unlock(&sbi->cache_list_lock);
1288 release_cfn(exist);
1289 filp_close(filp, NULL);
1290 filp = ERR_PTR(-EEXIST);
1291 goto out;
1292 }
1293 mutex_unlock(&sbi->cache_list_lock);
1294 return filp;
1295 out:
1296 free_cfn(cfn);
1297 return filp;
1298 }
1299
hmdfs_rename_dentry(struct dentry * old_dentry,struct dentry * new_dentry,struct file * old_filp,struct file * new_filp)1300 int hmdfs_rename_dentry(struct dentry *old_dentry, struct dentry *new_dentry,
1301 struct file *old_filp, struct file *new_filp)
1302 {
1303 int ret;
1304 struct hmdfs_sb_info *sbi = hmdfs_sb(new_dentry->d_sb);
1305
1306 /*
1307 * Try to delete first, because stale dentry might exist after
1308 * coverwrite.
1309 */
1310 hmdfs_delete_dentry(new_dentry, new_filp);
1311
1312 ret = create_dentry(new_dentry, d_inode(old_dentry), new_filp, sbi);
1313 if (ret) {
1314 hmdfs_err("create dentry failed!, err=%d", ret);
1315 return ret;
1316 }
1317
1318 hmdfs_delete_dentry(old_dentry, old_filp);
1319 return 0;
1320 }
1321
1322 /**
1323 * cache_file_persistent - link the tmpfile to the cache dir
1324 * @con: the connection peer
1325 * @filp: the file handler of the tmpfile
1326 * @relative_path: the relative path which the tmpfile belongs
1327 * @server: server or client
1328 *
1329 * Return value: the new file handler of the persistent file if the
1330 * persistent operation succeed. Otherwise will return the original handler
1331 * of the tmpfile passed in, so that the caller does not have to check
1332 * the returned handler.
1333 *
1334 */
cache_file_persistent(struct hmdfs_peer * con,struct file * filp,const char * relative_path,bool server)1335 struct file *cache_file_persistent(struct hmdfs_peer *con, struct file *filp,
1336 const char *relative_path, bool server)
1337 {
1338 struct cache_file_node *cfn = NULL;
1339 char *fullname = NULL;
1340 char *cid = server ? HMDFS_SERVER_CID : (char *)con->cid;
1341 struct file *newf = NULL;
1342 int i = 0;
1343 int len;
1344 int err;
1345
1346 if (!con->sbi->s_dentry_cache)
1347 return filp;
1348
1349 cfn = find_cfn(con->sbi, cid, relative_path, server);
1350 if (cfn) {
1351 release_cfn(cfn);
1352 return filp;
1353 }
1354 fullname = kzalloc(PATH_MAX, GFP_KERNEL);
1355 if (!fullname)
1356 return filp;
1357
1358 err = cache_file_name_generate(fullname, con, relative_path, server);
1359 if (err)
1360 goto out;
1361
1362 err = __vfs_setxattr(file_dentry(filp), file_inode(filp),
1363 DENTRY_FILE_XATTR_NAME, relative_path,
1364 strlen(relative_path), 0);
1365 if (err) {
1366 hmdfs_err("setxattr for file failed, err=%d", err);
1367 goto out;
1368 }
1369
1370 len = strlen(fullname);
1371
1372 do {
1373 err = hmdfs_linkat(&filp->f_path, fullname);
1374 if (!err)
1375 break;
1376
1377 snprintf(fullname + len, PATH_MAX - len, "_%d", i);
1378 } while (i++ < DENTRY_FILE_NAME_RETRY);
1379
1380 if (err) {
1381 hmdfs_err("link for file failed, err=%d", err);
1382 goto out;
1383 }
1384
1385 newf = insert_cfn(con->sbi, fullname, relative_path, cid, server);
1386 if (!IS_ERR(newf))
1387 filp = newf;
1388 out:
1389 kfree(fullname);
1390 return filp;
1391 }
1392
get_cloud_cache_file(struct dentry * dentry,struct hmdfs_sb_info * sbi)1393 int get_cloud_cache_file(struct dentry *dentry, struct hmdfs_sb_info *sbi)
1394 {
1395 int ret;
1396 ssize_t res;
1397 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
1398 struct clearcache_item *item;
1399 struct file *filp = NULL;
1400 uint64_t hash;
1401 char *relative_path = NULL;
1402 char *dirname = NULL;
1403 char *fullname = NULL;
1404 char *cache_file_name = NULL;
1405 char *kvalue = NULL;
1406
1407 item = hmdfs_find_cache_item(CLOUD_DEVICE, dentry);
1408 if (item) {
1409 kref_put(&item->ref, release_cache_item);
1410 return 0;
1411 }
1412
1413 relative_path = hmdfs_get_dentry_relative_path(dentry);
1414 if (unlikely(!relative_path)) {
1415 hmdfs_err("get relative path failed %d", -ENOMEM);
1416 ret = -ENOMEM;
1417 goto out;
1418 }
1419
1420 dirname = kzalloc(PATH_MAX, GFP_KERNEL);
1421 if (!dirname) {
1422 ret = -ENOMEM;
1423 goto out;
1424 }
1425
1426 cache_file_name = kzalloc(PATH_MAX, GFP_KERNEL);
1427 if (!cache_file_name) {
1428 ret = -ENOMEM;
1429 goto out;
1430 }
1431
1432 fullname = kzalloc(PATH_MAX, GFP_KERNEL);
1433 if (!fullname) {
1434 ret = -ENOMEM;
1435 goto out;
1436 }
1437
1438 kvalue = kzalloc(PATH_MAX, GFP_KERNEL);
1439 if (!kvalue) {
1440 ret = -ENOMEM;
1441 goto out;
1442 }
1443
1444 hash = path_hash(relative_path, strlen(relative_path),
1445 sbi->s_case_sensitive);
1446 concat_cachefile_name(cache_file_name, hash, CLOUD_CID, false);
1447 snprintf(dirname, PATH_MAX, "%s/dentry_cache/cloud/",
1448 sbi->cache_dir);
1449 snprintf(fullname, PATH_MAX, "%s%s", dirname, cache_file_name);
1450
1451 filp = filp_open(fullname, O_RDWR | O_LARGEFILE, 0);
1452 if (IS_ERR(filp)) {
1453 hmdfs_debug("open fail %ld", PTR_ERR(filp));
1454 ret = PTR_ERR(filp);
1455 goto out;
1456 }
1457
1458 res = __vfs_getxattr(file_dentry(filp), file_inode(filp),
1459 DENTRY_FILE_XATTR_NAME, kvalue, PATH_MAX);
1460 if (res <= 0 || res >= PATH_MAX) {
1461 hmdfs_err("getxattr return: %zd", res);
1462 filp_close(filp, NULL);
1463 ret = -ENOENT;
1464 goto out;
1465 }
1466 kvalue[res] = '\0';
1467
1468 if (!path_cmp(relative_path, kvalue, sbi->s_case_sensitive)) {
1469 hmdfs_err("relative path from xattr do not match");
1470 filp_close(filp, NULL);
1471 ret = -ENOENT;
1472 goto out;
1473 }
1474
1475 mutex_lock(&d_info->cache_pull_lock);
1476 hmdfs_add_cache_list(CLOUD_DEVICE, dentry, filp);
1477 mutex_unlock(&d_info->cache_pull_lock);
1478
1479 ret = 0;
1480 out:
1481 kfree(relative_path);
1482 kfree(dirname);
1483 kfree(fullname);
1484 kfree(cache_file_name);
1485 kfree(kvalue);
1486
1487 return ret;
1488 }
1489
__destroy_cfn(struct list_head * head)1490 void __destroy_cfn(struct list_head *head)
1491 {
1492 struct cache_file_node *cfn = NULL;
1493 struct cache_file_node *n = NULL;
1494
1495 list_for_each_entry_safe(cfn, n, head, list) {
1496 list_del_init(&cfn->list);
1497 release_cfn(cfn);
1498 }
1499 }
1500
hmdfs_cfn_destroy(struct hmdfs_sb_info * sbi)1501 void hmdfs_cfn_destroy(struct hmdfs_sb_info *sbi)
1502 {
1503 mutex_lock(&sbi->cache_list_lock);
1504 __destroy_cfn(&sbi->client_cache);
1505 __destroy_cfn(&sbi->server_cache);
1506 mutex_unlock(&sbi->cache_list_lock);
1507 }
1508
find_cfn(struct hmdfs_sb_info * sbi,const char * cid,const char * path,bool server)1509 struct cache_file_node *find_cfn(struct hmdfs_sb_info *sbi, const char *cid,
1510 const char *path, bool server)
1511 {
1512 struct cache_file_node *cfn = NULL;
1513
1514 mutex_lock(&sbi->cache_list_lock);
1515 cfn = __find_cfn(sbi, cid, path, server);
1516 mutex_unlock(&sbi->cache_list_lock);
1517 return cfn;
1518 }
1519
release_cfn(struct cache_file_node * cfn)1520 void release_cfn(struct cache_file_node *cfn)
1521 {
1522 if (refcount_dec_and_test(&cfn->ref))
1523 free_cfn(cfn);
1524 }
1525
remove_cfn(struct cache_file_node * cfn)1526 void remove_cfn(struct cache_file_node *cfn)
1527 {
1528 struct hmdfs_sb_info *sbi = cfn->sbi;
1529 bool deleted;
1530
1531 mutex_lock(&sbi->cache_list_lock);
1532 deleted = list_empty(&cfn->list);
1533 if (!deleted)
1534 list_del_init(&cfn->list);
1535 mutex_unlock(&sbi->cache_list_lock);
1536 if (!deleted) {
1537 delete_dentry_file(cfn->filp);
1538 release_cfn(cfn);
1539 }
1540 }
1541
hmdfs_do_lock_file(struct file * filp,unsigned char fl_type,loff_t start,loff_t len)1542 int hmdfs_do_lock_file(struct file *filp, unsigned char fl_type, loff_t start,
1543 loff_t len)
1544 {
1545 struct file_lock fl;
1546 int err;
1547
1548 locks_init_lock(&fl);
1549
1550 fl.fl_type = fl_type;
1551 fl.fl_flags = FL_POSIX | FL_CLOSE | FL_SLEEP;
1552 fl.fl_start = start;
1553 fl.fl_end = start + len - 1;
1554 fl.fl_owner = filp;
1555 fl.fl_pid = current->tgid;
1556 fl.fl_file = filp;
1557 fl.fl_ops = NULL;
1558 fl.fl_lmops = NULL;
1559
1560 err = locks_lock_file_wait(filp, &fl);
1561 if (err)
1562 hmdfs_err("lock file wait failed: %d", err);
1563
1564 return err;
1565 }
1566
hmdfs_wlock_file(struct file * filp,loff_t start,loff_t len)1567 int hmdfs_wlock_file(struct file *filp, loff_t start, loff_t len)
1568 {
1569 return hmdfs_do_lock_file(filp, F_WRLCK, start, len);
1570 }
1571
hmdfs_rlock_file(struct file * filp,loff_t start,loff_t len)1572 int hmdfs_rlock_file(struct file *filp, loff_t start, loff_t len)
1573 {
1574 return hmdfs_do_lock_file(filp, F_RDLCK, start, len);
1575 }
1576
hmdfs_unlock_file(struct file * filp,loff_t start,loff_t len)1577 int hmdfs_unlock_file(struct file *filp, loff_t start, loff_t len)
1578 {
1579 return hmdfs_do_lock_file(filp, F_UNLCK, start, len);
1580 }
1581
cache_file_truncate(struct hmdfs_sb_info * sbi,const struct path * path,loff_t length)1582 long cache_file_truncate(struct hmdfs_sb_info *sbi, const struct path *path,
1583 loff_t length)
1584 {
1585 const struct cred *old_cred = hmdfs_override_creds(sbi->system_cred);
1586 long ret = vfs_truncate(path, length);
1587
1588 hmdfs_revert_creds(old_cred);
1589
1590 return ret;
1591 }
1592
cache_file_read(struct hmdfs_sb_info * sbi,struct file * filp,void * buf,size_t count,loff_t * pos)1593 ssize_t cache_file_read(struct hmdfs_sb_info *sbi, struct file *filp, void *buf,
1594 size_t count, loff_t *pos)
1595 {
1596 const struct cred *old_cred = hmdfs_override_creds(sbi->system_cred);
1597 ssize_t ret = kernel_read(filp, buf, count, pos);
1598
1599 hmdfs_revert_creds(old_cred);
1600
1601 return ret;
1602 }
1603
cache_file_write(struct hmdfs_sb_info * sbi,struct file * filp,const void * buf,size_t count,loff_t * pos)1604 ssize_t cache_file_write(struct hmdfs_sb_info *sbi, struct file *filp,
1605 const void *buf, size_t count, loff_t *pos)
1606 {
1607 const struct cred *old_cred = hmdfs_override_creds(sbi->system_cred);
1608 ssize_t ret = kernel_write(filp, buf, count, pos);
1609
1610 hmdfs_revert_creds(old_cred);
1611
1612 return ret;
1613 }
1614
1615
read_header(struct hmdfs_sb_info * sbi,struct file * filp,struct hmdfs_dcache_header * header)1616 int read_header(struct hmdfs_sb_info *sbi, struct file *filp,
1617 struct hmdfs_dcache_header *header)
1618 {
1619 ssize_t bytes;
1620 loff_t pos = 0;
1621
1622 bytes = cache_file_read(sbi, filp, header, sizeof(*header), &pos);
1623 if (bytes != sizeof(*header)) {
1624 hmdfs_err("read file failed, err:%zd", bytes);
1625 return -EIO;
1626 }
1627
1628 return 0;
1629 }
1630
cache_get_dentry_count(struct hmdfs_sb_info * sbi,struct file * filp)1631 static unsigned long long cache_get_dentry_count(struct hmdfs_sb_info *sbi,
1632 struct file *filp)
1633 {
1634 struct hmdfs_dcache_header header;
1635 int overallpage;
1636
1637 overallpage = get_dentry_group_cnt(file_inode(filp));
1638 if (overallpage == 0)
1639 return 0;
1640
1641 if (read_header(sbi, filp, &header))
1642 return 0;
1643
1644 return le64_to_cpu(header.num);
1645 }
1646
cache_check_case_sensitive(struct hmdfs_sb_info * sbi,struct file * filp)1647 static int cache_check_case_sensitive(struct hmdfs_sb_info *sbi,
1648 struct file *filp)
1649 {
1650 struct hmdfs_dcache_header header;
1651
1652 if (read_header(sbi, filp, &header))
1653 return 0;
1654
1655 if (sbi->s_case_sensitive != (bool)header.case_sensitive) {
1656 hmdfs_info("Case sensitive inconsistent, current fs is: %d, cache is %d, will drop cache",
1657 sbi->s_case_sensitive, header.case_sensitive);
1658 return 0;
1659 }
1660 return 1;
1661 }
1662
write_header(struct file * filp,struct hmdfs_dcache_header * header)1663 int write_header(struct file *filp, struct hmdfs_dcache_header *header)
1664 {
1665 loff_t pos = 0;
1666 ssize_t size;
1667
1668 size = kernel_write(filp, header, sizeof(*header), &pos);
1669 if (size != sizeof(*header)) {
1670 hmdfs_err("update dcache header failed %zd", size);
1671 return -EIO;
1672 }
1673
1674 return 0;
1675 }
1676
add_to_delete_list(struct hmdfs_sb_info * sbi,struct cache_file_node * cfn)1677 void add_to_delete_list(struct hmdfs_sb_info *sbi, struct cache_file_node *cfn)
1678 {
1679 mutex_lock(&sbi->cache_list_lock);
1680 list_add_tail(&cfn->list, &sbi->to_delete);
1681 mutex_unlock(&sbi->cache_list_lock);
1682 }
1683
load_cfn(struct hmdfs_sb_info * sbi,const char * fullname,const char * path,const char * cid,bool server)1684 void load_cfn(struct hmdfs_sb_info *sbi, const char *fullname, const char *path,
1685 const char *cid, bool server)
1686 {
1687 struct cache_file_node *cfn = NULL;
1688 struct cache_file_node *cfn1 = NULL;
1689 struct list_head *head = NULL;
1690
1691 cfn = create_cfn(sbi, path, cid, server);
1692 if (!cfn)
1693 return;
1694
1695 cfn->filp = filp_open(fullname, O_RDWR | O_LARGEFILE, 0);
1696 if (IS_ERR(cfn->filp)) {
1697 hmdfs_err("open fail %ld", PTR_ERR(cfn->filp));
1698 goto out;
1699 }
1700
1701 if (cache_get_dentry_count(sbi, cfn->filp) < sbi->dcache_threshold && strcmp(cid, CLOUD_CID)) {
1702 add_to_delete_list(sbi, cfn);
1703 return;
1704 }
1705
1706 if (!cache_check_case_sensitive(sbi, cfn->filp) && strcmp(cid, CLOUD_CID)) {
1707 add_to_delete_list(sbi, cfn);
1708 return;
1709 }
1710
1711 head = get_list_head(sbi, server);
1712
1713 mutex_lock(&sbi->cache_list_lock);
1714 cfn1 = __find_cfn(sbi, cid, path, server);
1715 if (!cfn1) {
1716 list_add_tail(&cfn->list, head);
1717 } else {
1718 release_cfn(cfn1);
1719 mutex_unlock(&sbi->cache_list_lock);
1720 add_to_delete_list(sbi, cfn);
1721 return;
1722 }
1723 mutex_unlock(&sbi->cache_list_lock);
1724
1725 return;
1726 out:
1727 free_cfn(cfn);
1728 }
1729
get_cid_and_hash(const char * name,uint64_t * hash,char * cid)1730 static int get_cid_and_hash(const char *name, uint64_t *hash, char *cid)
1731 {
1732 int len;
1733 char *p = strstr(name, "_");
1734
1735 if (!p)
1736 return -EINVAL;
1737
1738 len = p - name;
1739 if (len >= HMDFS_CFN_CID_SIZE)
1740 return -EINVAL;
1741
1742 memcpy(cid, name, len);
1743 cid[len] = '\0';
1744
1745 if (sscanf(++p, "%llx", hash) != 1)
1746 return -EINVAL;
1747 return 0;
1748 }
1749
store_one(const char * name,struct cache_file_callback * cb)1750 static void store_one(const char *name, struct cache_file_callback *cb)
1751 {
1752 struct file *file = NULL;
1753 char *fullname = NULL;
1754 char *kvalue = NULL;
1755 char cid[HMDFS_CFN_CID_SIZE];
1756 uint64_t hash;
1757 ssize_t error;
1758
1759 if (strlen(name) + strlen(cb->dirname) >= PATH_MAX)
1760 return;
1761
1762 fullname = kzalloc(PATH_MAX, GFP_KERNEL);
1763 if (!fullname)
1764 return;
1765
1766 snprintf(fullname, PATH_MAX, "%s%s", cb->dirname, name);
1767
1768 file = filp_open(fullname, O_RDWR | O_LARGEFILE, 0);
1769 if (IS_ERR(file)) {
1770 hmdfs_err("open fail %ld", PTR_ERR(file));
1771 goto out;
1772 }
1773
1774 kvalue = kzalloc(PATH_MAX, GFP_KERNEL);
1775 if (!kvalue)
1776 goto out_file;
1777
1778 error = __vfs_getxattr(file_dentry(file), file_inode(file),
1779 DENTRY_FILE_XATTR_NAME, kvalue, PATH_MAX);
1780 if (error <= 0 || error >= PATH_MAX) {
1781 hmdfs_err("getxattr return: %zd", error);
1782 goto out_kvalue;
1783 }
1784
1785 kvalue[error] = '\0';
1786 cid[0] = '\0';
1787
1788 if (!cb->server) {
1789 if (get_cid_and_hash(name, &hash, cid)) {
1790 hmdfs_err("get cid and hash fail");
1791 goto out_kvalue;
1792 }
1793 }
1794
1795 load_cfn(cb->sbi, fullname, kvalue, cid, cb->server);
1796
1797 out_kvalue:
1798 kfree(kvalue);
1799 out_file:
1800 filp_close(file, NULL);
1801 out:
1802 kfree(fullname);
1803 }
1804
cache_file_iterate(struct dir_context * ctx,const char * name,int name_len,loff_t offset,u64 ino,unsigned int d_type)1805 static int cache_file_iterate(struct dir_context *ctx, const char *name,
1806 int name_len, loff_t offset, u64 ino,
1807 unsigned int d_type)
1808 {
1809 struct cache_file_item *cfi = NULL;
1810 struct cache_file_callback *cb =
1811 container_of(ctx, struct cache_file_callback, ctx);
1812
1813 if (name_len > NAME_MAX) {
1814 hmdfs_err("name_len:%d NAME_MAX:%u", name_len, NAME_MAX);
1815 return 0;
1816 }
1817
1818 if (d_type != DT_REG)
1819 return 0;
1820
1821 cfi = kmalloc(sizeof(*cfi), GFP_KERNEL);
1822 if (!cfi)
1823 return -ENOMEM;
1824
1825 cfi->name = kstrndup(name, name_len, GFP_KERNEL);
1826 if (!cfi->name) {
1827 kfree(cfi);
1828 return -ENOMEM;
1829 }
1830
1831 list_add_tail(&cfi->list, &cb->list);
1832
1833 return 0;
1834 }
1835
hmdfs_do_load(struct hmdfs_sb_info * sbi,const char * fullname,bool server)1836 void hmdfs_do_load(struct hmdfs_sb_info *sbi, const char *fullname, bool server)
1837 {
1838 struct file *file = NULL;
1839 struct path dirpath;
1840 int err;
1841 struct cache_file_item *cfi = NULL;
1842 struct cache_file_item *n = NULL;
1843 struct cache_file_callback cb = {
1844 .ctx.actor = cache_file_iterate,
1845 .ctx.pos = 0,
1846 .dirname = fullname,
1847 .sbi = sbi,
1848 .server = server,
1849 };
1850 INIT_LIST_HEAD(&cb.list);
1851
1852
1853 err = kern_path(fullname, LOOKUP_DIRECTORY, &dirpath);
1854 if (err) {
1855 hmdfs_info("No file path");
1856 return;
1857 }
1858
1859 file = dentry_open(&dirpath, O_RDONLY, current_cred());
1860 if (IS_ERR_OR_NULL(file)) {
1861 hmdfs_err("dentry_open failed, error: %ld", PTR_ERR(file));
1862 path_put(&dirpath);
1863 return;
1864 }
1865
1866 err = iterate_dir(file, &cb.ctx);
1867 if (err)
1868 hmdfs_err("iterate_dir failed, err: %d", err);
1869
1870 list_for_each_entry_safe(cfi, n, &cb.list, list) {
1871 store_one(cfi->name, &cb);
1872 list_del_init(&cfi->list);
1873 kfree(cfi->name);
1874 kfree(cfi);
1875 }
1876
1877 fput(file);
1878 path_put(&dirpath);
1879 }
1880
1881 /**
1882 * This function just used for delete dentryfile.dat
1883 */
delete_dentry_file(struct file * filp)1884 int delete_dentry_file(struct file *filp)
1885 {
1886 int err = 0;
1887 struct dentry *dentry = file_dentry(filp);
1888 struct dentry *parent = lock_parent(dentry);
1889
1890 if (dentry->d_parent == parent) {
1891 dget(dentry);
1892 err = vfs_unlink(d_inode(parent), dentry, NULL);
1893 dput(dentry);
1894 }
1895 unlock_dir(parent);
1896
1897 return err;
1898 }
1899
hmdfs_delete_useless_cfn(struct hmdfs_sb_info * sbi)1900 void hmdfs_delete_useless_cfn(struct hmdfs_sb_info *sbi)
1901 {
1902 struct cache_file_node *cfn = NULL;
1903 struct cache_file_node *n = NULL;
1904
1905 mutex_lock(&sbi->cache_list_lock);
1906
1907 list_for_each_entry_safe(cfn, n, &sbi->to_delete, list) {
1908 delete_dentry_file(cfn->filp);
1909 list_del_init(&cfn->list);
1910 release_cfn(cfn);
1911 }
1912 mutex_unlock(&sbi->cache_list_lock);
1913 }
1914
hmdfs_cfn_load(struct hmdfs_sb_info * sbi)1915 void hmdfs_cfn_load(struct hmdfs_sb_info *sbi)
1916 {
1917 char *fullname = NULL;
1918
1919 if (!sbi->s_dentry_cache)
1920 return;
1921
1922 fullname = kzalloc(PATH_MAX, GFP_KERNEL);
1923 if (!fullname)
1924 return;
1925
1926 snprintf(fullname, PATH_MAX, "%s/dentry_cache/client/",
1927 sbi->cache_dir);
1928 hmdfs_do_load(sbi, fullname, false);
1929
1930 snprintf(fullname, PATH_MAX, "%s/dentry_cache/server/",
1931 sbi->cache_dir);
1932 hmdfs_do_load(sbi, fullname, true);
1933
1934 kfree(fullname);
1935
1936 hmdfs_delete_useless_cfn(sbi);
1937 }
1938
__cache_file_destroy_by_path(struct list_head * head,const char * path)1939 static void __cache_file_destroy_by_path(struct list_head *head,
1940 const char *path)
1941 {
1942 struct cache_file_node *cfn = NULL;
1943 struct cache_file_node *n = NULL;
1944
1945 list_for_each_entry_safe(cfn, n, head, list) {
1946 if (strcmp(path, cfn->relative_path) != 0)
1947 continue;
1948 list_del_init(&cfn->list);
1949 delete_dentry_file(cfn->filp);
1950 release_cfn(cfn);
1951 }
1952 }
1953
cache_file_destroy_by_path(struct hmdfs_sb_info * sbi,const char * path)1954 static void cache_file_destroy_by_path(struct hmdfs_sb_info *sbi,
1955 const char *path)
1956 {
1957 mutex_lock(&sbi->cache_list_lock);
1958
1959 __cache_file_destroy_by_path(&sbi->server_cache, path);
1960 __cache_file_destroy_by_path(&sbi->client_cache, path);
1961
1962 mutex_unlock(&sbi->cache_list_lock);
1963 }
1964
cache_file_find_and_delete(struct hmdfs_peer * con,const char * relative_path)1965 static void cache_file_find_and_delete(struct hmdfs_peer *con,
1966 const char *relative_path)
1967 {
1968 struct cache_file_node *cfn;
1969
1970 cfn = find_cfn(con->sbi, con->cid, relative_path, false);
1971 if (!cfn)
1972 return;
1973
1974 remove_cfn(cfn);
1975 release_cfn(cfn);
1976 }
1977
cache_file_delete_by_dentry(struct hmdfs_peer * con,struct dentry * dentry)1978 void cache_file_delete_by_dentry(struct hmdfs_peer *con, struct dentry *dentry)
1979 {
1980 char *relative_path = NULL;
1981
1982 relative_path = hmdfs_get_dentry_relative_path(dentry);
1983 if (unlikely(!relative_path)) {
1984 hmdfs_err("get relative path failed %d", -ENOMEM);
1985 return;
1986 }
1987 cache_file_find_and_delete(con, relative_path);
1988 kfree(relative_path);
1989 }
1990
hmdfs_get_new_dentry_file(struct hmdfs_peer * con,const char * relative_path,struct hmdfs_dcache_header * header)1991 struct file *hmdfs_get_new_dentry_file(struct hmdfs_peer *con,
1992 const char *relative_path,
1993 struct hmdfs_dcache_header *header)
1994 {
1995 struct hmdfs_sb_info *sbi = con->sbi;
1996 int len = strlen(relative_path);
1997 struct file *filp = NULL;
1998 int err;
1999
2000 filp = create_local_dentry_file_cache(sbi);
2001 if (IS_ERR(filp))
2002 return filp;
2003
2004 err = hmdfs_client_start_readdir(con, filp, relative_path, len, header);
2005 if (err) {
2006 if (err != -ENOENT)
2007 hmdfs_err("readdir failed dev: %llu err: %d",
2008 con->device_id, err);
2009 fput(filp);
2010 filp = ERR_PTR(err);
2011 }
2012
2013 return filp;
2014 }
2015
add_cfn_to_item(struct dentry * dentry,struct hmdfs_peer * con,struct cache_file_node * cfn)2016 void add_cfn_to_item(struct dentry *dentry, struct hmdfs_peer *con,
2017 struct cache_file_node *cfn)
2018 {
2019 struct file *file = cfn->filp;
2020 int err;
2021
2022 err = hmdfs_add_cache_list(con->device_id, dentry, file);
2023 if (unlikely(err)) {
2024 hmdfs_err("add cache list failed devid:%llu err:%d",
2025 con->device_id, err);
2026 return;
2027 }
2028 }
2029
hmdfs_add_file_to_cache(struct dentry * dentry,struct hmdfs_peer * con,struct file * file,const char * relative_path)2030 int hmdfs_add_file_to_cache(struct dentry *dentry, struct hmdfs_peer *con,
2031 struct file *file, const char *relative_path)
2032 {
2033 struct hmdfs_sb_info *sbi = con->sbi;
2034 struct file *newf = file;
2035
2036 if (cache_get_dentry_count(sbi, file) >= sbi->dcache_threshold)
2037 newf = cache_file_persistent(con, file, relative_path, false);
2038 else
2039 cache_file_find_and_delete(con, relative_path);
2040
2041 return hmdfs_add_cache_list(con->device_id, dentry, newf);
2042 }
2043
read_header_and_revalidate(struct hmdfs_peer * con,struct file * filp,const char * relative_path)2044 static struct file *read_header_and_revalidate(struct hmdfs_peer *con,
2045 struct file *filp,
2046 const char *relative_path)
2047 {
2048 struct hmdfs_dcache_header header;
2049 struct hmdfs_dcache_header *p = NULL;
2050
2051 if (read_header(con->sbi, filp, &header) == 0)
2052 p = &header;
2053
2054 return hmdfs_get_new_dentry_file(con, relative_path, p);
2055 }
2056
remote_file_revalidate_cfn(struct dentry * dentry,struct hmdfs_peer * con,struct cache_file_node * cfn,const char * relative_path)2057 void remote_file_revalidate_cfn(struct dentry *dentry, struct hmdfs_peer *con,
2058 struct cache_file_node *cfn,
2059 const char *relative_path)
2060 {
2061 struct file *file = NULL;
2062 int err;
2063
2064 file = read_header_and_revalidate(con, cfn->filp, relative_path);
2065 if (IS_ERR(file))
2066 return;
2067
2068 /*
2069 * If the request returned ok but file length is 0, we assume
2070 * that the server verified the client cache file is uptodate.
2071 */
2072 if (i_size_read(file->f_inode) == 0) {
2073 hmdfs_info("The cfn cache for dev:%llu is uptodate",
2074 con->device_id);
2075 fput(file);
2076 add_cfn_to_item(dentry, con, cfn);
2077 return;
2078 }
2079
2080 /* OK, cfn is not uptodate, let's remove it and add the new file */
2081 remove_cfn(cfn);
2082
2083 err = hmdfs_add_file_to_cache(dentry, con, file, relative_path);
2084 if (unlikely(err))
2085 hmdfs_err("add cache list failed devid:%llu err:%d",
2086 con->device_id, err);
2087 fput(file);
2088 }
2089
remote_file_revalidate_item(struct dentry * dentry,struct hmdfs_peer * con,struct clearcache_item * item,const char * relative_path)2090 void remote_file_revalidate_item(struct dentry *dentry, struct hmdfs_peer *con,
2091 struct clearcache_item *item,
2092 const char *relative_path)
2093 {
2094 struct file *file = NULL;
2095 int err;
2096
2097 file = read_header_and_revalidate(con, item->filp, relative_path);
2098 if (IS_ERR(file))
2099 return;
2100
2101 /*
2102 * If the request returned ok but file length is 0, we assume
2103 * that the server verified the client cache file is uptodate.
2104 */
2105 if (i_size_read(file->f_inode) == 0) {
2106 hmdfs_info("The item cache for dev:%llu is uptodate",
2107 con->device_id);
2108 item->time = jiffies;
2109 fput(file);
2110 return;
2111 }
2112
2113 /* We need to replace the old item */
2114 remove_cache_item(item);
2115 cache_file_find_and_delete(con, relative_path);
2116
2117 err = hmdfs_add_file_to_cache(dentry, con, file, relative_path);
2118 if (unlikely(err))
2119 hmdfs_err("add cache list failed devid:%llu err:%d",
2120 con->device_id, err);
2121 fput(file);
2122 }
2123
get_remote_dentry_file(struct dentry * dentry,struct hmdfs_peer * con)2124 bool get_remote_dentry_file(struct dentry *dentry, struct hmdfs_peer *con)
2125 {
2126 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2127 struct cache_file_node *cfn = NULL;
2128 struct hmdfs_sb_info *sbi = con->sbi;
2129 char *relative_path = NULL;
2130 int err = 0;
2131 struct file *filp = NULL;
2132 struct clearcache_item *item;
2133
2134 if (hmdfs_cache_revalidate(READ_ONCE(con->conn_time), con->device_id,
2135 dentry))
2136 return false;
2137
2138 relative_path = hmdfs_get_dentry_relative_path(dentry);
2139 if (unlikely(!relative_path)) {
2140 hmdfs_err("get relative path failed %d", -ENOMEM);
2141 return false;
2142 }
2143 mutex_lock(&d_info->cache_pull_lock);
2144 if (hmdfs_cache_revalidate(READ_ONCE(con->conn_time), con->device_id,
2145 dentry))
2146 goto out_unlock;
2147
2148 item = hmdfs_find_cache_item(con->device_id, dentry);
2149 if (item) {
2150 remote_file_revalidate_item(dentry, con, item, relative_path);
2151 kref_put(&item->ref, release_cache_item);
2152 goto out_unlock;
2153 }
2154
2155 cfn = find_cfn(sbi, con->cid, relative_path, false);
2156 if (cfn) {
2157 remote_file_revalidate_cfn(dentry, con, cfn, relative_path);
2158 release_cfn(cfn);
2159 goto out_unlock;
2160 }
2161
2162 filp = hmdfs_get_new_dentry_file(con, relative_path, NULL);
2163 if (IS_ERR(filp)) {
2164 err = PTR_ERR(filp);
2165 goto out_unlock;
2166 }
2167
2168 err = hmdfs_add_file_to_cache(dentry, con, filp, relative_path);
2169 if (unlikely(err))
2170 hmdfs_err("add cache list failed devid:%lu err:%d",
2171 (unsigned long)con->device_id, err);
2172 fput(filp);
2173
2174 out_unlock:
2175 mutex_unlock(&d_info->cache_pull_lock);
2176 if (err && err != -ENOENT)
2177 hmdfs_err("readdir failed dev:%lu err:%d",
2178 (unsigned long)con->device_id, err);
2179 kfree(relative_path);
2180 return true;
2181 }
2182
hmdfs_file_type(const char * name)2183 int hmdfs_file_type(const char *name)
2184 {
2185 if (!name)
2186 return -EINVAL;
2187
2188 if (!strcmp(name, CURRENT_DIR) || !strcmp(name, PARENT_DIR))
2189 return HMDFS_TYPE_DOT;
2190
2191 return HMDFS_TYPE_COMMON;
2192 }
2193
hmdfs_find_cache_item(uint64_t dev_id,struct dentry * dentry)2194 struct clearcache_item *hmdfs_find_cache_item(uint64_t dev_id,
2195 struct dentry *dentry)
2196 {
2197 struct clearcache_item *item = NULL;
2198 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2199
2200 if (!d_info)
2201 return NULL;
2202
2203 spin_lock(&d_info->cache_list_lock);
2204 list_for_each_entry(item, &(d_info->cache_list_head), list) {
2205 if (dev_id == item->dev_id) {
2206 kref_get(&item->ref);
2207 spin_unlock(&d_info->cache_list_lock);
2208 return item;
2209 }
2210 }
2211 spin_unlock(&d_info->cache_list_lock);
2212 return NULL;
2213 }
2214
hmdfs_cache_revalidate(unsigned long conn_time,uint64_t dev_id,struct dentry * dentry)2215 bool hmdfs_cache_revalidate(unsigned long conn_time, uint64_t dev_id,
2216 struct dentry *dentry)
2217 {
2218 bool ret = false;
2219 struct clearcache_item *item = NULL;
2220 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2221 unsigned int timeout;
2222
2223 if (!d_info)
2224 return ret;
2225
2226 timeout = hmdfs_sb(dentry->d_sb)->dcache_timeout;
2227 spin_lock(&d_info->cache_list_lock);
2228 list_for_each_entry(item, &(d_info->cache_list_head), list) {
2229 if (dev_id == item->dev_id) {
2230 ret = cache_item_revalidate(conn_time, item->time,
2231 timeout);
2232 break;
2233 }
2234 }
2235 spin_unlock(&d_info->cache_list_lock);
2236 return ret;
2237 }
2238
remove_cache_item(struct clearcache_item * item)2239 void remove_cache_item(struct clearcache_item *item)
2240 {
2241 bool deleted;
2242
2243 spin_lock(&item->d_info->cache_list_lock);
2244 deleted = list_empty(&item->list);
2245 if (!deleted)
2246 list_del_init(&item->list);
2247 spin_unlock(&item->d_info->cache_list_lock);
2248 if (!deleted)
2249 kref_put(&item->ref, release_cache_item);
2250 }
2251
release_cache_item(struct kref * ref)2252 void release_cache_item(struct kref *ref)
2253 {
2254 struct clearcache_item *item =
2255 container_of(ref, struct clearcache_item, ref);
2256
2257 if (item->filp)
2258 fput(item->filp);
2259 kfree(item);
2260 }
2261
hmdfs_remove_cache_filp(struct hmdfs_peer * con,struct dentry * dentry)2262 void hmdfs_remove_cache_filp(struct hmdfs_peer *con, struct dentry *dentry)
2263 {
2264 struct clearcache_item *item = NULL;
2265 struct clearcache_item *item_temp = NULL;
2266 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2267 // struct path *lower_path = NULL;
2268
2269 if (!d_info)
2270 return;
2271
2272 spin_lock(&d_info->cache_list_lock);
2273 list_for_each_entry_safe(item, item_temp, &(d_info->cache_list_head),
2274 list) {
2275 if (con->device_id == item->dev_id) {
2276 list_del_init(&item->list);
2277 spin_unlock(&d_info->cache_list_lock);
2278 cache_file_delete_by_dentry(con, dentry);
2279 kref_put(&item->ref, release_cache_item);
2280 return;
2281 }
2282 }
2283 spin_unlock(&d_info->cache_list_lock);
2284 }
2285
hmdfs_add_cache_list(uint64_t dev_id,struct dentry * dentry,struct file * filp)2286 int hmdfs_add_cache_list(uint64_t dev_id, struct dentry *dentry,
2287 struct file *filp)
2288 {
2289 struct clearcache_item *item = NULL;
2290 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2291
2292 if (!d_info)
2293 return -ENOMEM;
2294
2295 item = kzalloc(sizeof(*item), GFP_KERNEL);
2296 if (!item)
2297 return -ENOMEM;
2298
2299 item->dev_id = dev_id;
2300 item->filp = get_file(filp);
2301 item->time = jiffies;
2302 item->d_info = d_info;
2303 kref_init(&item->ref);
2304 spin_lock(&d_info->cache_list_lock);
2305 list_add_tail(&(item->list), &(d_info->cache_list_head));
2306 spin_unlock(&d_info->cache_list_lock);
2307 return 0;
2308 }
2309
hmdfs_add_remote_cache_list(struct hmdfs_peer * con,const char * dir_path)2310 void hmdfs_add_remote_cache_list(struct hmdfs_peer *con, const char *dir_path)
2311 {
2312 int err = 0;
2313 struct remotecache_item *item = NULL;
2314 struct remotecache_item *item_temp = NULL;
2315 struct path path, root_path;
2316 struct hmdfs_dentry_info *d_info = NULL;
2317
2318 err = kern_path(con->sbi->local_dst, 0, &root_path);
2319 if (err) {
2320 hmdfs_err("kern_path failed err = %d", err);
2321 return;
2322 }
2323
2324 err = vfs_path_lookup(root_path.dentry, root_path.mnt, dir_path, 0,
2325 &path);
2326 if (err)
2327 goto out_put_root;
2328
2329 d_info = hmdfs_d(path.dentry);
2330 if (!d_info) {
2331 err = -EINVAL;
2332 goto out;
2333 }
2334
2335 /* find duplicate con */
2336 mutex_lock(&d_info->remote_cache_list_lock);
2337 list_for_each_entry_safe(item, item_temp,
2338 &(d_info->remote_cache_list_head), list) {
2339 if (item->con->device_id == con->device_id) {
2340 mutex_unlock(&d_info->remote_cache_list_lock);
2341 goto out;
2342 }
2343 }
2344
2345 item = kzalloc(sizeof(*item), GFP_KERNEL);
2346 if (!item) {
2347 err = -ENOMEM;
2348 mutex_unlock(&d_info->remote_cache_list_lock);
2349 goto out;
2350 }
2351
2352 item->con = con;
2353 item->drop_flag = 0;
2354 list_add(&(item->list), &(d_info->remote_cache_list_head));
2355 mutex_unlock(&d_info->remote_cache_list_lock);
2356
2357 out:
2358 path_put(&path);
2359 out_put_root:
2360 path_put(&root_path);
2361 }
2362
hmdfs_drop_remote_cache_dents(struct dentry * dentry)2363 int hmdfs_drop_remote_cache_dents(struct dentry *dentry)
2364 {
2365 struct path lower_path;
2366 struct inode *lower_inode = NULL;
2367 struct remotecache_item *item = NULL;
2368 struct remotecache_item *item_temp = NULL;
2369 struct hmdfs_dentry_info *d_info = NULL;
2370 char *relative_path = NULL;
2371
2372 if (!dentry) {
2373 hmdfs_err("dentry null and return");
2374 return 0;
2375 }
2376
2377 d_info = hmdfs_d(dentry);
2378 if (!d_info) {
2379 hmdfs_err("d_info null and return");
2380 return 0;
2381 }
2382 hmdfs_get_lower_path(dentry, &lower_path);
2383 if (IS_ERR_OR_NULL(lower_path.dentry)) {
2384 hmdfs_put_lower_path(&lower_path);
2385 return 0;
2386 }
2387 lower_inode = d_inode(lower_path.dentry);
2388 hmdfs_put_lower_path(&lower_path);
2389 if (IS_ERR_OR_NULL(lower_inode))
2390 return 0;
2391 /* only for directory */
2392 if (!S_ISDIR(lower_inode->i_mode))
2393 return 0;
2394
2395 relative_path = hmdfs_get_dentry_relative_path(dentry);
2396 if (!relative_path) {
2397 hmdfs_err("get dentry relative path failed");
2398 return 0;
2399 }
2400 mutex_lock(&d_info->remote_cache_list_lock);
2401 list_for_each_entry_safe(item, item_temp,
2402 &(d_info->remote_cache_list_head), list) {
2403 if (item->drop_flag) {
2404 item->drop_flag = 0;
2405 continue;
2406 }
2407 mutex_unlock(&d_info->remote_cache_list_lock);
2408 hmdfs_send_drop_push(item->con, relative_path);
2409 mutex_lock(&d_info->remote_cache_list_lock);
2410 list_del(&item->list);
2411 kfree(item);
2412 }
2413 mutex_unlock(&d_info->remote_cache_list_lock);
2414
2415 kfree(relative_path);
2416 return 0;
2417 }
2418
2419 /* Clear the dentry cache files of target directory */
hmdfs_clear_cache_dents(struct dentry * dentry,bool remove_cache)2420 int hmdfs_clear_cache_dents(struct dentry *dentry, bool remove_cache)
2421 {
2422 struct clearcache_item *item = NULL;
2423 struct clearcache_item *item_temp = NULL;
2424 struct hmdfs_dentry_info *d_info = hmdfs_d(dentry);
2425 char *path = NULL;
2426
2427 if (!d_info)
2428 return 0;
2429
2430 spin_lock(&d_info->cache_list_lock);
2431 list_for_each_entry_safe(item, item_temp, &(d_info->cache_list_head),
2432 list) {
2433 list_del_init(&item->list);
2434 kref_put(&item->ref, release_cache_item);
2435 }
2436 spin_unlock(&d_info->cache_list_lock);
2437
2438 if (!remove_cache)
2439 return 0;
2440
2441 /* it also need confirm that there are no dentryfile_dev*
2442 * under this dentry
2443 */
2444 path = hmdfs_get_dentry_relative_path(dentry);
2445
2446 if (unlikely(!path)) {
2447 hmdfs_err("get relative path failed");
2448 return 0;
2449 }
2450
2451 cache_file_destroy_by_path(hmdfs_sb(dentry->d_sb), path);
2452
2453 kfree(path);
2454 return 0;
2455 }
2456
hmdfs_mark_drop_flag(uint64_t device_id,struct dentry * dentry)2457 void hmdfs_mark_drop_flag(uint64_t device_id, struct dentry *dentry)
2458 {
2459 struct remotecache_item *item = NULL;
2460 struct hmdfs_dentry_info *d_info = NULL;
2461
2462 d_info = hmdfs_d(dentry);
2463 if (!d_info) {
2464 hmdfs_err("d_info null and return");
2465 return;
2466 }
2467
2468 mutex_lock(&d_info->remote_cache_list_lock);
2469 list_for_each_entry(item, &(d_info->remote_cache_list_head), list) {
2470 if (item->con->device_id == device_id) {
2471 item->drop_flag = 1;
2472 break;
2473 }
2474 }
2475 mutex_unlock(&d_info->remote_cache_list_lock);
2476 }
2477
hmdfs_clear_drop_flag(struct dentry * dentry)2478 void hmdfs_clear_drop_flag(struct dentry *dentry)
2479 {
2480 struct remotecache_item *item = NULL;
2481 struct hmdfs_dentry_info *d_info = NULL;
2482
2483 if (!dentry) {
2484 hmdfs_err("dentry null and return");
2485 return;
2486 }
2487
2488 d_info = hmdfs_d(dentry);
2489 if (!d_info) {
2490 hmdfs_err("d_info null and return");
2491 return;
2492 }
2493
2494 mutex_lock(&d_info->remote_cache_list_lock);
2495 list_for_each_entry(item, &(d_info->remote_cache_list_head), list) {
2496 if (item->drop_flag)
2497 item->drop_flag = 0;
2498 }
2499 mutex_unlock(&d_info->remote_cache_list_lock);
2500 }
2501
2502 #define DUSTBIN_SUFFIX ".hwbk"
hmdfs_rename_bak(struct dentry * dentry)2503 static void hmdfs_rename_bak(struct dentry *dentry)
2504 {
2505 struct path lower_path;
2506 struct dentry *lower_parent = NULL;
2507 struct dentry *lower_dentry = NULL;
2508 struct dentry *new_dentry = NULL;
2509 char *name = NULL;
2510 int len = 0;
2511 int err = 0;
2512
2513 hmdfs_get_lower_path(dentry, &lower_path);
2514 lower_dentry = lower_path.dentry;
2515 len = strlen(lower_dentry->d_name.name) + strlen(DUSTBIN_SUFFIX) + 2;
2516 if (len >= NAME_MAX) {
2517 err = -ENAMETOOLONG;
2518 goto put_lower_path;
2519 }
2520
2521 name = kmalloc(len, GFP_KERNEL);
2522 if (!name) {
2523 err = -ENOMEM;
2524 goto put_lower_path;
2525 }
2526
2527 snprintf(name, len, ".%s%s", lower_dentry->d_name.name, DUSTBIN_SUFFIX);
2528 err = mnt_want_write(lower_path.mnt);
2529 if (err) {
2530 hmdfs_info("get write access failed, err %d", err);
2531 goto free_name;
2532 }
2533
2534 lower_parent = lock_parent(lower_dentry);
2535 new_dentry = lookup_one_len(name, lower_parent, strlen(name));
2536 if (IS_ERR(new_dentry)) {
2537 err = PTR_ERR(new_dentry);
2538 hmdfs_info("lookup new dentry failed, err %d", err);
2539 goto unlock_parent;
2540 }
2541
2542 err = vfs_rename(d_inode(lower_parent), lower_dentry,
2543 d_inode(lower_parent), new_dentry, NULL, 0);
2544
2545 dput(new_dentry);
2546 unlock_parent:
2547 unlock_dir(lower_parent);
2548 mnt_drop_write(lower_path.mnt);
2549 free_name:
2550 kfree(name);
2551 put_lower_path:
2552 hmdfs_put_lower_path(&lower_path);
2553
2554 if (err)
2555 hmdfs_err("failed to rename file, err %d", err);
2556 }
2557
hmdfs_root_unlink(uint64_t device_id,struct path * root_path,const char * unlink_dir,const char * unlink_name)2558 int hmdfs_root_unlink(uint64_t device_id, struct path *root_path,
2559 const char *unlink_dir, const char *unlink_name)
2560 {
2561 int err = 0;
2562 struct path path;
2563 struct dentry *child_dentry = NULL;
2564 struct inode *dir = NULL;
2565 struct inode *child_inode = NULL;
2566 kuid_t tmp_uid;
2567
2568 err = vfs_path_lookup(root_path->dentry, root_path->mnt,
2569 unlink_dir, LOOKUP_DIRECTORY, &path);
2570 if (err) {
2571 hmdfs_err("found path failed err = %d", err);
2572 return err;
2573 }
2574 dir = d_inode(path.dentry);
2575 inode_lock_nested(dir, I_MUTEX_PARENT);
2576
2577 child_dentry = lookup_one_len(unlink_name, path.dentry,
2578 strlen(unlink_name));
2579 if (IS_ERR(child_dentry)) {
2580 err = PTR_ERR(child_dentry);
2581 hmdfs_err("lookup_one_len failed, err = %d", err);
2582 goto unlock_out;
2583 }
2584 if (d_is_negative(child_dentry)) {
2585 err = -ENOENT;
2586 dput(child_dentry);
2587 goto unlock_out;
2588 }
2589 child_inode = d_inode(child_dentry);
2590 if (!child_inode)
2591 goto unlock_out;
2592
2593 tmp_uid = hmdfs_override_inode_uid(dir);
2594
2595 hmdfs_mark_drop_flag(device_id, path.dentry);
2596 ihold(child_inode);
2597 err = vfs_unlink(dir, child_dentry, NULL);
2598 /*
2599 * -EOWNERDEAD means we want to put the file in a specail dir instead of
2600 * deleting it, specifically dustbin in phone, so that user can
2601 * recover the deleted images and videos.
2602 */
2603 if (err == -EOWNERDEAD) {
2604 hmdfs_rename_bak(child_dentry);
2605 err = 0;
2606 }
2607 if (err)
2608 hmdfs_err("unlink path failed err = %d", err);
2609 hmdfs_revert_inode_uid(dir, tmp_uid);
2610 dput(child_dentry);
2611
2612 unlock_out:
2613 inode_unlock(dir);
2614 if (child_inode)
2615 iput(child_inode);
2616 path_put(&path);
2617 return err;
2618 }
2619
hmdfs_root_mkdir(uint64_t device_id,const char * local_dst_path,const char * mkdir_dir,const char * mkdir_name,umode_t mode)2620 struct dentry *hmdfs_root_mkdir(uint64_t device_id, const char *local_dst_path,
2621 const char *mkdir_dir, const char *mkdir_name,
2622 umode_t mode)
2623 {
2624 int err;
2625 struct path path;
2626 struct dentry *child_dentry = NULL;
2627 struct dentry *ret = NULL;
2628 char *mkdir_path = NULL;
2629 char *mkdir_abs_path = NULL;
2630
2631 mkdir_path = hmdfs_connect_path(mkdir_dir, mkdir_name);
2632 if (!mkdir_path)
2633 return ERR_PTR(-EACCES);
2634
2635 mkdir_abs_path =
2636 hmdfs_get_dentry_absolute_path(local_dst_path, mkdir_path);
2637 if (!mkdir_abs_path) {
2638 ret = ERR_PTR(-ENOMEM);
2639 goto out;
2640 }
2641
2642 child_dentry = kern_path_create(AT_FDCWD, mkdir_abs_path,
2643 &path, LOOKUP_DIRECTORY);
2644 if (IS_ERR(child_dentry)) {
2645 ret = child_dentry;
2646 goto out;
2647 }
2648
2649 hmdfs_mark_drop_flag(device_id, child_dentry->d_parent);
2650 err = vfs_mkdir(d_inode(path.dentry), child_dentry, mode);
2651 if (err) {
2652 hmdfs_err("mkdir failed! err=%d", err);
2653 ret = ERR_PTR(err);
2654 goto out_put;
2655 }
2656 ret = dget(child_dentry);
2657 out_put:
2658 done_path_create(&path, child_dentry);
2659 out:
2660 kfree(mkdir_path);
2661 kfree(mkdir_abs_path);
2662 return ret;
2663 }
2664
hmdfs_root_create(uint64_t device_id,const char * local_dst_path,const char * create_dir,const char * create_name,umode_t mode,bool want_excl)2665 struct dentry *hmdfs_root_create(uint64_t device_id, const char *local_dst_path,
2666 const char *create_dir,
2667 const char *create_name,
2668 umode_t mode, bool want_excl)
2669 {
2670 int err;
2671 struct path path;
2672 struct dentry *child_dentry = NULL;
2673 struct dentry *ret = NULL;
2674 char *create_path = NULL;
2675 char *create_abs_path = NULL;
2676
2677 create_path = hmdfs_connect_path(create_dir, create_name);
2678 if (!create_path)
2679 return ERR_PTR(-EACCES);
2680
2681 create_abs_path =
2682 hmdfs_get_dentry_absolute_path(local_dst_path, create_path);
2683 if (!create_abs_path) {
2684 ret = ERR_PTR(-ENOMEM);
2685 goto out;
2686 }
2687
2688 child_dentry = kern_path_create(AT_FDCWD, create_abs_path, &path, 0);
2689
2690 if (IS_ERR(child_dentry)) {
2691 ret = child_dentry;
2692 goto out;
2693 }
2694 hmdfs_mark_drop_flag(device_id, child_dentry->d_parent);
2695 err = vfs_create(d_inode(path.dentry), child_dentry, mode, want_excl);
2696 if (err) {
2697 hmdfs_err("path create failed! err=%d", err);
2698 ret = ERR_PTR(err);
2699 goto out_put;
2700 }
2701 ret = dget(child_dentry);
2702 out_put:
2703 done_path_create(&path, child_dentry);
2704 out:
2705 kfree(create_path);
2706 kfree(create_abs_path);
2707 return ret;
2708 }
2709
hmdfs_root_rmdir(uint64_t device_id,struct path * root_path,const char * rmdir_dir,const char * rmdir_name)2710 int hmdfs_root_rmdir(uint64_t device_id, struct path *root_path,
2711 const char *rmdir_dir, const char *rmdir_name)
2712 {
2713 int err = 0;
2714 struct path path;
2715 struct dentry *child_dentry = NULL;
2716 struct inode *dir = NULL;
2717
2718 err = vfs_path_lookup(root_path->dentry, root_path->mnt,
2719 rmdir_dir, LOOKUP_DIRECTORY, &path);
2720 if (err) {
2721 hmdfs_err("found path failed err = %d", err);
2722 return err;
2723 }
2724 dir = d_inode(path.dentry);
2725 inode_lock_nested(dir, I_MUTEX_PARENT);
2726
2727 child_dentry = lookup_one_len(rmdir_name, path.dentry,
2728 strlen(rmdir_name));
2729 if (IS_ERR(child_dentry)) {
2730 err = PTR_ERR(child_dentry);
2731 hmdfs_err("lookup_one_len failed, err = %d", err);
2732 goto unlock_out;
2733 }
2734 if (d_is_negative(child_dentry)) {
2735 err = -ENOENT;
2736 dput(child_dentry);
2737 goto unlock_out;
2738 }
2739
2740 hmdfs_mark_drop_flag(device_id, path.dentry);
2741 err = vfs_rmdir(dir, child_dentry);
2742 if (err)
2743 hmdfs_err("rmdir failed err = %d", err);
2744 dput(child_dentry);
2745
2746 unlock_out:
2747 inode_unlock(dir);
2748 path_put(&path);
2749 return err;
2750 }
2751
hmdfs_root_rename(struct hmdfs_sb_info * sbi,uint64_t device_id,const char * oldpath,const char * oldname,const char * newpath,const char * newname,unsigned int flags)2752 int hmdfs_root_rename(struct hmdfs_sb_info *sbi, uint64_t device_id,
2753 const char *oldpath, const char *oldname,
2754 const char *newpath, const char *newname,
2755 unsigned int flags)
2756 {
2757 int err = 0;
2758 struct path path_dst;
2759 struct path path_old;
2760 struct path path_new;
2761 struct dentry *trap = NULL;
2762 struct dentry *old_dentry = NULL;
2763 struct dentry *new_dentry = NULL;
2764
2765 err = kern_path(sbi->local_dst, 0, &path_dst);
2766 if (err) {
2767 hmdfs_err("kern_path for local dst failed %d", err);
2768 return err;
2769 }
2770
2771 err = vfs_path_lookup(path_dst.dentry, path_dst.mnt, oldpath, 0,
2772 &path_old);
2773 if (err) {
2774 hmdfs_info("lookup oldpath from local_dst failed, err %d", err);
2775 goto put_path_dst;
2776 }
2777
2778 err = vfs_path_lookup(path_dst.dentry, path_dst.mnt, newpath, 0,
2779 &path_new);
2780 if (err) {
2781 hmdfs_info("lookup newpath from local_dst failed, err %d", err);
2782 goto put_path_old;
2783 }
2784
2785 err = mnt_want_write(path_dst.mnt);
2786 if (err) {
2787 hmdfs_info("get write access failed for local_dst, err %d",
2788 err);
2789 goto put_path_new;
2790 }
2791
2792 trap = lock_rename(path_new.dentry, path_old.dentry);
2793
2794 old_dentry = lookup_one_len(oldname, path_old.dentry, strlen(oldname));
2795 if (IS_ERR(old_dentry)) {
2796 err = PTR_ERR(old_dentry);
2797 hmdfs_info("lookup old dentry failed, err %d", err);
2798 goto unlock;
2799 }
2800
2801 /* source should not be ancestor of target */
2802 if (old_dentry == trap) {
2803 err = -EINVAL;
2804 goto put_old_dentry;
2805 }
2806
2807 new_dentry = lookup_one_len(newname, path_new.dentry, strlen(newname));
2808 if (IS_ERR(new_dentry)) {
2809 err = PTR_ERR(new_dentry);
2810 hmdfs_info("lookup new dentry failed, err %d", err);
2811 goto put_old_dentry;
2812 }
2813
2814 /*
2815 * Exchange rename is not supported, thus target should not be an
2816 * ancestor of source.
2817 */
2818 if (trap == new_dentry) {
2819 err = -ENOTEMPTY;
2820 goto put_new_dentry;
2821 }
2822
2823 if (d_is_positive(new_dentry) && (flags & RENAME_NOREPLACE)) {
2824 err = -EEXIST;
2825 goto put_new_dentry;
2826 }
2827
2828 hmdfs_mark_drop_flag(device_id, path_old.dentry);
2829 if (path_old.dentry != path_new.dentry)
2830 hmdfs_mark_drop_flag(device_id, path_new.dentry);
2831
2832 err = vfs_rename(d_inode(path_old.dentry), old_dentry,
2833 d_inode(path_new.dentry), new_dentry, NULL, 0);
2834
2835 put_new_dentry:
2836 dput(new_dentry);
2837 put_old_dentry:
2838 dput(old_dentry);
2839 unlock:
2840 unlock_rename(path_new.dentry, path_old.dentry);
2841 mnt_drop_write(path_dst.mnt);
2842 put_path_new:
2843 path_put(&path_new);
2844 put_path_old:
2845 path_put(&path_old);
2846 put_path_dst:
2847 path_put(&path_dst);
2848
2849 return err;
2850 }
2851
hmdfs_get_path_in_sb(struct super_block * sb,const char * name,unsigned int flags,struct path * path)2852 int hmdfs_get_path_in_sb(struct super_block *sb, const char *name,
2853 unsigned int flags, struct path *path)
2854 {
2855 int err;
2856
2857 err = kern_path(name, flags, path);
2858 if (err) {
2859 hmdfs_err("can't get %s %d\n", name, err);
2860 return err;
2861 }
2862
2863 /* should ensure the path is belong sb */
2864 if (path->dentry->d_sb != sb) {
2865 err = -EINVAL;
2866 hmdfs_err("Wrong sb: %s on %s", name,
2867 path->dentry->d_sb->s_type->name);
2868 path_put(path);
2869 }
2870
2871 return err;
2872 }
2873