]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - fs/aufs/dirren.c
x86/mm: Use WRITE_ONCE() when setting PTEs
[mirror_ubuntu-bionic-kernel.git] / fs / aufs / dirren.c
1 /*
2 * Copyright (C) 2017 Junjiro R. Okajima
3 *
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * special handling in renaming a directoy
20 * in order to support looking-up the before-renamed name on the lower readonly
21 * branches
22 */
23
24 #include <linux/byteorder/generic.h>
25 #include "aufs.h"
26
27 static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent)
28 {
29 int idx;
30
31 idx = au_dr_ihash(ent->dr_h_ino);
32 au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx);
33 }
34
35 static int au_dr_hino_test_empty(struct au_dr_br *dr)
36 {
37 int ret, i;
38 struct hlist_bl_head *hbl;
39
40 ret = 1;
41 for (i = 0; ret && i < AuDirren_NHASH; i++) {
42 hbl = dr->dr_h_ino + i;
43 hlist_bl_lock(hbl);
44 ret &= hlist_bl_empty(hbl);
45 hlist_bl_unlock(hbl);
46 }
47
48 return ret;
49 }
50
51 static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino)
52 {
53 struct au_dr_hino *found, *ent;
54 struct hlist_bl_head *hbl;
55 struct hlist_bl_node *pos;
56 int idx;
57
58 found = NULL;
59 idx = au_dr_ihash(ino);
60 hbl = dr->dr_h_ino + idx;
61 hlist_bl_lock(hbl);
62 hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
63 if (ent->dr_h_ino == ino) {
64 found = ent;
65 break;
66 }
67 hlist_bl_unlock(hbl);
68
69 return found;
70 }
71
72 int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino,
73 struct au_dr_hino *add_ent)
74 {
75 int found, idx;
76 struct hlist_bl_head *hbl;
77 struct hlist_bl_node *pos;
78 struct au_dr_hino *ent;
79
80 found = 0;
81 idx = au_dr_ihash(ino);
82 hbl = dr->dr_h_ino + idx;
83 #if 0
84 {
85 struct hlist_bl_node *tmp;
86
87 hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
88 AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino);
89 }
90 #endif
91 hlist_bl_lock(hbl);
92 hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
93 if (ent->dr_h_ino == ino) {
94 found = 1;
95 break;
96 }
97 if (!found && add_ent)
98 hlist_bl_add_head(&add_ent->dr_hnode, hbl);
99 hlist_bl_unlock(hbl);
100
101 if (!found && add_ent)
102 AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino);
103
104 return found;
105 }
106
107 void au_dr_hino_free(struct au_dr_br *dr)
108 {
109 int i;
110 struct hlist_bl_head *hbl;
111 struct hlist_bl_node *pos, *tmp;
112 struct au_dr_hino *ent;
113
114 /* SiMustWriteLock(sb); */
115
116 for (i = 0; i < AuDirren_NHASH; i++) {
117 hbl = dr->dr_h_ino + i;
118 /* no spinlock since sbinfo must be write-locked */
119 hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
120 kfree(ent);
121 INIT_HLIST_BL_HEAD(hbl);
122 }
123 }
124
125 /* returns the number of inodes or an error */
126 static int au_dr_hino_store(struct super_block *sb, struct au_branch *br,
127 struct file *hinofile)
128 {
129 int err, i;
130 ssize_t ssz;
131 loff_t pos, oldsize;
132 __be64 u64;
133 struct inode *hinoinode;
134 struct hlist_bl_head *hbl;
135 struct hlist_bl_node *n1, *n2;
136 struct au_dr_hino *ent;
137
138 SiMustWriteLock(sb);
139 AuDebugOn(!au_br_writable(br->br_perm));
140
141 hinoinode = file_inode(hinofile);
142 oldsize = i_size_read(hinoinode);
143
144 err = 0;
145 pos = 0;
146 hbl = br->br_dirren.dr_h_ino;
147 for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) {
148 /* no bit-lock since sbinfo must be write-locked */
149 hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) {
150 AuDbg("hi%llu, %pD2\n",
151 (unsigned long long)ent->dr_h_ino, hinofile);
152 u64 = cpu_to_be64(ent->dr_h_ino);
153 ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos);
154 if (ssz == sizeof(u64))
155 continue;
156
157 /* write error */
158 pr_err("ssz %zd, %pD2\n", ssz, hinofile);
159 err = -ENOSPC;
160 if (ssz < 0)
161 err = ssz;
162 break;
163 }
164 }
165 /* regardless the error */
166 if (pos < oldsize) {
167 err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile);
168 AuTraceErr(err);
169 }
170
171 AuTraceErr(err);
172 return err;
173 }
174
175 static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile)
176 {
177 int err, hidx;
178 ssize_t ssz;
179 size_t sz, n;
180 loff_t pos;
181 uint64_t u64;
182 struct au_dr_hino *ent;
183 struct inode *hinoinode;
184 struct hlist_bl_head *hbl;
185
186 err = 0;
187 pos = 0;
188 hbl = dr->dr_h_ino;
189 hinoinode = file_inode(hinofile);
190 sz = i_size_read(hinoinode);
191 AuDebugOn(sz % sizeof(u64));
192 n = sz / sizeof(u64);
193 while (n--) {
194 ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos);
195 if (unlikely(ssz != sizeof(u64))) {
196 pr_err("ssz %zd, %pD2\n", ssz, hinofile);
197 err = -EINVAL;
198 if (ssz < 0)
199 err = ssz;
200 goto out_free;
201 }
202
203 ent = kmalloc(sizeof(*ent), GFP_NOFS);
204 if (!ent) {
205 err = -ENOMEM;
206 AuTraceErr(err);
207 goto out_free;
208 }
209 ent->dr_h_ino = be64_to_cpu((__force __be64)u64);
210 AuDbg("hi%llu, %pD2\n",
211 (unsigned long long)ent->dr_h_ino, hinofile);
212 hidx = au_dr_ihash(ent->dr_h_ino);
213 au_hbl_add(&ent->dr_hnode, hbl + hidx);
214 }
215 goto out; /* success */
216
217 out_free:
218 au_dr_hino_free(dr);
219 out:
220 AuTraceErr(err);
221 return err;
222 }
223
224 /*
225 * @bindex/@br is a switch to distinguish whether suspending hnotify or not.
226 * @path is a switch to distinguish load and store.
227 */
228 static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex,
229 struct au_branch *br, const struct path *path)
230 {
231 int err, flags;
232 unsigned char load, suspend;
233 struct file *hinofile;
234 struct au_hinode *hdir;
235 struct inode *dir, *delegated;
236 struct path hinopath;
237 struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO,
238 sizeof(AUFS_WH_DR_BRHINO) - 1);
239
240 AuDebugOn(bindex < 0 && !br);
241 AuDebugOn(bindex >= 0 && br);
242
243 err = -EINVAL;
244 suspend = !br;
245 if (suspend)
246 br = au_sbr(sb, bindex);
247 load = !!path;
248 if (!load) {
249 path = &br->br_path;
250 AuDebugOn(!au_br_writable(br->br_perm));
251 if (unlikely(!au_br_writable(br->br_perm)))
252 goto out;
253 }
254
255 hdir = NULL;
256 if (suspend) {
257 dir = d_inode(sb->s_root);
258 hdir = au_hinode(au_ii(dir), bindex);
259 dir = hdir->hi_inode;
260 au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
261 } else {
262 dir = d_inode(path->dentry);
263 inode_lock_nested(dir, AuLsc_I_CHILD);
264 }
265 hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry);
266 err = PTR_ERR(hinopath.dentry);
267 if (IS_ERR(hinopath.dentry))
268 goto out_unlock;
269
270 err = 0;
271 flags = O_RDONLY;
272 if (load) {
273 if (d_is_negative(hinopath.dentry))
274 goto out_dput; /* success */
275 } else {
276 if (au_dr_hino_test_empty(&br->br_dirren)) {
277 if (d_is_positive(hinopath.dentry)) {
278 delegated = NULL;
279 err = vfsub_unlink(dir, &hinopath, &delegated,
280 /*force*/0);
281 AuTraceErr(err);
282 if (unlikely(err))
283 pr_err("ignored err %d, %pd2\n",
284 err, hinopath.dentry);
285 if (unlikely(err == -EWOULDBLOCK))
286 iput(delegated);
287 err = 0;
288 }
289 goto out_dput;
290 } else if (!d_is_positive(hinopath.dentry)) {
291 err = vfsub_create(dir, &hinopath, 0600,
292 /*want_excl*/false);
293 AuTraceErr(err);
294 if (unlikely(err))
295 goto out_dput;
296 }
297 flags = O_WRONLY;
298 }
299 hinopath.mnt = path->mnt;
300 hinofile = vfsub_dentry_open(&hinopath, flags);
301 if (suspend)
302 au_hn_inode_unlock(hdir);
303 else
304 inode_unlock(dir);
305 dput(hinopath.dentry);
306 AuTraceErrPtr(hinofile);
307 if (IS_ERR(hinofile)) {
308 err = PTR_ERR(hinofile);
309 goto out;
310 }
311
312 if (load)
313 err = au_dr_hino_load(&br->br_dirren, hinofile);
314 else
315 err = au_dr_hino_store(sb, br, hinofile);
316 fput(hinofile);
317 goto out;
318
319 out_dput:
320 dput(hinopath.dentry);
321 out_unlock:
322 if (suspend)
323 au_hn_inode_unlock(hdir);
324 else
325 inode_unlock(dir);
326 out:
327 AuTraceErr(err);
328 return err;
329 }
330
331 /* ---------------------------------------------------------------------- */
332
333 static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
334 {
335 int err;
336 struct kstatfs kstfs;
337 dev_t dev;
338 struct dentry *dentry;
339 struct super_block *sb;
340
341 err = vfs_statfs((void *)path, &kstfs);
342 AuTraceErr(err);
343 if (unlikely(err))
344 goto out;
345
346 /* todo: support for UUID */
347
348 if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
349 brid->type = AuBrid_FSID;
350 brid->fsid = kstfs.f_fsid;
351 } else {
352 dentry = path->dentry;
353 sb = dentry->d_sb;
354 dev = sb->s_dev;
355 if (dev) {
356 brid->type = AuBrid_DEV;
357 brid->dev = dev;
358 }
359 }
360
361 out:
362 return err;
363 }
364
365 int au_dr_br_init(struct super_block *sb, struct au_branch *br,
366 const struct path *path)
367 {
368 int err, i;
369 struct au_dr_br *dr;
370 struct hlist_bl_head *hbl;
371
372 dr = &br->br_dirren;
373 hbl = dr->dr_h_ino;
374 for (i = 0; i < AuDirren_NHASH; i++, hbl++)
375 INIT_HLIST_BL_HEAD(hbl);
376
377 err = au_dr_brid_init(&dr->dr_brid, path);
378 if (unlikely(err))
379 goto out;
380
381 if (au_opt_test(au_mntflags(sb), DIRREN))
382 err = au_dr_hino(sb, /*bindex*/-1, br, path);
383
384 out:
385 AuTraceErr(err);
386 return err;
387 }
388
389 int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
390 {
391 int err;
392
393 err = 0;
394 if (au_br_writable(br->br_perm))
395 err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL);
396 if (!err)
397 au_dr_hino_free(&br->br_dirren);
398
399 return err;
400 }
401
402 /* ---------------------------------------------------------------------- */
403
404 static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
405 char *buf, size_t sz)
406 {
407 int err;
408 unsigned int major, minor;
409 char *p;
410
411 p = buf;
412 err = snprintf(p, sz, "%d_", brid->type);
413 AuDebugOn(err > sz);
414 p += err;
415 sz -= err;
416 switch (brid->type) {
417 case AuBrid_Unset:
418 return -EINVAL;
419 case AuBrid_UUID:
420 err = snprintf(p, sz, "%pU", brid->uuid.b);
421 break;
422 case AuBrid_FSID:
423 err = snprintf(p, sz, "%08x-%08x",
424 brid->fsid.val[0], brid->fsid.val[1]);
425 break;
426 case AuBrid_DEV:
427 major = MAJOR(brid->dev);
428 minor = MINOR(brid->dev);
429 if (major <= 0xff && minor <= 0xff)
430 err = snprintf(p, sz, "%02x%02x", major, minor);
431 else
432 err = snprintf(p, sz, "%03x:%05x", major, minor);
433 break;
434 }
435 AuDebugOn(err > sz);
436 p += err;
437 sz -= err;
438 err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
439 AuDebugOn(err > sz);
440 p += err;
441 sz -= err;
442
443 return p - buf;
444 }
445
446 static int au_drinfo_name(struct au_branch *br, char *name, int len)
447 {
448 int rlen;
449 struct dentry *br_dentry;
450 struct inode *br_inode;
451
452 br_dentry = au_br_dentry(br);
453 br_inode = d_inode(br_dentry);
454 rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len);
455 AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ);
456 AuDebugOn(rlen > len);
457
458 return rlen;
459 }
460
461 /* ---------------------------------------------------------------------- */
462
463 /*
464 * from the given @h_dentry, construct drinfo at @*fdata.
465 * when the size of @*fdata is not enough, reallocate and return new @fdata and
466 * @allocated.
467 */
468 static int au_drinfo_construct(struct au_drinfo_fdata **fdata,
469 struct dentry *h_dentry,
470 unsigned char *allocated)
471 {
472 int err, v;
473 struct au_drinfo_fdata *f, *p;
474 struct au_drinfo *drinfo;
475 struct inode *h_inode;
476 struct qstr *qname;
477
478 err = 0;
479 f = *fdata;
480 h_inode = d_inode(h_dentry);
481 qname = &h_dentry->d_name;
482 drinfo = &f->drinfo;
483 drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino);
484 drinfo->oldnamelen = qname->len;
485 if (*allocated < sizeof(*f) + qname->len) {
486 v = roundup_pow_of_two(*allocated + qname->len);
487 p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0);
488 if (unlikely(!p)) {
489 err = -ENOMEM;
490 AuTraceErr(err);
491 goto out;
492 }
493 f = p;
494 *fdata = f;
495 *allocated = v;
496 drinfo = &f->drinfo;
497 }
498 memcpy(drinfo->oldname, qname->name, qname->len);
499 AuDbg("i%llu, %.*s\n",
500 be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen,
501 drinfo->oldname);
502
503 out:
504 AuTraceErr(err);
505 return err;
506 }
507
508 /* callers have to free the return value */
509 static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino)
510 {
511 struct au_drinfo *ret, *drinfo;
512 struct au_drinfo_fdata fdata;
513 int len;
514 loff_t pos;
515 ssize_t ssz;
516
517 ret = ERR_PTR(-EIO);
518 pos = 0;
519 ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos);
520 if (unlikely(ssz != sizeof(fdata))) {
521 AuIOErr("ssz %zd, %u, %pD2\n",
522 ssz, (unsigned int)sizeof(fdata), file);
523 goto out;
524 }
525
526 fdata.magic = ntohl((__force __be32)fdata.magic);
527 switch (fdata.magic) {
528 case AUFS_DRINFO_MAGIC_V1:
529 break;
530 default:
531 AuIOErr("magic-num 0x%x, 0x%x, %pD2\n",
532 fdata.magic, AUFS_DRINFO_MAGIC_V1, file);
533 goto out;
534 }
535
536 drinfo = &fdata.drinfo;
537 len = drinfo->oldnamelen;
538 if (!len) {
539 AuIOErr("broken drinfo %pD2\n", file);
540 goto out;
541 }
542
543 ret = NULL;
544 drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino);
545 if (unlikely(h_ino && drinfo->ino != h_ino)) {
546 AuDbg("ignored i%llu, i%llu, %pD2\n",
547 (unsigned long long)drinfo->ino,
548 (unsigned long long)h_ino, file);
549 goto out; /* success */
550 }
551
552 ret = kmalloc(sizeof(*ret) + len, GFP_NOFS);
553 if (unlikely(!ret)) {
554 ret = ERR_PTR(-ENOMEM);
555 AuTraceErrPtr(ret);
556 goto out;
557 }
558
559 *ret = *drinfo;
560 ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos);
561 if (unlikely(ssz != len)) {
562 kfree(ret);
563 ret = ERR_PTR(-EIO);
564 AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file);
565 goto out;
566 }
567
568 AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname);
569
570 out:
571 return ret;
572 }
573
574 /* ---------------------------------------------------------------------- */
575
576 /* in order to be revertible */
577 struct au_drinfo_rev_elm {
578 int created;
579 struct dentry *info_dentry;
580 struct au_drinfo *info_last;
581 };
582
583 struct au_drinfo_rev {
584 unsigned char already;
585 aufs_bindex_t nelm;
586 struct au_drinfo_rev_elm elm[0];
587 };
588
589 /* todo: isn't it too large? */
590 struct au_drinfo_store {
591 struct path h_ppath;
592 struct dentry *h_dentry;
593 struct au_drinfo_fdata *fdata;
594 char *infoname; /* inside of whname, just after PFX */
595 char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ];
596 aufs_bindex_t btgt, btail;
597 unsigned char no_sio,
598 allocated, /* current size of *fdata */
599 infonamelen, /* room size for p */
600 whnamelen, /* length of the genarated name */
601 renameback; /* renamed back */
602 };
603
604 /* on rename(2) error, the caller should revert it using @elm */
605 static int au_drinfo_do_store(struct au_drinfo_store *w,
606 struct au_drinfo_rev_elm *elm)
607 {
608 int err, len;
609 ssize_t ssz;
610 loff_t pos;
611 struct path infopath = {
612 .mnt = w->h_ppath.mnt
613 };
614 struct inode *h_dir, *h_inode, *delegated;
615 struct file *infofile;
616 struct qstr *qname;
617
618 AuDebugOn(elm
619 && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm)));
620
621 infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry,
622 w->whnamelen);
623 AuTraceErrPtr(infopath.dentry);
624 if (IS_ERR(infopath.dentry)) {
625 err = PTR_ERR(infopath.dentry);
626 goto out;
627 }
628
629 err = 0;
630 h_dir = d_inode(w->h_ppath.dentry);
631 if (elm && d_is_negative(infopath.dentry)) {
632 err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true);
633 AuTraceErr(err);
634 if (unlikely(err))
635 goto out_dput;
636 elm->created = 1;
637 elm->info_dentry = dget(infopath.dentry);
638 }
639
640 infofile = vfsub_dentry_open(&infopath, O_RDWR);
641 AuTraceErrPtr(infofile);
642 if (IS_ERR(infofile)) {
643 err = PTR_ERR(infofile);
644 goto out_dput;
645 }
646
647 h_inode = d_inode(infopath.dentry);
648 if (elm && i_size_read(h_inode)) {
649 h_inode = d_inode(w->h_dentry);
650 elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino);
651 AuTraceErrPtr(elm->info_last);
652 if (IS_ERR(elm->info_last)) {
653 err = PTR_ERR(elm->info_last);
654 elm->info_last = NULL;
655 AuDebugOn(elm->info_dentry);
656 goto out_fput;
657 }
658 }
659
660 if (elm && w->renameback) {
661 delegated = NULL;
662 err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0);
663 AuTraceErr(err);
664 if (unlikely(err == -EWOULDBLOCK))
665 iput(delegated);
666 goto out_fput;
667 }
668
669 pos = 0;
670 qname = &w->h_dentry->d_name;
671 len = sizeof(*w->fdata) + qname->len;
672 if (!elm)
673 len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen;
674 ssz = vfsub_write_k(infofile, w->fdata, len, &pos);
675 if (ssz == len) {
676 AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino,
677 w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname);
678 goto out_fput; /* success */
679 } else {
680 err = -EIO;
681 if (ssz < 0)
682 err = ssz;
683 /* the caller should revert it using @elm */
684 }
685
686 out_fput:
687 fput(infofile);
688 out_dput:
689 dput(infopath.dentry);
690 out:
691 AuTraceErr(err);
692 return err;
693 }
694
695 struct au_call_drinfo_do_store_args {
696 int *errp;
697 struct au_drinfo_store *w;
698 struct au_drinfo_rev_elm *elm;
699 };
700
701 static void au_call_drinfo_do_store(void *args)
702 {
703 struct au_call_drinfo_do_store_args *a = args;
704
705 *a->errp = au_drinfo_do_store(a->w, a->elm);
706 }
707
708 static int au_drinfo_store_sio(struct au_drinfo_store *w,
709 struct au_drinfo_rev_elm *elm)
710 {
711 int err, wkq_err;
712
713 if (w->no_sio)
714 err = au_drinfo_do_store(w, elm);
715 else {
716 struct au_call_drinfo_do_store_args a = {
717 .errp = &err,
718 .w = w,
719 .elm = elm
720 };
721 wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a);
722 if (unlikely(wkq_err))
723 err = wkq_err;
724 }
725 AuTraceErr(err);
726
727 return err;
728 }
729
730 static int au_drinfo_store_work_init(struct au_drinfo_store *w,
731 aufs_bindex_t btgt)
732 {
733 int err;
734
735 memset(w, 0, sizeof(*w));
736 w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40);
737 strcpy(w->whname, AUFS_WH_DR_INFO_PFX);
738 w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1;
739 w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX);
740 w->btgt = btgt;
741 w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
742
743 err = -ENOMEM;
744 w->fdata = kcalloc(1, w->allocated, GFP_NOFS);
745 if (unlikely(!w->fdata)) {
746 AuTraceErr(err);
747 goto out;
748 }
749 w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1);
750 err = 0;
751
752 out:
753 return err;
754 }
755
756 static void au_drinfo_store_work_fin(struct au_drinfo_store *w)
757 {
758 kfree(w->fdata);
759 }
760
761 static void au_drinfo_store_rev(struct au_drinfo_rev *rev,
762 struct au_drinfo_store *w)
763 {
764 struct au_drinfo_rev_elm *elm;
765 struct inode *h_dir, *delegated;
766 int err, nelm;
767 struct path infopath = {
768 .mnt = w->h_ppath.mnt
769 };
770
771 h_dir = d_inode(w->h_ppath.dentry);
772 IMustLock(h_dir);
773
774 err = 0;
775 elm = rev->elm;
776 for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
777 AuDebugOn(elm->created && elm->info_last);
778 if (elm->created) {
779 AuDbg("here\n");
780 delegated = NULL;
781 infopath.dentry = elm->info_dentry;
782 err = vfsub_unlink(h_dir, &infopath, &delegated,
783 !w->no_sio);
784 AuTraceErr(err);
785 if (unlikely(err == -EWOULDBLOCK))
786 iput(delegated);
787 dput(elm->info_dentry);
788 } else if (elm->info_last) {
789 AuDbg("here\n");
790 w->fdata->drinfo = *elm->info_last;
791 memcpy(w->fdata->drinfo.oldname,
792 elm->info_last->oldname,
793 elm->info_last->oldnamelen);
794 err = au_drinfo_store_sio(w, /*elm*/NULL);
795 kfree(elm->info_last);
796 }
797 if (unlikely(err))
798 AuIOErr("%d, %s\n", err, w->whname);
799 /* go on even if err */
800 }
801 }
802
803 /* caller has to call au_dr_rename_fin() later */
804 static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt,
805 struct qstr *dst_name, void *_rev)
806 {
807 int err, sz, nelm;
808 aufs_bindex_t bindex, btail;
809 struct au_drinfo_store work;
810 struct au_drinfo_rev *rev, **p;
811 struct au_drinfo_rev_elm *elm;
812 struct super_block *sb;
813 struct au_branch *br;
814 struct au_hinode *hdir;
815
816 err = au_drinfo_store_work_init(&work, btgt);
817 AuTraceErr(err);
818 if (unlikely(err))
819 goto out;
820
821 err = -ENOMEM;
822 btail = au_dbtaildir(dentry);
823 nelm = btail - btgt;
824 sz = sizeof(*rev) + sizeof(*elm) * nelm;
825 rev = kcalloc(1, sz, GFP_NOFS);
826 if (unlikely(!rev)) {
827 AuTraceErr(err);
828 goto out_args;
829 }
830 rev->nelm = nelm;
831 elm = rev->elm;
832 p = _rev;
833 *p = rev;
834
835 err = 0;
836 sb = dentry->d_sb;
837 work.h_ppath.dentry = au_h_dptr(dentry, btgt);
838 work.h_ppath.mnt = au_sbr_mnt(sb, btgt);
839 hdir = au_hi(d_inode(dentry), btgt);
840 au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
841 for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) {
842 work.h_dentry = au_h_dptr(dentry, bindex);
843 if (!work.h_dentry)
844 continue;
845
846 err = au_drinfo_construct(&work.fdata, work.h_dentry,
847 &work.allocated);
848 AuTraceErr(err);
849 if (unlikely(err))
850 break;
851
852 work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name);
853 br = au_sbr(sb, bindex);
854 work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
855 work.whnamelen += au_drinfo_name(br, work.infoname,
856 work.infonamelen);
857 AuDbg("whname %.*s, i%llu, %.*s\n",
858 work.whnamelen, work.whname,
859 be64_to_cpu((__force __be64)work.fdata->drinfo.ino),
860 work.fdata->drinfo.oldnamelen,
861 work.fdata->drinfo.oldname);
862
863 err = au_drinfo_store_sio(&work, elm);
864 AuTraceErr(err);
865 if (unlikely(err))
866 break;
867 }
868 if (unlikely(err)) {
869 /* revert all drinfo */
870 au_drinfo_store_rev(rev, &work);
871 kfree(rev);
872 *p = NULL;
873 }
874 au_hn_inode_unlock(hdir);
875
876 out_args:
877 au_drinfo_store_work_fin(&work);
878 out:
879 return err;
880 }
881
882 /* ---------------------------------------------------------------------- */
883
884 int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
885 struct qstr *dst_name, void *_rev)
886 {
887 int err, already;
888 ino_t ino;
889 struct super_block *sb;
890 struct au_branch *br;
891 struct au_dr_br *dr;
892 struct dentry *h_dentry;
893 struct inode *h_inode;
894 struct au_dr_hino *ent;
895 struct au_drinfo_rev *rev, **p;
896
897 AuDbg("bindex %d\n", bindex);
898
899 err = -ENOMEM;
900 ent = kmalloc(sizeof(*ent), GFP_NOFS);
901 if (unlikely(!ent))
902 goto out;
903
904 sb = src->d_sb;
905 br = au_sbr(sb, bindex);
906 dr = &br->br_dirren;
907 h_dentry = au_h_dptr(src, bindex);
908 h_inode = d_inode(h_dentry);
909 ino = h_inode->i_ino;
910 ent->dr_h_ino = ino;
911 already = au_dr_hino_test_add(dr, ino, ent);
912 AuDbg("b%d, hi%llu, already %d\n",
913 bindex, (unsigned long long)ino, already);
914
915 err = au_drinfo_store(src, bindex, dst_name, _rev);
916 AuTraceErr(err);
917 if (!err) {
918 p = _rev;
919 rev = *p;
920 rev->already = already;
921 goto out; /* success */
922 }
923
924 /* revert */
925 if (!already)
926 au_dr_hino_del(dr, ent);
927 kfree(ent);
928
929 out:
930 AuTraceErr(err);
931 return err;
932 }
933
934 void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev)
935 {
936 struct au_drinfo_rev *rev;
937 struct au_drinfo_rev_elm *elm;
938 int nelm;
939
940 rev = _rev;
941 elm = rev->elm;
942 for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
943 dput(elm->info_dentry);
944 kfree(elm->info_last);
945 }
946 kfree(rev);
947 }
948
949 void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev)
950 {
951 int err;
952 struct au_drinfo_store work;
953 struct au_drinfo_rev *rev = _rev;
954 struct super_block *sb;
955 struct au_branch *br;
956 struct inode *h_inode;
957 struct au_dr_br *dr;
958 struct au_dr_hino *ent;
959
960 err = au_drinfo_store_work_init(&work, btgt);
961 if (unlikely(err))
962 goto out;
963
964 sb = src->d_sb;
965 br = au_sbr(sb, btgt);
966 work.h_ppath.dentry = au_h_dptr(src, btgt);
967 work.h_ppath.mnt = au_br_mnt(br);
968 au_drinfo_store_rev(rev, &work);
969 au_drinfo_store_work_fin(&work);
970 if (rev->already)
971 goto out;
972
973 dr = &br->br_dirren;
974 h_inode = d_inode(work.h_ppath.dentry);
975 ent = au_dr_hino_find(dr, h_inode->i_ino);
976 BUG_ON(!ent);
977 au_dr_hino_del(dr, ent);
978 kfree(ent);
979
980 out:
981 kfree(rev);
982 if (unlikely(err))
983 pr_err("failed to remove dirren info\n");
984 }
985
986 /* ---------------------------------------------------------------------- */
987
988 static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath,
989 char *whname, int whnamelen,
990 struct dentry **info_dentry)
991 {
992 struct au_drinfo *drinfo;
993 struct file *f;
994 struct inode *h_dir;
995 struct path infopath;
996 int unlocked;
997
998 AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname);
999
1000 *info_dentry = NULL;
1001 drinfo = NULL;
1002 unlocked = 0;
1003 h_dir = d_inode(h_ppath->dentry);
1004 vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
1005 infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry,
1006 whnamelen);
1007 if (IS_ERR(infopath.dentry)) {
1008 drinfo = (void *)infopath.dentry;
1009 goto out;
1010 }
1011
1012 if (d_is_negative(infopath.dentry))
1013 goto out_dput; /* success */
1014
1015 infopath.mnt = h_ppath->mnt;
1016 f = vfsub_dentry_open(&infopath, O_RDONLY);
1017 inode_unlock_shared(h_dir);
1018 unlocked = 1;
1019 if (IS_ERR(f)) {
1020 drinfo = (void *)f;
1021 goto out_dput;
1022 }
1023
1024 drinfo = au_drinfo_read_k(f, /*h_ino*/0);
1025 if (IS_ERR_OR_NULL(drinfo))
1026 goto out_fput;
1027
1028 AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname);
1029 *info_dentry = dget(infopath.dentry); /* keep it alive */
1030
1031 out_fput:
1032 fput(f);
1033 out_dput:
1034 dput(infopath.dentry);
1035 out:
1036 if (!unlocked)
1037 inode_unlock_shared(h_dir);
1038 AuTraceErrPtr(drinfo);
1039 return drinfo;
1040 }
1041
1042 struct au_drinfo_do_load_args {
1043 struct au_drinfo **drinfop;
1044 struct path *h_ppath;
1045 char *whname;
1046 int whnamelen;
1047 struct dentry **info_dentry;
1048 };
1049
1050 static void au_call_drinfo_do_load(void *args)
1051 {
1052 struct au_drinfo_do_load_args *a = args;
1053
1054 *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen,
1055 a->info_dentry);
1056 }
1057
1058 struct au_drinfo_load {
1059 struct path h_ppath;
1060 struct qstr *qname;
1061 unsigned char no_sio;
1062
1063 aufs_bindex_t ninfo;
1064 struct au_drinfo **drinfo;
1065 };
1066
1067 static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex,
1068 struct au_branch *br)
1069 {
1070 int err, wkq_err, whnamelen, e;
1071 char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]
1072 = AUFS_WH_DR_INFO_PFX;
1073 struct au_drinfo *drinfo;
1074 struct qstr oldname;
1075 struct inode *h_dir, *delegated;
1076 struct dentry *info_dentry;
1077 struct path infopath;
1078
1079 whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
1080 whnamelen += au_drinfo_name(br, whname + whnamelen,
1081 sizeof(whname) - whnamelen);
1082 if (w->no_sio)
1083 drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen,
1084 &info_dentry);
1085 else {
1086 struct au_drinfo_do_load_args args = {
1087 .drinfop = &drinfo,
1088 .h_ppath = &w->h_ppath,
1089 .whname = whname,
1090 .whnamelen = whnamelen,
1091 .info_dentry = &info_dentry
1092 };
1093 wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args);
1094 if (unlikely(wkq_err))
1095 drinfo = ERR_PTR(wkq_err);
1096 }
1097 err = PTR_ERR(drinfo);
1098 if (IS_ERR_OR_NULL(drinfo))
1099 goto out;
1100
1101 err = 0;
1102 oldname.len = drinfo->oldnamelen;
1103 oldname.name = drinfo->oldname;
1104 if (au_qstreq(w->qname, &oldname)) {
1105 /* the name is renamed back */
1106 kfree(drinfo);
1107 drinfo = NULL;
1108
1109 infopath.dentry = info_dentry;
1110 infopath.mnt = w->h_ppath.mnt;
1111 h_dir = d_inode(w->h_ppath.dentry);
1112 delegated = NULL;
1113 inode_lock_nested(h_dir, AuLsc_I_PARENT);
1114 e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio);
1115 inode_unlock(h_dir);
1116 if (unlikely(e))
1117 AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry);
1118 if (unlikely(e == -EWOULDBLOCK))
1119 iput(delegated);
1120 }
1121 kfree(w->drinfo[bindex]);
1122 w->drinfo[bindex] = drinfo;
1123 dput(info_dentry);
1124
1125 out:
1126 AuTraceErr(err);
1127 return err;
1128 }
1129
1130 /* ---------------------------------------------------------------------- */
1131
1132 static void au_dr_lkup_free(struct au_drinfo **drinfo, int n)
1133 {
1134 struct au_drinfo **p = drinfo;
1135
1136 while (n-- > 0)
1137 kfree(*drinfo++);
1138 kfree(p);
1139 }
1140
1141 int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
1142 aufs_bindex_t btgt)
1143 {
1144 int err, ninfo;
1145 struct au_drinfo_load w;
1146 aufs_bindex_t bindex, bbot;
1147 struct au_branch *br;
1148 struct inode *h_dir;
1149 struct au_dr_hino *ent;
1150 struct super_block *sb;
1151
1152 AuDbg("%.*s, name %.*s, whname %.*s, b%d\n",
1153 AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name),
1154 AuLNPair(&lkup->whname), btgt);
1155
1156 sb = dentry->d_sb;
1157 bbot = au_sbbot(sb);
1158 w.ninfo = bbot + 1;
1159 if (!lkup->dirren.drinfo) {
1160 lkup->dirren.drinfo = kcalloc(w.ninfo,
1161 sizeof(*lkup->dirren.drinfo),
1162 GFP_NOFS);
1163 if (unlikely(!lkup->dirren.drinfo)) {
1164 err = -ENOMEM;
1165 goto out;
1166 }
1167 lkup->dirren.ninfo = w.ninfo;
1168 }
1169 w.drinfo = lkup->dirren.drinfo;
1170 w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
1171 w.h_ppath.dentry = au_h_dptr(dentry, btgt);
1172 AuDebugOn(!w.h_ppath.dentry);
1173 w.h_ppath.mnt = au_sbr_mnt(sb, btgt);
1174 w.qname = &dentry->d_name;
1175
1176 ninfo = 0;
1177 for (bindex = btgt + 1; bindex <= bbot; bindex++) {
1178 br = au_sbr(sb, bindex);
1179 err = au_drinfo_load(&w, bindex, br);
1180 if (unlikely(err))
1181 goto out_free;
1182 if (w.drinfo[bindex])
1183 ninfo++;
1184 }
1185 if (!ninfo) {
1186 br = au_sbr(sb, btgt);
1187 h_dir = d_inode(w.h_ppath.dentry);
1188 ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino);
1189 AuDebugOn(!ent);
1190 au_dr_hino_del(&br->br_dirren, ent);
1191 kfree(ent);
1192 }
1193 goto out; /* success */
1194
1195 out_free:
1196 au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
1197 lkup->dirren.ninfo = 0;
1198 lkup->dirren.drinfo = NULL;
1199 out:
1200 AuTraceErr(err);
1201 return err;
1202 }
1203
1204 void au_dr_lkup_fin(struct au_do_lookup_args *lkup)
1205 {
1206 au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
1207 }
1208
1209 int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt)
1210 {
1211 int err;
1212 struct au_drinfo *drinfo;
1213
1214 err = 0;
1215 if (!lkup->dirren.drinfo)
1216 goto out;
1217 AuDebugOn(lkup->dirren.ninfo < btgt + 1);
1218 drinfo = lkup->dirren.drinfo[btgt + 1];
1219 if (!drinfo)
1220 goto out;
1221
1222 kfree(lkup->whname.name);
1223 lkup->whname.name = NULL;
1224 lkup->dirren.dr_name.len = drinfo->oldnamelen;
1225 lkup->dirren.dr_name.name = drinfo->oldname;
1226 lkup->name = &lkup->dirren.dr_name;
1227 err = au_wh_name_alloc(&lkup->whname, lkup->name);
1228 if (!err)
1229 AuDbg("name %.*s, whname %.*s, b%d\n",
1230 AuLNPair(lkup->name), AuLNPair(&lkup->whname),
1231 btgt);
1232
1233 out:
1234 AuTraceErr(err);
1235 return err;
1236 }
1237
1238 int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
1239 ino_t h_ino)
1240 {
1241 int match;
1242 struct au_drinfo *drinfo;
1243
1244 match = 1;
1245 if (!lkup->dirren.drinfo)
1246 goto out;
1247 AuDebugOn(lkup->dirren.ninfo < bindex + 1);
1248 drinfo = lkup->dirren.drinfo[bindex + 1];
1249 if (!drinfo)
1250 goto out;
1251
1252 match = (drinfo->ino == h_ino);
1253 AuDbg("match %d\n", match);
1254
1255 out:
1256 return match;
1257 }
1258
1259 /* ---------------------------------------------------------------------- */
1260
1261 int au_dr_opt_set(struct super_block *sb)
1262 {
1263 int err;
1264 aufs_bindex_t bindex, bbot;
1265 struct au_branch *br;
1266
1267 err = 0;
1268 bbot = au_sbbot(sb);
1269 for (bindex = 0; !err && bindex <= bbot; bindex++) {
1270 br = au_sbr(sb, bindex);
1271 err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
1272 }
1273
1274 return err;
1275 }
1276
1277 int au_dr_opt_flush(struct super_block *sb)
1278 {
1279 int err;
1280 aufs_bindex_t bindex, bbot;
1281 struct au_branch *br;
1282
1283 err = 0;
1284 bbot = au_sbbot(sb);
1285 for (bindex = 0; !err && bindex <= bbot; bindex++) {
1286 br = au_sbr(sb, bindex);
1287 if (au_br_writable(br->br_perm))
1288 err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
1289 }
1290
1291 return err;
1292 }
1293
1294 int au_dr_opt_clr(struct super_block *sb, int no_flush)
1295 {
1296 int err;
1297 aufs_bindex_t bindex, bbot;
1298 struct au_branch *br;
1299
1300 err = 0;
1301 if (!no_flush) {
1302 err = au_dr_opt_flush(sb);
1303 if (unlikely(err))
1304 goto out;
1305 }
1306
1307 bbot = au_sbbot(sb);
1308 for (bindex = 0; bindex <= bbot; bindex++) {
1309 br = au_sbr(sb, bindex);
1310 au_dr_hino_free(&br->br_dirren);
1311 }
1312
1313 out:
1314 return err;
1315 }