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
* inode operations (del entry)
22
* $Id: i_op_del.c,v 1.4 2008/05/04 23:54:53 sfjro Exp $
28
* 0: wh is unnecessary
29
* plus: wh is necessary
32
int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup,
33
struct dentry *locked)
37
struct dentry *h_dentry;
38
struct super_block *sb;
40
LKTRTrace("%.*s, isdir %d, *bcpup %d, locked %p\n",
41
AuDLNPair(dentry), isdir, *bcpup, locked);
44
bstart = au_dbstart(dentry);
45
LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);
46
h_dentry = au_h_dptr(dentry, bstart);
49
if (au_test_ro(sb, bstart, dentry->d_inode)) {
50
err = AuWbrCopyup(au_sbi(sb), dentry);
53
if (unlikely(err < 0))
57
AuDebugOn(bstart < *bcpup
58
|| au_test_ro(sb, *bcpup, dentry->d_inode));
59
LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);
61
if (*bcpup != bstart) {
62
err = au_cpup_dirs(dentry, *bcpup, locked);
68
//struct nameidata nd;
69
aufs_bindex_t old_bend, new_bend, bdiropq = -1;
70
old_bend = au_dbend(dentry);
72
bdiropq = au_dbdiropq(dentry);
73
au_set_dbdiropq(dentry, -1);
75
need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
80
au_set_dbdiropq(dentry, bdiropq);
81
if (unlikely(err < 0))
83
new_bend = au_dbend(dentry);
84
if (!need_wh && old_bend != new_bend) {
85
au_set_h_dptr(dentry, new_bend, NULL);
86
au_set_dbend(dentry, old_bend);
88
} else if (!au_h_dptr(dentry, new_bend)->d_inode) {
89
LKTRTrace("negative\n");
90
au_set_h_dptr(dentry, new_bend, NULL);
91
au_set_dbend(dentry, old_bend);
96
LKTRTrace("need_wh %d\n", need_wh);
105
* simple tests for the removal inode operations.
106
* following the checks in vfs, plus the parent-child relationship.
108
int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
109
struct dentry *h_parent, int isdir, struct au_ndx *ndx)
112
struct super_block *sb;
113
struct dentry *h_dentry;
114
struct inode *h_inode;
117
LKTRTrace("%.*s/%.*s, b%d, dir %d\n",
118
AuDLNPair(h_parent), AuDLNPair(dentry), bindex, isdir);
121
exist = !!dentry->d_inode;
122
h_dentry = au_h_dptr(dentry, bindex);
123
h_inode = h_dentry->d_inode;
126
if (unlikely(!h_inode || !h_inode->i_nlink))
129
h_mode = h_inode->i_mode;
132
if (unlikely(S_ISDIR(h_mode)))
134
} else if (unlikely(!S_ISDIR(h_mode))) {
141
if (unlikely(h_inode))
146
/* expected parent dir is locked */
147
if (unlikely(h_parent != h_dentry->d_parent))
152
* some filesystem may unlink a dir and corrupt its consistency.
153
* so let's try heavy test.
155
if (1 /*unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))*/) {
156
struct dentry *h_latest;
157
struct qstr *qstr = &dentry->d_name;
160
if (unlikely(au_test_h_perm(h_parent->d_inode,
161
MAY_EXEC | MAY_WRITE,
162
au_ftest_ndx(ndx->flags, DLGT))))
165
h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len,
167
//err = PTR_ERR(h_latest);
169
if (IS_ERR(h_latest))
172
if (h_latest == h_dentry)
181
static struct dentry *
182
lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
185
struct dentry *wh_dentry;
187
struct dentry *h_parent, *parent, *gparent;
188
struct inode *dir, *h_dir, *gdir;
190
struct super_block *sb;
191
struct au_hinode *hgdir;
193
unsigned int mnt_flags;
195
LKTRTrace("%.*s, isdir %d\n", AuDLNPair(dentry), isdir);
197
need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup, NULL);
200
wh_dentry = ERR_PTR(err);
201
if (unlikely(err < 0))
204
//todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled.
208
mnt_flags = au_mntflags(sb);
209
parent = dentry->d_parent; /* dir inode is locked */
210
if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
211
&& !IS_ROOT(parent))) {
212
gparent = dget_parent(parent);
213
gdir = gparent->d_inode;
214
ii_read_lock_parent2(gdir);
215
hgdir = au_hi(gdir, bcpup);
216
ii_read_unlock(gdir);
219
dir = parent->d_inode;
221
h_parent = au_h_dptr(parent, bcpup);
222
h_dir = h_parent->d_inode;
224
AuDbgSleep_UdbaRace();
225
au_hdir_lock(h_dir, dir, bcpup);
226
//todo: revalidate the lower dentry?
228
if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) {
229
ndx.nfsmnt = au_nfsmnt(sb, bcpup);
231
if (unlikely(au_opt_test_dlgt(mnt_flags)))
232
au_fset_ndx(ndx.flags, DLGT);
234
//ndx.br = au_sbr(sb, bcpup);
235
//ndx.nd_file = NULL;
236
err = au_may_del(dentry, bcpup, h_parent, isdir, &ndx);
237
wh_dentry = ERR_PTR(err);
242
au_dtime_store(dt, parent, h_parent, hgdir);
245
goto out; /* success, no need to create whiteout */
247
ndx.nfsmnt = au_nfsmnt(sb, bcpup);
249
if (unlikely(au_opt_test_dlgt(mnt_flags)))
250
au_fset_ndx(ndx.flags, DLGT);
253
wh_dentry = au_wh_create(dir, dentry, bcpup, h_parent, &ndx);
254
//wh_dentry = ERR_PTR(-1);
255
if (!IS_ERR(wh_dentry))
256
goto out; /* success */
257
/* returns with the parent is locked and wh_dentry is DGETed */
260
au_hdir_unlock(h_dir, dir, bcpup);
262
AuTraceErrPtr(wh_dentry);
266
static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
267
struct au_nhash *whlist, struct inode *dir)
269
int rmdir_later, err;
270
struct dentry *h_dentry;
271
struct inode *inode, *h_inode;
272
struct super_block *sb;
274
LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex);
279
if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) {
280
inode = dentry->d_inode;
281
h_inode = au_h_iptr(inode, bindex);
282
au_hdir2_lock(h_inode, inode, bindex);
284
err = au_whtmp_ren(dir, dentry, bindex, /*noself*/1);
286
au_hdir_unlock(h_inode, inode, bindex);
291
h_dentry = au_h_dptr(dentry, bindex);
292
if (!au_test_nfs(h_dentry->d_sb)) {
293
const int dirwh = au_sbi(sb)->si_dirwh;
294
rmdir_later = (dirwh <= 1);
296
rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
302
err = au_whtmp_rmdir(h_dentry, whlist, bindex, dir, dentry->d_inode,
306
AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
307
AuDLNPair(h_dentry), bindex, err);
316
static void epilog(struct inode *dir, struct dentry *dentry,
317
aufs_bindex_t bindex)
321
dentry->d_inode->i_ctime = dir->i_ctime;
323
if (atomic_read(&dentry->d_count) == 1) {
324
au_set_h_dptr(dentry, au_dbstart(dentry), NULL);
325
au_update_dbstart(dentry);
327
if (au_ibstart(dir) == bindex)
328
au_cpup_attr_timesizes(dir);
334
#define au_ftest_rev(flags, name) ((flags) & AuRev_##name)
335
#define au_fset_rev(flags, name) { (flags) |= AuRev_##name; }
336
#define au_fclr_rev(flags, name) { (flags) &= ~AuRev_##name; }
337
#ifndef CONFIG_AUFS_DLGT
342
static int do_revert(int err, struct dentry *wh_dentry, struct dentry *dentry,
343
aufs_bindex_t bwh, struct au_dtime *dt, unsigned int flags)
348
dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
350
rerr = au_wh_unlink_dentry(dir, wh_dentry, dentry, dir,
351
au_ftest_rev(flags, DLGT));
354
au_set_dbwh(dentry, bwh);
359
AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
360
AuDLNPair(dentry), err, rerr);
364
/* ---------------------------------------------------------------------- */
366
int aufs_unlink(struct inode *dir, struct dentry *dentry)
369
struct inode *inode, *h_dir;
370
struct dentry *parent, *wh_dentry, *h_dentry;
372
aufs_bindex_t bwh, bindex, bstart;
373
struct super_block *sb;
374
struct vfsub_args vargs;
376
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
378
inode = dentry->d_inode;
379
if (unlikely(!inode))
380
return -ENOENT; /* possible? */
383
aufs_read_lock(dentry, AuLock_DW);
384
parent = dentry->d_parent; /* dir inode is locked */
385
di_write_lock_parent(parent);
387
bstart = au_dbstart(dentry);
388
bwh = au_dbwh(dentry);
390
wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt);
391
//wh_dentry = ERR_PTR(-1);
392
err = PTR_ERR(wh_dentry);
393
if (IS_ERR(wh_dentry))
397
dlgt = !!au_opt_test_dlgt(au_mntflags(sb));
398
AuDebugOn(au_dbstart(dentry) != bstart);
399
h_dentry = au_h_dptr(dentry, bstart);
402
if (bindex == bstart) {
403
vfsub_args_init(&vargs, NULL, dlgt, 0);
404
h_dir = h_dentry->d_parent->d_inode; /* dir inode is locked */
406
err = vfsub_unlink(h_dir, h_dentry, &vargs);
409
/* dir inode is locked */
411
|| wh_dentry->d_parent != au_h_dptr(parent, bindex));
412
h_dir = wh_dentry->d_parent->d_inode;
419
#if 0 //todo: update plink
420
if (unlikely(!inode->i_nlink
421
&& au_plink_test(sb, inode)
422
/* && atomic_read(&inode->i_count) == 2) */)) {
428
epilog(dir, dentry, bindex);
430
/* update target timestamps */
431
if (bindex == bstart) {
432
au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
433
inode->i_ctime = h_dentry->d_inode->i_ctime;
435
//todo: this timestamp may be reverted later
436
inode->i_ctime = h_dir->i_ctime;
437
goto out_unlock; /* success */
443
unsigned int rev_flags;
447
au_fset_rev(rev_flags, DLGT);
448
rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, rev_flags);
454
au_hdir_unlock(h_dir, dir, bindex);
458
di_write_unlock(parent);
459
aufs_read_unlock(dentry, AuLock_DW);
464
int aufs_rmdir(struct inode *dir, struct dentry *dentry)
466
int err, rmdir_later;
467
struct inode *inode, *h_dir;
468
struct dentry *parent, *wh_dentry, *h_dentry;
470
aufs_bindex_t bwh, bindex, bstart;
471
struct au_whtmp_rmdir_args *args;
472
struct au_nhash *whlist;
473
struct super_block *sb;
474
unsigned int mnt_flags;
476
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
478
inode = dentry->d_inode;
479
if (unlikely(!inode))
480
return -ENOENT; /* possible? */
483
whlist = au_nhash_new(GFP_TEMPORARY);
484
err = PTR_ERR(whlist);
489
args = kmalloc(sizeof(*args), GFP_TEMPORARY);
494
aufs_read_lock(dentry, AuLock_DW);
495
parent = dentry->d_parent; /* dir inode is locked */
496
di_write_lock_parent(parent);
497
err = au_test_empty(dentry, whlist);
502
bstart = au_dbstart(dentry);
503
bwh = au_dbwh(dentry);
505
wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt);
506
//wh_dentry = ERR_PTR(-1);
507
err = PTR_ERR(wh_dentry);
508
if (IS_ERR(wh_dentry))
511
AuDebugOn(au_dbstart(dentry) != bstart);
512
h_dentry = au_h_dptr(dentry, bstart);
516
if (bindex == bstart) {
517
h_dir = h_dentry->d_parent->d_inode; /* dir inode is locked */
519
err = renwh_and_rmdir(dentry, bstart, whlist, dir);
526
/* dir inode is locked */
528
|| wh_dentry->d_parent != au_h_dptr(parent, bindex));
529
h_dir = wh_dentry->d_parent->d_inode;
535
mnt_flags = au_mntflags(sb);
537
//aufs_bindex_t bi, bend;
539
if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
541
au_reset_hinotify(inode, /*flags*/0);
543
au_set_dbdiropq(dentry, -1);
544
epilog(dir, dentry, bindex);
547
au_whtmp_kick_rmdir(h_dentry, whlist, bstart, dir,
548
inode, /*noself*/1, args);
552
goto out_unlock; /* success */
559
unsigned int rev_flags;
562
if (unlikely(au_opt_test_dlgt(mnt_flags)))
563
au_fset_rev(rev_flags, DLGT);
564
rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, rev_flags);
570
au_hdir_unlock(h_dir, dir, bindex);
574
di_write_unlock(parent);
575
aufs_read_unlock(dentry, AuLock_DW);
578
au_nhash_del(whlist);