2
* Copyright (C) 2005-2008 Junjiro 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
22
* $Id: whout.c,v 1.9 2008/07/14 00:17:34 sfjro Exp $
26
#include <linux/namei.h>
29
#define WH_MASK S_IRUGO
31
/* If a directory contains this file, then it is opaque. We start with the
32
* .wh. flag so that it is blocked by lookup.
34
static struct qstr diropq_name = {
35
.name = AUFS_WH_DIROPQ,
36
.len = sizeof(AUFS_WH_DIROPQ) - 1
40
* generate whiteout name, which is NOT terminated by NULL.
41
* @name: original d_name.name
42
* @len: original d_name.len
44
* returns zero when succeeds, otherwise error.
45
* succeeded value as wh->name should be freed by au_wh_name_free().
47
int au_wh_name_alloc(const char *name, int len, struct qstr *wh)
51
AuDebugOn(!name || !len || !wh);
53
if (unlikely(len > PATH_MAX - AUFS_WH_PFX_LEN))
56
wh->len = len + AUFS_WH_PFX_LEN;
57
p = kmalloc(wh->len, GFP_NOFS);
60
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
61
memcpy(p + AUFS_WH_PFX_LEN, name, len);
68
void au_wh_name_free(struct qstr *wh)
70
AuDebugOn(!wh || !wh->name);
74
/* ---------------------------------------------------------------------- */
77
* test if the @wh_name exists under @h_parent.
78
* @try_sio specifies the necessary of super-io.
80
int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio,
84
struct dentry *wh_dentry;
88
LKTRTrace("%.*s/%.*s, ndx{%p, 0x%x}\n", AuDLNPair(h_parent),
89
wh_name->len, wh_name->name, ndx->nfsmnt, ndx->flags);
90
h_dir = h_parent->d_inode;
91
AuDebugOn(!S_ISDIR(h_dir->i_mode));
95
flags = ndx->nd->flags;
96
ndx->nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE);
100
wh_dentry = au_lkup_one(wh_name->name, h_parent,
103
wh_dentry = au_sio_lkup_one(wh_name->name, h_parent,
106
ndx->nd->flags = flags;
107
err = PTR_ERR(wh_dentry);
108
if (IS_ERR(wh_dentry))
112
if (!wh_dentry->d_inode)
113
goto out_wh; /* success */
116
if (S_ISREG(wh_dentry->d_inode->i_mode))
117
goto out_wh; /* success */
120
AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
121
AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
131
* test if the @h_dentry sets opaque or not.
133
int au_diropq_test(struct dentry *h_dentry, struct au_ndx *ndx)
138
LKTRTrace("dentry %.*s\n", AuDLNPair(h_dentry));
139
h_dir = h_dentry->d_inode;
140
AuDebugOn(!S_ISDIR(h_dir->i_mode));
142
try_sio = au_test_h_perm_sio(h_dir, MAY_EXEC,
143
au_ftest_ndx(ndx->flags, DLGT));
144
err = au_wh_test(h_dentry, &diropq_name, try_sio, ndx);
150
* returns a negative dentry whose name is unique and temporary.
152
struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct qstr *prefix,
156
struct dentry *dentry;
158
char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1
159
+ HEX_LEN + 1], *name, *p;
160
static unsigned char cnt;
162
LKTRTrace("hp %.*s, prefix %.*s\n",
163
AuDLNPair(h_parent), prefix->len, prefix->name);
164
AuDebugOn(!h_parent->d_inode);
167
len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
168
if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
169
dentry = ERR_PTR(-ENAMETOOLONG);
170
if (unlikely(len >= PATH_MAX))
172
dentry = ERR_PTR(-ENOMEM);
173
name = kmalloc(len + 1, GFP_NOFS);
178
/* doubly whiteout-ed */
179
memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
180
p = name + AUFS_WH_PFX_LEN * 2;
181
memcpy(p, prefix->name, prefix->len);
184
AuDebugOn(name + len + 1 - p <= HEX_LEN);
186
for (i = 0; i < 3; i++) {
187
sprintf(p, "%.*d", HEX_LEN, cnt++);
188
dentry = au_sio_lkup_one(name, h_parent, len, ndx);
189
if (IS_ERR(dentry) || !dentry->d_inode)
193
/* AuWarn("could not get random name\n"); */
194
dentry = ERR_PTR(-EEXIST);
195
AuDbg("%.*s\n", len, name);
199
if (unlikely(name != defname))
202
AuTraceErrPtr(dentry);
208
* rename the @dentry of @bindex to the whiteouted temporary name.
210
int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex,
211
struct dentry *h_dentry)
215
struct dentry *h_parent, *tmp_dentry;
216
struct super_block *sb;
217
unsigned int mnt_flags;
218
struct au_hin_ignore ign;
219
struct vfsub_args vargs;
220
struct au_ndx ndx = {
226
LKTRTrace("%.*s\n", AuDLNPair(h_dentry));
227
AuDebugOn(!h_dentry->d_inode);
228
h_parent = h_dentry->d_parent; /* dir inode is locked */
229
h_dir = h_parent->d_inode;
233
mnt_flags = au_mntflags(sb);
234
dlgt = !!au_test_dlgt(mnt_flags);
236
au_fset_ndx(ndx.flags, DLGT);
237
ndx.nfsmnt = au_nfsmnt(sb, bindex);
238
tmp_dentry = au_whtmp_lkup(h_parent, &h_dentry->d_name, &ndx);
239
err = PTR_ERR(tmp_dentry);
240
if (IS_ERR(tmp_dentry))
243
/* under the same dir, no need to lock_rename() */
244
vfsub_args_init(&vargs, &ign, dlgt, 0);
245
AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode));
246
vfsub_ign_hinode(&vargs, IN_MOVED_FROM | IN_MOVED_TO,
248
err = vfsub_rename(h_dir, h_dentry, h_dir, tmp_dentry, &vargs);
257
/* ---------------------------------------------------------------------- */
259
static int do_unlink_wh(struct au_hinode *hdir, struct inode *h_dir,
260
struct dentry *wh_dentry, const int dlgt)
263
struct au_hin_ignore ign;
264
struct vfsub_args vargs;
266
AuDebugOn(hdir && h_dir);
267
AuDebugOn(!hdir && !h_dir);
269
h_dir = hdir->hi_inode;
270
LKTRTrace("hi%lu, wh %.*s\n", h_dir->i_ino, AuDLNPair(wh_dentry));
271
AuDebugOn(!wh_dentry->d_inode || !S_ISREG(wh_dentry->d_inode->i_mode));
274
* forces superio when the dir has a sticky bit.
275
* this may be a violation of unix fs semantics.
277
vfsub_args_init(&vargs, &ign, dlgt,
278
(h_dir->i_mode & S_ISVTX)
279
&& wh_dentry->d_inode->i_uid != current->fsuid);
280
vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
281
err = vfsub_unlink(h_dir, wh_dentry, &vargs);
286
int au_wh_unlink_dentry(struct au_hinode *hdir, struct dentry *wh_dentry,
287
struct dentry *dentry, int dlgt)
291
LKTRTrace("i%lu, wh %.*s, d %p\n",
292
hdir->hi_inode->i_ino, AuDLNPair(wh_dentry), dentry);
293
AuDebugOn((dentry && au_dbwh(dentry) < 0)
294
|| !wh_dentry->d_inode
295
|| !S_ISREG(wh_dentry->d_inode->i_mode));
297
err = do_unlink_wh(hdir, /*h_dir*/NULL, wh_dentry, dlgt);
299
au_set_dbwh(dentry, -1);
305
static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
309
struct dentry *wh_dentry;
311
LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(wh));
313
/* au_test_h_perm() is already done */
314
wh_dentry = au_lkup_one(wh->name, h_parent, wh->len, ndx);
315
if (!IS_ERR(wh_dentry)) {
317
if (wh_dentry->d_inode && S_ISREG(wh_dentry->d_inode->i_mode))
318
err = do_unlink_wh(/*hdir*/NULL, h_parent->d_inode,
320
au_ftest_ndx(ndx->flags, DLGT));
323
err = PTR_ERR(wh_dentry);
329
/* ---------------------------------------------------------------------- */
331
static void clean_wh(struct inode *h_dir, struct dentry *wh, const int dlgt,
332
struct au_hinode *hdir)
335
struct au_hin_ignore ign;
336
struct vfsub_args vargs;
341
vfsub_args_init(&vargs, &ign, dlgt, 0);
342
vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
343
err = vfsub_unlink(h_dir, wh, &vargs);
345
AuWarn("failed unlink %.*s (%d), ignored.\n",
350
static void clean_plink(struct inode *h_dir, struct dentry *plink,
351
const int dlgt, struct au_hinode *hdir)
354
struct au_hin_ignore ign;
355
struct vfsub_args vargs;
359
if (plink->d_inode) {
360
vfsub_args_init(&vargs, &ign, dlgt, 0);
361
vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
362
err = vfsub_rmdir(h_dir, plink, &vargs);
364
AuWarn("failed rmdir %.*s (%d), ignored.\n",
365
AuDLNPair(plink), err);
369
static int test_linkable(struct inode *h_dir)
371
if (h_dir->i_op && h_dir->i_op->link)
376
static int plink_dir(struct inode *h_dir, struct dentry *plink, const int dlgt,
377
struct au_hinode *hdir)
380
struct au_hin_ignore ign;
381
struct vfsub_args vargs;
384
if (!plink->d_inode) {
386
if (unlikely(au_test_nfs(plink->d_sb)))
388
vfsub_args_init(&vargs, &ign, dlgt, 0);
389
vfsub_ign_hinode(&vargs, IN_CREATE, hdir);
390
err = vfsub_mkdir(h_dir, plink, mode, &vargs);
391
} else if (S_ISDIR(plink->d_inode->i_mode))
394
AuErr("unknown %.*s exists\n", AuDLNPair(plink));
400
* initialize the whiteout base file/dir for @br.
402
int au_wh_init(struct dentry *h_root, struct au_branch *br,
403
struct vfsmount *nfsmnt, struct super_block *sb,
404
aufs_bindex_t bindex)
407
struct dentry *wh, *plink;
409
struct au_hin_ignore ign;
410
struct vfsub_args vargs;
411
struct au_hinode *hdir;
412
static struct qstr base_name[] = {
414
.name = AUFS_WH_BASENAME,
415
.len = sizeof(AUFS_WH_BASENAME) - 1
418
.name = AUFS_WH_PLINKDIR,
419
.len = sizeof(AUFS_WH_PLINKDIR) - 1
422
struct au_ndx ndx = {
424
.flags = 0, /* always no dlgt */
428
const unsigned int mnt_flags = au_mntflags(sb);
429
const int do_plink = au_opt_test(mnt_flags, PLINK);
430
const int do_hinotify = au_opt_test(mnt_flags, UDBA_INOTIFY);
431
const int dlgt = au_test_dlgt(mnt_flags);
433
LKTRTrace("nfsmnt %p\n", nfsmnt);
434
BrWhMustWriteLock(br);
436
h_dir = h_root->d_inode;
438
/* doubly whiteouted */
439
wh = au_wh_lkup(h_root, base_name + 0, &ndx);
443
AuDebugOn(br->br_wh && br->br_wh != wh);
445
plink = au_wh_lkup(h_root, base_name + 1, &ndx);
446
err = PTR_ERR(plink);
449
AuDebugOn(br->br_plink && br->br_plink != plink);
458
if (unlikely(bindex >= 0 && do_hinotify))
459
hdir = au_hi(sb->s_root->d_inode, bindex);
460
switch (br->br_perm) {
465
clean_wh(h_dir, wh, dlgt, hdir);
466
clean_plink(h_dir, plink, dlgt, hdir);
469
case AuBr_RWNoLinkWH:
470
clean_wh(h_dir, wh, dlgt, hdir);
472
err = test_linkable(h_dir);
476
err = plink_dir(h_dir, plink, dlgt, hdir);
479
br->br_plink = dget(plink);
481
clean_plink(h_dir, plink, dlgt, hdir);
486
* for the moment, aufs supports the branch filesystem
487
* which does not support link(2).
488
* testing on FAT which does not support i_op->setattr() fully
489
* either, copyup failed.
490
* finally, such filesystem will not be used as the writable
493
err = test_linkable(h_dir);
499
vfsub_args_init(&vargs, &ign, dlgt, 0);
500
vfsub_ign_hinode(&vargs, IN_CREATE, hdir);
501
err = au_h_create(h_dir, wh, WH_MASK, &vargs,
504
else if (S_ISREG(wh->d_inode->i_mode))
507
AuErr("unknown %.*s/%.*s exists\n",
508
AuDLNPair(h_root), AuDLNPair(wh));
513
err = plink_dir(h_dir, plink, dlgt, hdir);
516
br->br_plink = dget(plink);
518
clean_plink(h_dir, plink, dlgt, hdir);
519
br->br_wh = dget(wh);
534
AuErr("%.*s doesn't support link(2), use noplink and rw+nolwh\n",
538
AuErr("an error(%d) on the writable branch %.*s(%s)\n",
539
err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
543
struct reinit_br_wh {
544
struct super_block *sb;
545
struct au_branch *br;
548
static void reinit_br_wh(void *arg)
551
struct reinit_br_wh *a = arg;
552
struct inode *h_dir, *dir;
553
struct dentry *h_root;
554
aufs_bindex_t bindex;
555
struct au_hin_ignore ign;
556
struct vfsub_args vargs;
559
AuDebugOn(!a->br->br_wh || !a->br->br_wh->d_inode || current->fsuid);
563
si_write_lock(a->sb);
564
if (unlikely(!au_br_writable(a->br->br_perm)))
566
bindex = au_br_index(a->sb, a->br->br_id);
567
if (unlikely(bindex < 0))
570
dir = a->sb->s_root->d_inode;
571
ii_read_lock_parent(dir);
572
h_root = dget_parent(a->br->br_wh);
573
h_dir = h_root->d_inode;
574
AuDebugOn(!h_dir->i_op || !h_dir->i_op->link);
575
vfsub_args_init(&vargs, &ign, /*dlgt*/0, 0);
576
mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
577
vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex));
578
br_wh_write_lock(a->br);
579
if (!au_verify_parent(a->br->br_wh, h_dir))
580
err = vfsub_unlink(h_dir, a->br->br_wh, &vargs);
582
AuWarn("%.*s is moved, ignored\n", AuDLNPair(a->br->br_wh));
588
err = au_wh_init(h_root, a->br, au_do_nfsmnt(a->br->br_mnt),
590
br_wh_write_unlock(a->br);
591
mutex_unlock(&h_dir->i_mutex);
596
atomic_dec_return(&a->br->br_wh_running);
598
si_write_unlock(a->sb);
601
AuIOErr("err %d\n", err);
604
static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
607
struct reinit_br_wh *arg;
610
if (atomic_inc_return(&br->br_wh_running) != 1)
614
arg = kmalloc(sizeof(*arg), GFP_NOFS);
617
* dec(wh_running), kfree(arg) and au_br_put()
623
wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*dlgt*/0);
624
if (unlikely(wkq_err)) {
625
atomic_dec_return(&br->br_wh_running);
634
atomic_dec_return(&br->br_wh_running);
638
* create the whiteout @wh.
640
static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
641
struct dentry *wh, struct inode *dir)
644
struct au_branch *br;
645
struct dentry *h_parent;
647
struct au_hin_ignore ign;
648
struct vfsub_args vargs;
650
LKTRTrace("%.*s\n", AuDLNPair(wh));
651
h_parent = wh->d_parent; /* dir inode is locked */
652
h_dir = h_parent->d_inode;
655
dlgt = !!au_test_dlgt(au_mntflags(sb));
656
br = au_sbr(sb, bindex);
659
vfsub_args_init(&vargs, &ign, dlgt, 0);
661
vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex));
662
err = vfsub_link(br->br_wh, h_dir, wh, &vargs);
663
if (!err || err != -EMLINK)
666
/* link count full. re-initialize br_wh. */
667
kick_reinit_br_wh(sb, br);
670
/* return this error in this context */
671
vfsub_args_init(&vargs, &ign, dlgt, 0);
673
vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex));
674
err = au_h_create(h_dir, wh, WH_MASK, &vargs, /*nd*/NULL,
675
au_do_nfsmnt(br->br_mnt));
678
br_wh_read_unlock(br);
683
/* ---------------------------------------------------------------------- */
686
* create or remove the diropq.
688
static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
691
struct dentry *opq_dentry, *h_dentry;
694
struct super_block *sb;
695
struct au_ndx ndx = {
701
LKTRTrace("%.*s, bindex %d, flags 0x%x\n",
702
AuDLNPair(dentry), bindex, flags);
703
h_dentry = au_h_dptr(dentry, bindex);
704
AuDebugOn(!h_dentry);
705
h_dir = h_dentry->d_inode;
706
AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode));
708
/* already checked by au_test_h_perm(). */
710
ndx.nfsmnt = au_nfsmnt(sb, bindex);
712
if (unlikely(au_ftest_diropq(flags, DLGT))) {
714
au_fset_ndx(ndx.flags, DLGT);
716
opq_dentry = au_lkup_one(diropq_name.name, h_dentry, diropq_name.len,
718
if (IS_ERR(opq_dentry))
721
if (au_ftest_diropq(flags, CREATE)) {
722
AuDebugOn(opq_dentry->d_inode);
723
err = link_or_create_wh(dentry->d_sb, bindex, opq_dentry,
726
au_set_dbdiropq(dentry, bindex);
727
goto out; /* success */
730
AuDebugOn(/* !S_ISDIR(dentry->d_inode->i_mode)
731
* || */!opq_dentry->d_inode);
732
err = do_unlink_wh(au_hi(dentry->d_inode, bindex),
733
/*h_dir*/NULL, opq_dentry, dlgt);
735
au_set_dbdiropq(dentry, -1);
738
opq_dentry = ERR_PTR(err);
741
AuTraceErrPtr(opq_dentry);
745
struct do_diropq_args {
746
struct dentry **errp;
747
struct dentry *dentry;
748
aufs_bindex_t bindex;
752
static void call_do_diropq(void *args)
754
struct do_diropq_args *a = args;
755
*a->errp = do_diropq(a->dentry, a->bindex, a->flags);
758
struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
761
struct dentry *diropq, *h_dentry;
763
LKTRTrace("%.*s, bindex %d, flags 0x%x\n",
764
AuDLNPair(dentry), bindex, flags);
766
h_dentry = au_h_dptr(dentry, bindex);
767
if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE,
768
au_ftest_diropq(flags, DLGT)))
769
diropq = do_diropq(dentry, bindex, flags);
772
struct do_diropq_args args = {
778
wkq_err = au_wkq_wait(call_do_diropq, &args, /*dlgt*/0);
779
if (unlikely(wkq_err))
780
diropq = ERR_PTR(wkq_err);
783
AuTraceErrPtr(diropq);
787
/* ---------------------------------------------------------------------- */
790
* lookup whiteout dentry.
791
* @h_parent: hidden parent dentry which must exist and be locked
792
* @base_name: name of dentry which will be whiteouted
793
* returns dentry for whiteout.
795
struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
800
struct dentry *wh_dentry;
802
LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(base_name));
804
err = au_wh_name_alloc(base_name->name, base_name->len, &wh_name);
805
wh_dentry = ERR_PTR(err);
807
/* do not superio. */
808
wh_dentry = au_lkup_one(wh_name.name, h_parent,
810
au_wh_name_free(&wh_name);
812
AuTraceErrPtr(wh_dentry);
817
* link/create a whiteout for @dentry on @bindex.
819
struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
820
struct dentry *h_parent, struct au_ndx *ndx)
822
struct dentry *wh_dentry;
825
struct super_block *sb;
827
LKTRTrace("%.*s/%.*s on b%d\n", AuDLNPair(h_parent),
828
AuDLNPair(dentry), bindex);
831
wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, ndx);
832
if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
833
dir = dentry->d_parent->d_inode; /* dir is locked */
835
err = link_or_create_wh(sb, bindex, wh_dentry, dir);
837
au_set_dbwh(dentry, bindex);
840
wh_dentry = ERR_PTR(err);
844
AuTraceErrPtr(wh_dentry);
848
/* ---------------------------------------------------------------------- */
850
/* Delete all whiteouts in this directory on branch bindex. */
851
static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
852
aufs_bindex_t bindex, struct au_ndx *ndx)
857
struct inode *h_inode;
858
struct hlist_head *head;
859
struct au_vdir_wh *tpos;
860
struct hlist_node *pos;
861
struct au_vdir_destr *str;
863
LKTRTrace("%.*s\n", AuDLNPair(h_dentry));
864
h_inode = h_dentry->d_inode;
865
AuDebugOn(IS_RDONLY(h_inode));
870
if (unlikely(!wh_name.name))
872
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
873
p += AUFS_WH_PFX_LEN;
875
/* already checked by au_test_h_perm(). */
877
for (i = 0; !err && i < AuSize_NHASH; i++) {
878
head = whlist->heads + i;
879
hlist_for_each_entry(tpos, pos, head, wh_hash) {
880
if (tpos->wh_bindex != bindex)
883
if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
884
memcpy(p, str->name, str->len);
885
wh_name.len = AUFS_WH_PFX_LEN + str->len;
886
err = unlink_wh_name(h_dentry, &wh_name, ndx);
891
AuIOErr("whiteout name too long %.*s\n",
892
str->len, str->name);
897
__putname(wh_name.name);
904
struct del_wh_children_args {
906
struct dentry *h_dentry;
907
struct au_nhash *whlist;
908
aufs_bindex_t bindex;
912
static void call_del_wh_children(void *args)
914
struct del_wh_children_args *a = args;
915
*a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->ndx);
918
/* ---------------------------------------------------------------------- */
921
* rmdir the whiteouted temporary named dir @h_dentry.
922
* @whlist: whiteouted children.
924
int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
925
struct dentry *wh_dentry, struct au_nhash *whlist)
928
struct inode *wh_inode, *h_dir;
929
struct super_block *sb;
930
unsigned int mnt_flags;
931
struct au_hin_ignore ign;
932
struct vfsub_args vargs;
933
struct au_ndx ndx = {
939
LKTRTrace("i%lu, %.*s, b%d\n",
940
dir->i_ino, AuDLNPair(wh_dentry), bindex);
943
h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
947
mnt_flags = au_mntflags(sb);
948
dlgt = !!au_test_dlgt(mnt_flags);
950
au_fset_ndx(ndx.flags, DLGT);
951
ndx.nfsmnt = au_nfsmnt(sb, bindex);
952
wh_inode = wh_dentry->d_inode;
953
mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
956
* someone else might change some whiteouts while we were sleeping.
957
* it means this whlist may have an obsoleted entry.
959
if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE, dlgt))
960
err = del_wh_children(wh_dentry, whlist, bindex, &ndx);
964
unsigned int flags = ndx.flags;
965
struct del_wh_children_args args = {
967
.h_dentry = wh_dentry,
974
wkq_err = au_wkq_wait(call_del_wh_children, &args, /*dlgt*/0);
975
if (unlikely(wkq_err))
979
mutex_unlock(&wh_inode->i_mutex);
982
vfsub_args_init(&vargs, &ign, dlgt, 0);
983
vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex));
984
err = vfsub_rmdir(h_dir, wh_dentry, &vargs);
985
/* d_drop(h_dentry); */
989
if (au_ibstart(dir) == bindex) {
990
au_cpup_attr_timesizes(dir);
991
/* au_cpup_attr_nlink(dir); */
994
return 0; /* success */
997
AuWarn("failed removing %.*s(%d), ignored\n",
998
AuDLNPair(wh_dentry), err);
1002
static void au_whtmp_rmdir_free_args(struct au_whtmp_rmdir_args *args)
1004
au_nhash_fin(&args->whlist);
1005
dput(args->wh_dentry);
1010
static void call_rmdir_whtmp(void *args)
1013
struct au_whtmp_rmdir_args *a = args;
1014
struct super_block *sb;
1016
LKTRTrace("%.*s, b%d, dir i%lu\n",
1017
AuDLNPair(a->wh_dentry), a->bindex, a->dir->i_ino);
1019
mutex_lock(&a->dir->i_mutex);
1021
si_noflush_read_lock(sb);
1022
err = au_test_ro(sb, a->bindex, NULL);
1026
ii_write_lock_parent(a->dir);
1028
struct dentry *h_parent;
1029
struct inode *h_dir;
1031
h_parent = dget_parent(a->wh_dentry);
1032
h_dir = h_parent->d_inode;
1033
mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
1034
if (!au_verify_parent(a->wh_dentry, h_dir)) {
1036
err = au_whtmp_rmdir(a->dir, a->bindex,
1037
a->wh_dentry, &a->whlist);
1039
mutex_unlock(&h_dir->i_mutex);
1042
ii_write_unlock(a->dir);
1044
mutex_unlock(&a->dir->i_mutex);
1046
au_whtmp_rmdir_free_args(a);
1048
AuIOErr("err %d\n", err);
1051
void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
1052
struct dentry *wh_dentry, struct au_nhash *whlist,
1053
struct au_whtmp_rmdir_args *args)
1057
LKTRTrace("%.*s\n", AuDLNPair(wh_dentry));
1060
/* all post-process will be done in do_rmdir_whtmp(). */
1061
args->dir = igrab(dir);
1062
args->bindex = bindex;
1063
args->wh_dentry = dget(wh_dentry);
1064
au_nhash_init(&args->whlist);
1065
au_nhash_move(&args->whlist, whlist);
1066
wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb, /*dlgt*/0);
1067
if (unlikely(wkq_err)) {
1068
AuWarn("rmdir error %.*s (%d), ignored\n",
1069
AuDLNPair(wh_dentry), wkq_err);
1070
au_whtmp_rmdir_free_args(args);