2
* Copyright (C) 2005-2009 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
26
#define WH_MASK S_IRUGO
29
* If a directory contains this file, then it is opaque. We start with the
30
* .wh. flag so that it is blocked by lookup.
32
static struct qstr diropq_name = {
33
.name = AUFS_WH_DIROPQ,
34
.len = sizeof(AUFS_WH_DIROPQ) - 1
38
* generate whiteout name, which is NOT terminated by NULL.
39
* @name: original d_name.name
40
* @len: original d_name.len
42
* returns zero when succeeds, otherwise error.
43
* succeeded value as wh->name should be freed by kfree().
45
int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
49
if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
52
wh->len = name->len + AUFS_WH_PFX_LEN;
53
p = kmalloc(wh->len, GFP_NOFS);
56
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
57
memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
64
/* ---------------------------------------------------------------------- */
67
* test if the @wh_name exists under @h_parent.
68
* @try_sio specifies the necessary of super-io.
70
int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
71
struct au_branch *br, int try_sio)
74
struct dentry *wh_dentry;
77
h_dir = h_parent->d_inode;
79
wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
81
wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
82
err = PTR_ERR(wh_dentry);
83
if (IS_ERR(wh_dentry))
87
if (!wh_dentry->d_inode)
88
goto out_wh; /* success */
91
if (S_ISREG(wh_dentry->d_inode->i_mode))
92
goto out_wh; /* success */
95
AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
96
AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
105
* test if the @h_dentry sets opaque or not.
107
int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
112
h_dir = h_dentry->d_inode;
113
err = au_wh_test(h_dentry, &diropq_name, br,
114
au_test_h_perm_sio(h_dir, MAY_EXEC));
119
* returns a negative dentry whose name is unique and temporary.
121
struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
124
struct dentry *dentry;
126
char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN_MIN + 1],
128
static unsigned short cnt;
131
BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
134
qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
135
if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
136
dentry = ERR_PTR(-ENAMETOOLONG);
137
if (unlikely(qs.len > NAME_MAX))
139
dentry = ERR_PTR(-ENOMEM);
140
name = kmalloc(qs.len + 1, GFP_NOFS);
145
/* doubly whiteout-ed */
146
memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
147
p = name + AUFS_WH_PFX_LEN * 2;
148
memcpy(p, prefix->name, prefix->len);
151
AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
154
for (i = 0; i < 3; i++) {
155
sprintf(p, "%.*d", AUFS_WH_TMP_LEN, cnt++);
156
dentry = au_sio_lkup_one(&qs, h_parent, br);
157
if (IS_ERR(dentry) || !dentry->d_inode)
161
/* pr_warning("could not get random name\n"); */
162
dentry = ERR_PTR(-EEXIST);
163
AuDbg("%.*s\n", AuLNPair(&qs));
170
AuTraceErrPtr(dentry);
175
* rename the @h_dentry on @br to the whiteouted temporary name.
177
int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
180
struct path h_path = {
184
struct dentry *h_parent;
186
h_parent = h_dentry->d_parent; /* dir inode is locked */
187
h_dir = h_parent->d_inode;
190
h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
191
err = PTR_ERR(h_path.dentry);
192
if (IS_ERR(h_path.dentry))
195
/* under the same dir, no need to lock_rename() */
196
err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
205
/* ---------------------------------------------------------------------- */
207
* functions for removing a whiteout
210
static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
215
* forces superio when the dir has a sticky bit.
216
* this may be a violation of unix fs semantics.
218
force = (h_dir->i_mode & S_ISVTX)
219
&& h_path->dentry->d_inode->i_uid != current_fsuid();
220
return vfsub_unlink(h_dir, h_path, force);
223
int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
224
struct dentry *dentry)
228
err = do_unlink_wh(h_dir, h_path);
230
au_set_dbwh(dentry, -1);
235
static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
236
struct au_branch *br)
239
struct path h_path = {
244
h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
245
if (IS_ERR(h_path.dentry))
246
err = PTR_ERR(h_path.dentry);
248
if (h_path.dentry->d_inode
249
&& S_ISREG(h_path.dentry->d_inode->i_mode))
250
err = do_unlink_wh(h_parent->d_inode, &h_path);
257
/* ---------------------------------------------------------------------- */
259
* initialize/clean whiteout for a branch
262
static void au_wh_clean(struct inode *h_dir, struct path *whpath,
267
if (!whpath->dentry->d_inode)
270
err = mnt_want_write(whpath->mnt);
273
err = vfsub_rmdir(h_dir, whpath);
275
err = vfsub_unlink(h_dir, whpath, /*force*/0);
276
mnt_drop_write(whpath->mnt);
279
pr_warning("failed removing %.*s (%d), ignored.\n",
280
AuDLNPair(whpath->dentry), err);
283
static int test_linkable(struct dentry *h_root)
285
struct inode *h_dir = h_root->d_inode;
287
if (h_dir->i_op->link)
290
pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
291
AuDLNPair(h_root), au_sbtype(h_root->d_sb));
295
/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
296
static int au_whdir(struct inode *h_dir, struct path *path)
301
if (!path->dentry->d_inode) {
304
if (au_test_nfs(path->dentry->d_sb))
306
err = mnt_want_write(path->mnt);
308
err = vfsub_mkdir(h_dir, path, mode);
309
mnt_drop_write(path->mnt);
311
} else if (S_ISDIR(path->dentry->d_inode->i_mode))
314
pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
320
const struct qstr *name;
321
struct dentry *dentry;
324
static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
327
h_path->dentry = base[AuBrWh_BASE].dentry;
328
au_wh_clean(h_dir, h_path, /*isdir*/0);
329
h_path->dentry = base[AuBrWh_PLINK].dentry;
330
au_wh_clean(h_dir, h_path, /*isdir*/1);
331
h_path->dentry = base[AuBrWh_ORPH].dentry;
332
au_wh_clean(h_dir, h_path, /*isdir*/1);
337
* minus: error, caller should print the mesage
339
* plus: error, caller should NOT print the mesage
341
static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
342
int do_plink, struct au_wh_base base[],
348
h_dir = h_root->d_inode;
349
h_path->dentry = base[AuBrWh_BASE].dentry;
350
au_wh_clean(h_dir, h_path, /*isdir*/0);
351
h_path->dentry = base[AuBrWh_PLINK].dentry;
353
err = test_linkable(h_root);
359
err = au_whdir(h_dir, h_path);
362
wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
364
au_wh_clean(h_dir, h_path, /*isdir*/1);
365
h_path->dentry = base[AuBrWh_ORPH].dentry;
366
err = au_whdir(h_dir, h_path);
369
wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
376
* for the moment, aufs supports the branch filesystem which does not support
377
* link(2). testing on FAT which does not support i_op->setattr() fully either,
378
* copyup failed. finally, such filesystem will not be used as the writable
381
* returns tri-state, see above.
383
static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
384
int do_plink, struct au_wh_base base[],
390
WbrWhMustWriteLock(wbr);
392
err = test_linkable(h_root);
399
* todo: should this create be done in /sbin/mount.aufs helper?
402
h_dir = h_root->d_inode;
403
if (!base[AuBrWh_BASE].dentry->d_inode) {
404
err = mnt_want_write(h_path->mnt);
406
h_path->dentry = base[AuBrWh_BASE].dentry;
407
err = vfsub_create(h_dir, h_path, WH_MASK);
408
mnt_drop_write(h_path->mnt);
410
} else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
413
pr_err("unknown %.*s/%.*s exists\n",
414
AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
418
h_path->dentry = base[AuBrWh_PLINK].dentry;
420
err = au_whdir(h_dir, h_path);
423
wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
425
au_wh_clean(h_dir, h_path, /*isdir*/1);
426
wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
428
h_path->dentry = base[AuBrWh_ORPH].dentry;
429
err = au_whdir(h_dir, h_path);
432
wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
439
* initialize the whiteout base file/dir for @br.
441
int au_wh_init(struct dentry *h_root, struct au_branch *br,
442
struct super_block *sb)
445
const unsigned char do_plink
446
= !!au_opt_test(au_mntflags(sb), PLINK);
451
struct au_wbr *wbr = br->br_wbr;
452
static const struct qstr base_name[] = {
454
.name = AUFS_BASE_NAME,
455
.len = sizeof(AUFS_BASE_NAME) - 1
458
.name = AUFS_PLINKDIR_NAME,
459
.len = sizeof(AUFS_PLINKDIR_NAME) - 1
462
.name = AUFS_ORPHDIR_NAME,
463
.len = sizeof(AUFS_ORPHDIR_NAME) - 1
466
struct au_wh_base base[] = {
468
.name = base_name + AuBrWh_BASE,
472
.name = base_name + AuBrWh_PLINK,
476
.name = base_name + AuBrWh_ORPH,
482
WbrWhMustWriteLock(wbr);
484
h_dir = h_root->d_inode;
485
for (i = 0; i < AuBrWh_Last; i++) {
486
/* doubly whiteouted */
489
d = au_wh_lkup(h_root, (void *)base[i].name, br);
497
&& wbr->wbr_wh[i] != base[i].dentry);
501
for (i = 0; i < AuBrWh_Last; i++) {
502
dput(wbr->wbr_wh[i]);
503
wbr->wbr_wh[i] = NULL;
508
switch (br->br_perm) {
513
au_wh_init_ro(h_dir, base, &path);
516
case AuBrPerm_RWNoLinkWH:
517
err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
525
err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
535
goto out; /* success */
538
pr_err("an error(%d) on the writable branch %.*s(%s)\n",
539
err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
541
for (i = 0; i < AuBrWh_Last; i++)
542
dput(base[i].dentry);
546
/* ---------------------------------------------------------------------- */
548
* whiteouts are all hard-linked usually.
549
* when its link count reaches a ceiling, we create a new whiteout base
553
struct reinit_br_wh {
554
struct super_block *sb;
555
struct au_branch *br;
558
static void reinit_br_wh(void *arg)
561
aufs_bindex_t bindex;
563
struct reinit_br_wh *a = arg;
566
struct dentry *h_root;
567
struct au_hinode *hdir;
572
si_noflush_write_lock(a->sb);
573
if (!au_br_writable(a->br->br_perm))
575
bindex = au_br_index(a->sb, a->br->br_id);
576
if (unlikely(bindex < 0))
579
di_read_lock_parent(a->sb->s_root, AuLock_IR);
580
dir = a->sb->s_root->d_inode;
581
hdir = au_hi(dir, bindex);
582
h_root = au_h_dptr(a->sb->s_root, bindex);
584
au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
585
wbr_wh_write_lock(wbr);
586
err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
589
err = mnt_want_write(a->br->br_mnt);
591
h_path.dentry = wbr->wbr_whbase;
592
h_path.mnt = a->br->br_mnt;
593
err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
594
mnt_drop_write(a->br->br_mnt);
597
pr_warning("%.*s is moved, ignored\n",
598
AuDLNPair(wbr->wbr_whbase));
601
dput(wbr->wbr_whbase);
602
wbr->wbr_whbase = NULL;
604
err = au_wh_init(h_root, a->br, a->sb);
605
wbr_wh_write_unlock(wbr);
606
au_hin_imtx_unlock(hdir);
607
di_read_unlock(a->sb->s_root, AuLock_IR);
611
atomic_dec(&wbr->wbr_wh_running);
612
atomic_dec(&a->br->br_count);
613
au_nwt_done(&au_sbi(a->sb)->si_nowait);
614
si_write_unlock(a->sb);
617
AuIOErr("err %d\n", err);
620
static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
623
struct reinit_br_wh *arg;
626
if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
630
arg = kmalloc(sizeof(*arg), GFP_NOFS);
633
* dec(wh_running), kfree(arg) and dec(br_count)
638
atomic_inc(&br->br_count);
639
wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb);
640
if (unlikely(wkq_err)) {
641
atomic_dec(&br->br_wbr->wbr_wh_running);
642
atomic_dec(&br->br_count);
650
atomic_dec(&br->br_wbr->wbr_wh_running);
653
/* ---------------------------------------------------------------------- */
656
* create the whiteout @wh.
658
static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
662
struct path h_path = {
665
struct au_branch *br;
667
struct dentry *h_parent;
670
h_parent = wh->d_parent; /* dir inode is locked */
671
h_dir = h_parent->d_inode;
674
br = au_sbr(sb, bindex);
675
h_path.mnt = br->br_mnt;
677
wbr_wh_read_lock(wbr);
678
if (wbr->wbr_whbase) {
679
err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
680
if (!err || err != -EMLINK)
683
/* link count full. re-initialize br_whbase. */
684
kick_reinit_br_wh(sb, br);
687
/* return this error in this context */
688
err = vfsub_create(h_dir, &h_path, WH_MASK);
691
wbr_wh_read_unlock(wbr);
695
/* ---------------------------------------------------------------------- */
698
* create or remove the diropq.
700
static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
703
struct dentry *opq_dentry, *h_dentry;
704
struct super_block *sb;
705
struct au_branch *br;
709
br = au_sbr(sb, bindex);
710
h_dentry = au_h_dptr(dentry, bindex);
711
opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
712
if (IS_ERR(opq_dentry))
715
if (au_ftest_diropq(flags, CREATE)) {
716
err = link_or_create_wh(sb, bindex, opq_dentry);
718
au_set_dbdiropq(dentry, bindex);
719
goto out; /* success */
723
.dentry = opq_dentry,
726
err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
728
au_set_dbdiropq(dentry, -1);
731
opq_dentry = ERR_PTR(err);
737
struct do_diropq_args {
738
struct dentry **errp;
739
struct dentry *dentry;
740
aufs_bindex_t bindex;
744
static void call_do_diropq(void *args)
746
struct do_diropq_args *a = args;
747
*a->errp = do_diropq(a->dentry, a->bindex, a->flags);
750
struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
753
struct dentry *diropq, *h_dentry;
755
h_dentry = au_h_dptr(dentry, bindex);
756
if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
757
diropq = do_diropq(dentry, bindex, flags);
760
struct do_diropq_args args = {
767
wkq_err = au_wkq_wait(call_do_diropq, &args);
768
if (unlikely(wkq_err))
769
diropq = ERR_PTR(wkq_err);
775
/* ---------------------------------------------------------------------- */
778
* lookup whiteout dentry.
779
* @h_parent: lower parent dentry which must exist and be locked
780
* @base_name: name of dentry which will be whiteouted
781
* returns dentry for whiteout.
783
struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
784
struct au_branch *br)
788
struct dentry *wh_dentry;
790
err = au_wh_name_alloc(&wh_name, base_name);
791
wh_dentry = ERR_PTR(err);
793
wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
800
* link/create a whiteout for @dentry on @bindex.
802
struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
803
struct dentry *h_parent)
805
struct dentry *wh_dentry;
806
struct super_block *sb;
810
wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
811
if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
812
err = link_or_create_wh(sb, bindex, wh_dentry);
814
au_set_dbwh(dentry, bindex);
817
wh_dentry = ERR_PTR(err);
824
/* ---------------------------------------------------------------------- */
826
/* Delete all whiteouts in this directory on branch bindex. */
827
static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
828
aufs_bindex_t bindex, struct au_branch *br)
834
struct hlist_head *head;
835
struct au_vdir_wh *tpos;
836
struct hlist_node *pos;
837
struct au_vdir_destr *str;
842
if (unlikely(!wh_name.name))
846
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
847
p += AUFS_WH_PFX_LEN;
849
head = whlist->nh_head;
850
for (ul = 0; !err && ul < n; ul++, head++) {
851
hlist_for_each_entry(tpos, pos, head, wh_hash) {
852
if (tpos->wh_bindex != bindex)
856
if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
857
memcpy(p, str->name, str->len);
858
wh_name.len = AUFS_WH_PFX_LEN + str->len;
859
err = unlink_wh_name(h_dentry, &wh_name, br);
864
AuIOErr("whiteout name too long %.*s\n",
865
str->len, str->name);
870
__putname(wh_name.name);
876
struct del_wh_children_args {
878
struct dentry *h_dentry;
879
struct au_nhash *whlist;
880
aufs_bindex_t bindex;
881
struct au_branch *br;
884
static void call_del_wh_children(void *args)
886
struct del_wh_children_args *a = args;
887
*a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
890
/* ---------------------------------------------------------------------- */
892
struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
894
struct au_whtmp_rmdir *whtmp;
900
whtmp = kmalloc(sizeof(*whtmp), gfp);
901
if (unlikely(!whtmp)) {
902
whtmp = ERR_PTR(-ENOMEM);
907
whtmp->wh_dentry = NULL;
908
/* no estimation for dir size */
909
rdhash = au_sbi(sb)->si_rdhash;
911
rdhash = AUFS_RDHASH_DEF;
912
err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
915
whtmp = ERR_PTR(err);
922
void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
924
dput(whtmp->wh_dentry);
926
au_nhash_wh_free(&whtmp->whlist);
931
* rmdir the whiteouted temporary named dir @h_dentry.
932
* @whlist: whiteouted children.
934
int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
935
struct dentry *wh_dentry, struct au_nhash *whlist)
939
struct inode *wh_inode, *h_dir;
940
struct au_branch *br;
942
h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
945
br = au_sbr(dir->i_sb, bindex);
946
wh_inode = wh_dentry->d_inode;
947
mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
950
* someone else might change some whiteouts while we were sleeping.
951
* it means this whlist may have an obsoleted entry.
953
if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
954
err = del_wh_children(wh_dentry, whlist, bindex, br);
957
struct del_wh_children_args args = {
959
.h_dentry = wh_dentry,
965
wkq_err = au_wkq_wait(call_del_wh_children, &args);
966
if (unlikely(wkq_err))
969
mutex_unlock(&wh_inode->i_mutex);
972
h_tmp.dentry = wh_dentry;
973
h_tmp.mnt = br->br_mnt;
974
err = vfsub_rmdir(h_dir, &h_tmp);
975
/* d_drop(h_dentry); */
979
if (au_ibstart(dir) == bindex) {
980
au_cpup_attr_timesizes(dir);
983
return 0; /* success */
986
pr_warning("failed removing %.*s(%d), ignored\n",
987
AuDLNPair(wh_dentry), err);
991
static void call_rmdir_whtmp(void *args)
994
struct au_whtmp_rmdir *a = args;
995
struct super_block *sb;
996
struct dentry *h_parent;
998
struct au_branch *br;
999
struct au_hinode *hdir;
1001
/* rmdir by nfsd may cause deadlock with this i_mutex */
1002
/* mutex_lock(&a->dir->i_mutex); */
1004
si_noflush_read_lock(sb);
1005
err = au_test_ro(sb, a->bindex, NULL);
1010
br = au_sbr(sb, a->bindex);
1011
ii_write_lock_parent(a->dir);
1012
h_parent = dget_parent(a->wh_dentry);
1013
h_dir = h_parent->d_inode;
1014
hdir = au_hi(a->dir, a->bindex);
1015
au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1016
err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br);
1018
err = mnt_want_write(br->br_mnt);
1020
err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry,
1022
mnt_drop_write(br->br_mnt);
1025
au_hin_imtx_unlock(hdir);
1027
ii_write_unlock(a->dir);
1030
/* mutex_unlock(&a->dir->i_mutex); */
1031
au_nwt_done(&au_sbi(sb)->si_nowait);
1033
au_whtmp_rmdir_free(a);
1035
AuIOErr("err %d\n", err);
1038
void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
1039
struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
1045
/* all post-process will be done in do_rmdir_whtmp(). */
1046
args->dir = au_igrab(dir);
1047
args->bindex = bindex;
1048
args->wh_dentry = dget(wh_dentry);
1049
wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb);
1050
if (unlikely(wkq_err)) {
1051
pr_warning("rmdir error %.*s (%d), ignored\n",
1052
AuDLNPair(wh_dentry), wkq_err);
1053
au_whtmp_rmdir_free(args);