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