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