2 * Copyright (C) 2005-2012 Junjiro R. Okajima
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.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * whiteout for logical deletion and opaque directory
25 #define WH_MASK S_IRUGO
28 * If a directory contains this file, then it is opaque. We start with the
29 * .wh. flag so that it is blocked by lookup.
31 static struct qstr diropq_name = {
32 .name = AUFS_WH_DIROPQ,
33 .len = sizeof(AUFS_WH_DIROPQ) - 1
37 * generate whiteout name, which is NOT terminated by NULL.
38 * @name: original d_name.name
39 * @len: original d_name.len
41 * returns zero when succeeds, otherwise error.
42 * succeeded value as wh->name should be freed by kfree().
44 int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
48 if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
51 wh->len = name->len + AUFS_WH_PFX_LEN;
52 p = kmalloc(wh->len, GFP_NOFS);
55 memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
56 memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
63 /* ---------------------------------------------------------------------- */
66 * test if the @wh_name exists under @h_parent.
67 * @try_sio specifies the necessary of super-io.
69 int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
70 struct au_branch *br, int try_sio)
73 struct dentry *wh_dentry;
76 wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
78 wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
79 err = PTR_ERR(wh_dentry);
80 if (IS_ERR(wh_dentry))
84 if (!wh_dentry->d_inode)
85 goto out_wh; /* success */
88 if (S_ISREG(wh_dentry->d_inode->i_mode))
89 goto out_wh; /* success */
92 AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
93 AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
102 * test if the @h_dentry sets opaque or not.
104 int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
109 h_dir = h_dentry->d_inode;
110 err = au_wh_test(h_dentry, &diropq_name, br,
111 au_test_h_perm_sio(h_dir, MAY_EXEC));
116 * returns a negative dentry whose name is unique and temporary.
118 struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
121 struct dentry *dentry;
123 char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
125 /* strict atomic_t is unnecessary here */
126 static unsigned short cnt;
129 BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
132 qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
133 if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
134 dentry = ERR_PTR(-ENAMETOOLONG);
135 if (unlikely(qs.len > NAME_MAX))
137 dentry = ERR_PTR(-ENOMEM);
138 name = kmalloc(qs.len + 1, GFP_NOFS);
143 /* doubly whiteout-ed */
144 memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
145 p = name + AUFS_WH_PFX_LEN * 2;
146 memcpy(p, prefix->name, prefix->len);
149 AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
152 for (i = 0; i < 3; i++) {
153 sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
154 dentry = au_sio_lkup_one(&qs, h_parent, br);
155 if (IS_ERR(dentry) || !dentry->d_inode)
159 /* pr_warning("could not get random name\n"); */
160 dentry = ERR_PTR(-EEXIST);
161 AuDbg("%.*s\n", AuLNPair(&qs));
168 AuTraceErrPtr(dentry);
173 * rename the @h_dentry on @br to the whiteouted temporary name.
175 int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
178 struct path h_path = {
182 struct dentry *h_parent;
184 h_parent = h_dentry->d_parent; /* dir inode is locked */
185 h_dir = h_parent->d_inode;
188 h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
189 err = PTR_ERR(h_path.dentry);
190 if (IS_ERR(h_path.dentry))
193 /* under the same dir, no need to lock_rename() */
194 err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
203 /* ---------------------------------------------------------------------- */
205 * functions for removing a whiteout
208 static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
213 * forces superio when the dir has a sticky bit.
214 * this may be a violation of unix fs semantics.
216 force = (h_dir->i_mode & S_ISVTX)
217 && h_path->dentry->d_inode->i_uid != current_fsuid();
218 return vfsub_unlink(h_dir, h_path, force);
221 int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
222 struct dentry *dentry)
226 err = do_unlink_wh(h_dir, h_path);
228 au_set_dbwh(dentry, -1);
233 static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
234 struct au_branch *br)
237 struct path h_path = {
242 h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
243 if (IS_ERR(h_path.dentry))
244 err = PTR_ERR(h_path.dentry);
246 if (h_path.dentry->d_inode
247 && S_ISREG(h_path.dentry->d_inode->i_mode))
248 err = do_unlink_wh(h_parent->d_inode, &h_path);
255 /* ---------------------------------------------------------------------- */
257 * initialize/clean whiteout for a branch
260 static void au_wh_clean(struct inode *h_dir, struct path *whpath,
265 if (!whpath->dentry->d_inode)
268 err = mnt_want_write(whpath->mnt);
271 err = vfsub_rmdir(h_dir, whpath);
273 err = vfsub_unlink(h_dir, whpath, /*force*/0);
274 mnt_drop_write(whpath->mnt);
277 pr_warning("failed removing %.*s (%d), ignored.\n",
278 AuDLNPair(whpath->dentry), err);
281 static int test_linkable(struct dentry *h_root)
283 struct inode *h_dir = h_root->d_inode;
285 if (h_dir->i_op->link)
288 pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
289 AuDLNPair(h_root), au_sbtype(h_root->d_sb));
293 /* todo: should this mkdir be done in /sbin/mount.aufs helper? */
294 static int au_whdir(struct inode *h_dir, struct path *path)
299 if (!path->dentry->d_inode) {
302 if (au_test_nfs(path->dentry->d_sb))
304 err = mnt_want_write(path->mnt);
306 err = vfsub_mkdir(h_dir, path, mode);
307 mnt_drop_write(path->mnt);
309 } else if (S_ISDIR(path->dentry->d_inode->i_mode))
312 pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
318 const struct qstr *name;
319 struct dentry *dentry;
322 static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
325 h_path->dentry = base[AuBrWh_BASE].dentry;
326 au_wh_clean(h_dir, h_path, /*isdir*/0);
327 h_path->dentry = base[AuBrWh_PLINK].dentry;
328 au_wh_clean(h_dir, h_path, /*isdir*/1);
329 h_path->dentry = base[AuBrWh_ORPH].dentry;
330 au_wh_clean(h_dir, h_path, /*isdir*/1);
335 * minus: error, caller should print the mesage
337 * plus: error, caller should NOT print the mesage
339 static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
340 int do_plink, struct au_wh_base base[],
346 h_dir = h_root->d_inode;
347 h_path->dentry = base[AuBrWh_BASE].dentry;
348 au_wh_clean(h_dir, h_path, /*isdir*/0);
349 h_path->dentry = base[AuBrWh_PLINK].dentry;
351 err = test_linkable(h_root);
357 err = au_whdir(h_dir, h_path);
360 wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
362 au_wh_clean(h_dir, h_path, /*isdir*/1);
363 h_path->dentry = base[AuBrWh_ORPH].dentry;
364 err = au_whdir(h_dir, h_path);
367 wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
374 * for the moment, aufs supports the branch filesystem which does not support
375 * link(2). testing on FAT which does not support i_op->setattr() fully either,
376 * copyup failed. finally, such filesystem will not be used as the writable
379 * returns tri-state, see above.
381 static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
382 int do_plink, struct au_wh_base base[],
388 WbrWhMustWriteLock(wbr);
390 err = test_linkable(h_root);
397 * todo: should this create be done in /sbin/mount.aufs helper?
400 h_dir = h_root->d_inode;
401 if (!base[AuBrWh_BASE].dentry->d_inode) {
402 err = mnt_want_write(h_path->mnt);
404 h_path->dentry = base[AuBrWh_BASE].dentry;
405 err = vfsub_create(h_dir, h_path, WH_MASK);
406 mnt_drop_write(h_path->mnt);
408 } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
411 pr_err("unknown %.*s/%.*s exists\n",
412 AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
416 h_path->dentry = base[AuBrWh_PLINK].dentry;
418 err = au_whdir(h_dir, h_path);
421 wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
423 au_wh_clean(h_dir, h_path, /*isdir*/1);
424 wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
426 h_path->dentry = base[AuBrWh_ORPH].dentry;
427 err = au_whdir(h_dir, h_path);
430 wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
437 * initialize the whiteout base file/dir for @br.
439 int au_wh_init(struct dentry *h_root, struct au_branch *br,
440 struct super_block *sb)
443 const unsigned char do_plink
444 = !!au_opt_test(au_mntflags(sb), PLINK);
449 struct au_wbr *wbr = br->br_wbr;
450 static const struct qstr base_name[] = {
452 .name = AUFS_BASE_NAME,
453 .len = sizeof(AUFS_BASE_NAME) - 1
456 .name = AUFS_PLINKDIR_NAME,
457 .len = sizeof(AUFS_PLINKDIR_NAME) - 1
460 .name = AUFS_ORPHDIR_NAME,
461 .len = sizeof(AUFS_ORPHDIR_NAME) - 1
464 struct au_wh_base base[] = {
466 .name = base_name + AuBrWh_BASE,
470 .name = base_name + AuBrWh_PLINK,
474 .name = base_name + AuBrWh_ORPH,
480 WbrWhMustWriteLock(wbr);
482 for (i = 0; i < AuBrWh_Last; i++) {
483 /* doubly whiteouted */
486 d = au_wh_lkup(h_root, (void *)base[i].name, br);
494 && wbr->wbr_wh[i] != base[i].dentry);
498 for (i = 0; i < AuBrWh_Last; i++) {
499 dput(wbr->wbr_wh[i]);
500 wbr->wbr_wh[i] = NULL;
504 if (!au_br_writable(br->br_perm)) {
505 h_dir = h_root->d_inode;
506 au_wh_init_ro(h_dir, base, &path);
507 } else if (!au_br_wh_linkable(br->br_perm)) {
508 err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
514 err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
520 goto out; /* success */
523 pr_err("an error(%d) on the writable branch %.*s(%s)\n",
524 err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
526 for (i = 0; i < AuBrWh_Last; i++)
527 dput(base[i].dentry);
531 /* ---------------------------------------------------------------------- */
533 * whiteouts are all hard-linked usually.
534 * when its link count reaches a ceiling, we create a new whiteout base
538 struct reinit_br_wh {
539 struct super_block *sb;
540 struct au_branch *br;
543 static void reinit_br_wh(void *arg)
546 aufs_bindex_t bindex;
548 struct reinit_br_wh *a = arg;
551 struct dentry *h_root;
552 struct au_hinode *hdir;
557 si_noflush_write_lock(a->sb);
558 if (!au_br_writable(a->br->br_perm))
560 bindex = au_br_index(a->sb, a->br->br_id);
561 if (unlikely(bindex < 0))
564 di_read_lock_parent(a->sb->s_root, AuLock_IR);
565 dir = a->sb->s_root->d_inode;
566 hdir = au_hi(dir, bindex);
567 h_root = au_h_dptr(a->sb->s_root, bindex);
569 au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
570 wbr_wh_write_lock(wbr);
571 err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
574 err = mnt_want_write(a->br->br_mnt);
576 h_path.dentry = wbr->wbr_whbase;
577 h_path.mnt = a->br->br_mnt;
578 err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
579 mnt_drop_write(a->br->br_mnt);
582 pr_warning("%.*s is moved, ignored\n",
583 AuDLNPair(wbr->wbr_whbase));
586 dput(wbr->wbr_whbase);
587 wbr->wbr_whbase = NULL;
589 err = au_wh_init(h_root, a->br, a->sb);
590 wbr_wh_write_unlock(wbr);
591 au_hn_imtx_unlock(hdir);
592 di_read_unlock(a->sb->s_root, AuLock_IR);
596 atomic_dec(&wbr->wbr_wh_running);
597 atomic_dec(&a->br->br_count);
598 si_write_unlock(a->sb);
599 au_nwt_done(&au_sbi(a->sb)->si_nowait);
602 AuIOErr("err %d\n", err);
605 static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
608 struct reinit_br_wh *arg;
611 if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
615 arg = kmalloc(sizeof(*arg), GFP_NOFS);
618 * dec(wh_running), kfree(arg) and dec(br_count)
623 atomic_inc(&br->br_count);
624 wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
625 if (unlikely(wkq_err)) {
626 atomic_dec(&br->br_wbr->wbr_wh_running);
627 atomic_dec(&br->br_count);
635 atomic_dec(&br->br_wbr->wbr_wh_running);
638 /* ---------------------------------------------------------------------- */
641 * create the whiteout @wh.
643 static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
647 struct path h_path = {
650 struct au_branch *br;
652 struct dentry *h_parent;
655 h_parent = wh->d_parent; /* dir inode is locked */
656 h_dir = h_parent->d_inode;
659 br = au_sbr(sb, bindex);
660 h_path.mnt = br->br_mnt;
662 wbr_wh_read_lock(wbr);
663 if (wbr->wbr_whbase) {
664 err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
665 if (!err || err != -EMLINK)
668 /* link count full. re-initialize br_whbase. */
669 kick_reinit_br_wh(sb, br);
672 /* return this error in this context */
673 err = vfsub_create(h_dir, &h_path, WH_MASK);
676 wbr_wh_read_unlock(wbr);
680 /* ---------------------------------------------------------------------- */
683 * create or remove the diropq.
685 static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
688 struct dentry *opq_dentry, *h_dentry;
689 struct super_block *sb;
690 struct au_branch *br;
694 br = au_sbr(sb, bindex);
695 h_dentry = au_h_dptr(dentry, bindex);
696 opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
697 if (IS_ERR(opq_dentry))
700 if (au_ftest_diropq(flags, CREATE)) {
701 err = link_or_create_wh(sb, bindex, opq_dentry);
703 au_set_dbdiropq(dentry, bindex);
704 goto out; /* success */
708 .dentry = opq_dentry,
711 err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
713 au_set_dbdiropq(dentry, -1);
716 opq_dentry = ERR_PTR(err);
722 struct do_diropq_args {
723 struct dentry **errp;
724 struct dentry *dentry;
725 aufs_bindex_t bindex;
729 static void call_do_diropq(void *args)
731 struct do_diropq_args *a = args;
732 *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
735 struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
738 struct dentry *diropq, *h_dentry;
740 h_dentry = au_h_dptr(dentry, bindex);
741 if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
742 diropq = do_diropq(dentry, bindex, flags);
745 struct do_diropq_args args = {
752 wkq_err = au_wkq_wait(call_do_diropq, &args);
753 if (unlikely(wkq_err))
754 diropq = ERR_PTR(wkq_err);
760 /* ---------------------------------------------------------------------- */
763 * lookup whiteout dentry.
764 * @h_parent: lower parent dentry which must exist and be locked
765 * @base_name: name of dentry which will be whiteouted
766 * returns dentry for whiteout.
768 struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
769 struct au_branch *br)
773 struct dentry *wh_dentry;
775 err = au_wh_name_alloc(&wh_name, base_name);
776 wh_dentry = ERR_PTR(err);
778 wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
785 * link/create a whiteout for @dentry on @bindex.
787 struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
788 struct dentry *h_parent)
790 struct dentry *wh_dentry;
791 struct super_block *sb;
795 wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
796 if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
797 err = link_or_create_wh(sb, bindex, wh_dentry);
799 au_set_dbwh(dentry, bindex);
802 wh_dentry = ERR_PTR(err);
809 /* ---------------------------------------------------------------------- */
811 /* Delete all whiteouts in this directory on branch bindex. */
812 static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
813 aufs_bindex_t bindex, struct au_branch *br)
819 struct hlist_head *head;
820 struct au_vdir_wh *tpos;
821 struct hlist_node *pos;
822 struct au_vdir_destr *str;
825 p = __getname_gfp(GFP_NOFS);
827 if (unlikely(!wh_name.name))
831 memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
832 p += AUFS_WH_PFX_LEN;
834 head = whlist->nh_head;
835 for (ul = 0; !err && ul < n; ul++, head++) {
836 hlist_for_each_entry(tpos, pos, head, wh_hash) {
837 if (tpos->wh_bindex != bindex)
841 if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
842 memcpy(p, str->name, str->len);
843 wh_name.len = AUFS_WH_PFX_LEN + str->len;
844 err = unlink_wh_name(h_dentry, &wh_name, br);
849 AuIOErr("whiteout name too long %.*s\n",
850 str->len, str->name);
855 __putname(wh_name.name);
861 struct del_wh_children_args {
863 struct dentry *h_dentry;
864 struct au_nhash *whlist;
865 aufs_bindex_t bindex;
866 struct au_branch *br;
869 static void call_del_wh_children(void *args)
871 struct del_wh_children_args *a = args;
872 *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
875 /* ---------------------------------------------------------------------- */
877 struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
879 struct au_whtmp_rmdir *whtmp;
885 whtmp = kmalloc(sizeof(*whtmp), gfp);
886 if (unlikely(!whtmp)) {
887 whtmp = ERR_PTR(-ENOMEM);
893 whtmp->wh_dentry = NULL;
894 /* no estimation for dir size */
895 rdhash = au_sbi(sb)->si_rdhash;
897 rdhash = AUFS_RDHASH_DEF;
898 err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
901 whtmp = ERR_PTR(err);
908 void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
911 atomic_dec(&whtmp->br->br_count);
912 dput(whtmp->wh_dentry);
914 au_nhash_wh_free(&whtmp->whlist);
919 * rmdir the whiteouted temporary named dir @h_dentry.
920 * @whlist: whiteouted children.
922 int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
923 struct dentry *wh_dentry, struct au_nhash *whlist)
927 struct inode *wh_inode, *h_dir;
928 struct au_branch *br;
930 h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
933 br = au_sbr(dir->i_sb, bindex);
934 wh_inode = wh_dentry->d_inode;
935 mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
938 * someone else might change some whiteouts while we were sleeping.
939 * it means this whlist may have an obsoleted entry.
941 if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
942 err = del_wh_children(wh_dentry, whlist, bindex, br);
945 struct del_wh_children_args args = {
947 .h_dentry = wh_dentry,
953 wkq_err = au_wkq_wait(call_del_wh_children, &args);
954 if (unlikely(wkq_err))
957 mutex_unlock(&wh_inode->i_mutex);
960 h_tmp.dentry = wh_dentry;
961 h_tmp.mnt = br->br_mnt;
962 err = vfsub_rmdir(h_dir, &h_tmp);
966 if (au_ibstart(dir) == bindex) {
967 /* todo: dir->i_mutex is necessary */
968 au_cpup_attr_timesizes(dir);
969 vfsub_drop_nlink(dir);
971 return 0; /* success */
974 pr_warning("failed removing %.*s(%d), ignored\n",
975 AuDLNPair(wh_dentry), err);
979 static void call_rmdir_whtmp(void *args)
982 aufs_bindex_t bindex;
983 struct au_whtmp_rmdir *a = args;
984 struct super_block *sb;
985 struct dentry *h_parent;
987 struct au_hinode *hdir;
989 /* rmdir by nfsd may cause deadlock with this i_mutex */
990 /* mutex_lock(&a->dir->i_mutex); */
993 si_read_lock(sb, !AuLock_FLUSH);
994 if (!au_br_writable(a->br->br_perm))
996 bindex = au_br_index(sb, a->br->br_id);
997 if (unlikely(bindex < 0))
1001 ii_write_lock_parent(a->dir);
1002 h_parent = dget_parent(a->wh_dentry);
1003 h_dir = h_parent->d_inode;
1004 hdir = au_hi(a->dir, bindex);
1005 au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1006 err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
1009 err = mnt_want_write(a->br->br_mnt);
1011 err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry,
1013 mnt_drop_write(a->br->br_mnt);
1016 au_hn_imtx_unlock(hdir);
1018 ii_write_unlock(a->dir);
1021 /* mutex_unlock(&a->dir->i_mutex); */
1022 au_whtmp_rmdir_free(a);
1024 au_nwt_done(&au_sbi(sb)->si_nowait);
1026 AuIOErr("err %d\n", err);
1029 void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
1030 struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
1033 struct super_block *sb;
1037 /* all post-process will be done in do_rmdir_whtmp(). */
1039 args->dir = au_igrab(dir);
1040 args->br = au_sbr(sb, bindex);
1041 atomic_inc(&args->br->br_count);
1042 args->wh_dentry = dget(wh_dentry);
1043 wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1044 if (unlikely(wkq_err)) {
1045 pr_warning("rmdir error %.*s (%d), ignored\n",
1046 AuDLNPair(wh_dentry), wkq_err);
1047 au_whtmp_rmdir_free(args);