16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
/* $Id: i_op_del.c,v 1.60 2008/03/16 23:45:04 sfjro Exp $ */
20
* inode operations (del entry)
22
* $Id: i_op_del.c,v 1.62 2008/04/13 23:42:32 sfjro Exp $
37
41
AuDLNPair(dentry), isdir, *bcpup, locked);
40
bstart = dbstart(dentry);
44
bstart = au_dbstart(dentry);
41
45
LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);
42
46
h_dentry = au_h_dptr(dentry);
45
49
if (au_test_ro(sb, bstart, dentry->d_inode)) {
46
err = AuWbrCopyup(stosi(sb), dentry);
50
err = AuWbrCopyup(au_sbi(sb), dentry);
49
53
if (unlikely(err < 0))
64
68
//struct nameidata nd;
65
69
aufs_bindex_t old_bend, new_bend, bdiropq = -1;
66
old_bend = dbend(dentry);
70
old_bend = au_dbend(dentry);
68
bdiropq = dbdiropq(dentry);
69
set_dbdiropq(dentry, -1);
72
bdiropq = au_dbdiropq(dentry);
73
au_set_dbdiropq(dentry, -1);
71
75
need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
76
set_dbdiropq(dentry, bdiropq);
80
au_set_dbdiropq(dentry, bdiropq);
77
81
if (unlikely(err < 0))
79
new_bend = dbend(dentry);
83
new_bend = au_dbend(dentry);
80
84
if (!need_wh && old_bend != new_bend) {
81
set_h_dptr(dentry, new_bend, NULL);
82
set_dbend(dentry, old_bend);
85
au_set_h_dptr(dentry, new_bend, NULL);
86
au_set_dbend(dentry, old_bend);
83
87
#if 0 // remove this?
84
88
} else if (!au_h_dptr_i(dentry, new_bend)->d_inode) {
85
89
LKTRTrace("negative\n");
86
set_h_dptr(dentry, new_bend, NULL);
87
set_dbend(dentry, old_bend);
90
au_set_h_dptr(dentry, new_bend, NULL);
91
au_set_dbend(dentry, old_bend);
102
106
* following the checks in vfs, plus the parent-child relationship.
104
108
int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
105
struct dentry *h_parent, int isdir, struct aufs_ndx *ndx)
109
struct dentry *h_parent, int isdir, struct au_ndx *ndx)
108
112
struct super_block *sb;
148
152
* some filesystem may unlink a dir and corrupt its consistency.
149
153
* so let's try heavy test.
151
if (1 /*unlikely(au_flag_test_udba_inotify(sb))*/) {
155
if (1 /*unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))*/) {
152
156
struct dentry *h_latest;
153
157
struct qstr *qstr = &dentry->d_name;
156
if (unlikely(au_test_perm(h_parent->d_inode,
157
MAY_EXEC | MAY_WRITE,
158
au_ftest_ndx(ndx->flags, DLGT))))
160
if (unlikely(au_test_h_perm(h_parent->d_inode,
161
MAY_EXEC | MAY_WRITE,
162
au_ftest_ndx(ndx->flags, DLGT))))
161
165
h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len,
182
186
int err, need_wh;
183
187
struct dentry *h_parent, *parent, *gparent;
184
188
struct inode *dir, *h_dir, *gdir;
186
190
struct super_block *sb;
187
struct aufs_hinode *hgdir;
191
struct au_hinode *hgdir;
188
192
aufs_bindex_t bcpup;
193
unsigned int mnt_flags;
190
195
LKTRTrace("%.*s, isdir %d\n", AuDLNPair(dentry), isdir);
202
207
sb = dentry->d_sb;
208
mnt_flags = au_mntflags(sb);
203
209
parent = dentry->d_parent; /* dir inode is locked */
204
if (unlikely(au_flag_test_udba_inotify(sb) && !IS_ROOT(parent))) {
210
if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
211
&& !IS_ROOT(parent))) {
205
212
gparent = dget_parent(parent);
206
213
gdir = gparent->d_inode;
207
214
ii_read_lock_parent2(gdir);
208
hgdir = itohi(gdir, bcpup);
215
hgdir = au_hi(gdir, bcpup);
209
216
ii_read_unlock(gdir);
215
222
h_dir = h_parent->d_inode;
217
224
AuDbgSleep_UdbaRace();
218
hdir_lock(h_dir, dir, bcpup);
225
au_hdir_lock(h_dir, dir, bcpup);
220
if (AuFlag(stosi(sb), f_udba) != AuUdba_NONE
221
&& dbstart(dentry) == bcpup) {
227
if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) {
222
228
ndx.nfsmnt = au_nfsmnt(sb, bcpup);
224
if (unlikely(au_need_dlgt(sb)))
230
if (unlikely(au_opt_test_dlgt(mnt_flags)))
225
231
au_fset_ndx(ndx.flags, DLGT);
227
//ndx.br = stobr(sb, bcpup);
233
//ndx.br = au_sbr(sb, bcpup);
228
234
//ndx.nd_file = NULL;
229
235
err = au_may_del(dentry, bcpup, h_parent, isdir, &ndx);
230
236
wh_dentry = ERR_PTR(err);
240
246
ndx.nfsmnt = au_nfsmnt(sb, bcpup);
242
if (unlikely(au_need_dlgt(sb)))
248
if (unlikely(au_opt_test_dlgt(mnt_flags)))
243
249
au_fset_ndx(ndx.flags, DLGT);
246
wh_dentry = simple_create_wh(dir, dentry, bcpup, h_parent, &ndx);
252
wh_dentry = au_wh_create(dir, dentry, bcpup, h_parent, &ndx);
247
253
//wh_dentry = ERR_PTR(-1);
248
254
if (!IS_ERR(wh_dentry))
249
255
goto out; /* success */
250
256
/* returns with the parent is locked and wh_dentry is DGETed */
253
hdir_unlock(h_dir, dir, bcpup);
259
au_hdir_unlock(h_dir, dir, bcpup);
255
261
AuTraceErrPtr(wh_dentry);
256
262
return wh_dentry;
259
265
static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
260
struct aufs_nhash *whlist, struct inode *dir)
266
struct au_nhash *whlist, struct inode *dir)
262
268
int rmdir_later, err;
263
269
struct dentry *hidden_dentry;
264
270
struct inode *inode, *h_inode;
271
struct super_block *sb;
266
273
LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex);
270
if (unlikely(au_flag_test_udba_inotify(dentry->d_sb))) {
278
if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) {
271
279
inode = dentry->d_inode;
272
280
h_inode = au_h_iptr_i(inode, bindex);
273
hdir2_lock(h_inode, inode, bindex);
281
au_hdir2_lock(h_inode, inode, bindex);
275
err = rename_whtmp(dir, dentry, bindex, /*noself*/1);
283
err = au_whtmp_ren(dir, dentry, bindex, /*noself*/1);
276
284
if (unlikely(inode))
277
hdir_unlock(h_inode, inode, bindex);
285
au_hdir_unlock(h_inode, inode, bindex);
279
287
if (unlikely(err))
282
290
hidden_dentry = au_h_dptr_i(dentry, bindex);
283
291
if (!au_test_nfs(hidden_dentry->d_sb)) {
284
const int dirwh = stosi(dentry->d_sb)->si_dirwh;
292
const int dirwh = au_sbi(sb)->si_dirwh;
285
293
rmdir_later = (dirwh <= 1);
286
294
if (!rmdir_later)
287
295
rmdir_later = nhash_test_longer_wh(whlist, bindex,
290
298
return rmdir_later;
293
err = rmdir_whtmp(hidden_dentry, whlist, bindex, dir, dentry->d_inode,
301
err = au_whtmp_rmdir(hidden_dentry, whlist, bindex, dir,
302
dentry->d_inode, /*noself*/1);
296
304
if (unlikely(err)) {
297
305
AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
312
320
dentry->d_inode->i_ctime = dir->i_ctime;
314
322
if (atomic_read(&dentry->d_count) == 1) {
315
set_h_dptr(dentry, dbstart(dentry), NULL);
323
au_set_h_dptr(dentry, au_dbstart(dentry), NULL);
316
324
au_update_dbstart(dentry);
318
if (ibstart(dir) == bindex)
326
if (au_ibstart(dir) == bindex)
319
327
au_cpup_attr_timesizes(dir);
320
328
dir->i_version++;
325
333
#define au_ftest_rev(flags, name) ((flags) & AuRev_##name)
326
334
#define au_fset_rev(flags, name) { (flags) |= AuRev_##name; }
327
335
#define au_fclr_rev(flags, name) { (flags) &= ~AuRev_##name; }
336
#ifndef CONFIG_AUFS_DLGT
329
341
static int do_revert(int err, struct dentry *wh_dentry, struct dentry *dentry,
330
aufs_bindex_t bwh, struct au_dtime *dt,
342
aufs_bindex_t bwh, struct au_dtime *dt, unsigned int flags)
334
345
struct inode *dir;
336
347
dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
338
rerr = au_unlink_wh_dentry(dir, wh_dentry, dentry, dir,
349
rerr = au_wh_unlink_dentry(dir, wh_dentry, dentry, dir,
339
350
au_ftest_rev(flags, DLGT));
342
set_dbwh(dentry, bwh);
353
au_set_dbwh(dentry, bwh);
343
354
au_dtime_revert(dt);
372
383
parent = dentry->d_parent; /* dir inode is locked */
373
384
di_write_lock_parent(parent);
375
bstart = dbstart(dentry);
386
bstart = au_dbstart(dentry);
387
bwh = au_dbwh(dentry);
378
389
wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt);
379
390
//wh_dentry = ERR_PTR(-1);
416
427
epilog(dir, dentry, bindex);
429
/* update target timestamps */
430
if (bindex == bstart) {
431
au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
432
inode->i_ctime = h_dentry->d_inode->i_ctime;
434
//todo: this timestamp may be reverted later
435
inode->i_ctime = h_dir->i_ctime;
417
436
goto out_unlock; /* success */
448
467
struct dentry *parent, *wh_dentry, *h_dentry;
449
468
struct au_dtime dt;
450
469
aufs_bindex_t bwh, bindex, bstart;
451
struct rmdir_whtmp_args *args;
452
struct aufs_nhash *whlist;
470
struct au_whtmp_rmdir_args *args;
471
struct au_nhash *whlist;
453
472
struct super_block *sb;
473
unsigned int mnt_flags;
455
475
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
513
533
sb = dentry->d_sb;
534
mnt_flags = au_mntflags(sb);
515
536
//aufs_bindex_t bi, bend;
517
if (unlikely(au_flag_test_udba_inotify(sb) && rmdir_later))
538
if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
518
540
au_reset_hinotify(inode, /*flags*/0);
519
541
inode->i_nlink = 0;
520
set_dbdiropq(dentry, -1);
542
au_set_dbdiropq(dentry, -1);
521
543
epilog(dir, dentry, bindex);
523
545
if (rmdir_later) {
524
kick_rmdir_whtmp(h_dentry, whlist, bstart, dir,
525
inode, /*noself*/1, args);
546
au_whtmp_kick_rmdir(h_dentry, whlist, bstart, dir,
547
inode, /*noself*/1, args);