~ubuntu-branches/ubuntu/vivid/aufs/vivid

« back to all changes in this revision

Viewing changes to fs/aufs/i_op_del.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-05-06 18:35:50 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080506183550-0b6c974kkgc46oeh
Tags: 0+20080506-1
* New upstream release, supports Kernel 2.6.25 (Closes: #479717)
* Fix building with older Kernels (Closes: #475042)
* Update the patches 01, 04 and 07 to also patch fs/aufs25

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima
 
2
 * Copyright (C) 2005-2008 Junjiro Okajima
3
3
 *
4
4
 * This program, aufs is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: i_op_del.c,v 1.60 2008/03/16 23:45:04 sfjro Exp $ */
 
19
/*
 
20
 * inode operations (del entry)
 
21
 *
 
22
 * $Id: i_op_del.c,v 1.62 2008/04/13 23:42:32 sfjro Exp $
 
23
 */
20
24
 
21
25
#include "aufs.h"
22
26
 
37
41
                  AuDLNPair(dentry), isdir, *bcpup, locked);
38
42
        sb = dentry->d_sb;
39
43
 
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);
43
47
        if (*bcpup < 0) {
44
48
                *bcpup = bstart;
45
49
                if (au_test_ro(sb, bstart, dentry->d_inode)) {
46
 
                        err = AuWbrCopyup(stosi(sb), dentry);
 
50
                        err = AuWbrCopyup(au_sbi(sb), dentry);
47
51
                        *bcpup = err;
48
52
                        //err = -1;
49
53
                        if (unlikely(err < 0))
63
67
        } else {
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);
67
71
                if (isdir) {
68
 
                        bdiropq = dbdiropq(dentry);
69
 
                        set_dbdiropq(dentry, -1);
 
72
                        bdiropq = au_dbdiropq(dentry);
 
73
                        au_set_dbdiropq(dentry, -1);
70
74
                }
71
75
                need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
72
76
                                         /*nd*/NULL);
73
77
                err = need_wh;
74
78
                //err = -1;
75
79
                if (isdir)
76
 
                        set_dbdiropq(dentry, bdiropq);
 
80
                        au_set_dbdiropq(dentry, bdiropq);
77
81
                if (unlikely(err < 0))
78
82
                        goto out;
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);
88
92
                        need_wh = 0;
89
93
#endif
90
94
                }
102
106
 * following the checks in vfs, plus the parent-child relationship.
103
107
 */
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)
106
110
{
107
111
        int err, exist;
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.
150
154
         */
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;
154
158
 
155
159
                err = -EACCES;
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))))
159
163
                        goto out;
160
164
 
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;
185
 
        struct aufs_ndx ndx;
 
189
        struct au_ndx ndx;
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;
189
194
 
190
195
        LKTRTrace("%.*s, isdir %d\n", AuDLNPair(dentry), isdir);
191
196
 
200
205
        hgdir = NULL;
201
206
        bcpup = *rbcpup;
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);
210
217
                dput(gparent);
211
218
        }
215
222
        h_dir = h_parent->d_inode;
216
223
 
217
224
        AuDbgSleep_UdbaRace();
218
 
        hdir_lock(h_dir, dir, bcpup);
 
225
        au_hdir_lock(h_dir, dir, bcpup);
219
226
 
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);
223
229
                ndx.flags = 0;
224
 
                if (unlikely(au_need_dlgt(sb)))
 
230
                if (unlikely(au_opt_test_dlgt(mnt_flags)))
225
231
                        au_fset_ndx(ndx.flags, DLGT);
226
232
                ndx.nd = NULL;
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);
239
245
 
240
246
        ndx.nfsmnt = au_nfsmnt(sb, bcpup);
241
247
        ndx.flags = 0;
242
 
        if (unlikely(au_need_dlgt(sb)))
 
248
        if (unlikely(au_opt_test_dlgt(mnt_flags)))
243
249
                au_fset_ndx(ndx.flags, DLGT);
244
250
        ndx.nd = NULL;
245
251
        //ndx.br = NULL;
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 */
251
257
 
252
258
 out_dir:
253
 
        hdir_unlock(h_dir, dir, bcpup);
 
259
        au_hdir_unlock(h_dir, dir, bcpup);
254
260
 out:
255
261
        AuTraceErrPtr(wh_dentry);
256
262
        return wh_dentry;
257
263
}
258
264
 
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)
261
267
{
262
268
        int rmdir_later, err;
263
269
        struct dentry *hidden_dentry;
264
270
        struct inode *inode, *h_inode;
 
271
        struct super_block *sb;
265
272
 
266
273
        LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex);
267
274
 
268
275
        inode = NULL;
269
276
        h_inode = NULL;
270
 
        if (unlikely(au_flag_test_udba_inotify(dentry->d_sb))) {
 
277
        sb = 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);
274
282
        }
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);
278
286
        //err = -1;
279
287
        if (unlikely(err))
280
288
                goto out;
281
289
 
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;
291
299
        }
292
300
 
293
 
        err = rmdir_whtmp(hidden_dentry, whlist, bindex, dir, dentry->d_inode,
294
 
                          /*noself*/1);
 
301
        err = au_whtmp_rmdir(hidden_dentry, whlist, bindex, dir,
 
302
                             dentry->d_inode, /*noself*/1);
295
303
        //err = -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;
313
321
 
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);
317
325
        }
318
 
        if (ibstart(dir) == bindex)
 
326
        if (au_ibstart(dir) == bindex)
319
327
                au_cpup_attr_timesizes(dir);
320
328
        dir->i_version++;
321
329
}
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
 
337
#undef AuRev_DLGT
 
338
#define AuRev_DLGT      0
 
339
#endif
328
340
 
329
341
static int do_revert(int err, struct dentry *wh_dentry, struct dentry *dentry,
330
 
                     aufs_bindex_t bwh, struct au_dtime *dt,
331
 
                     unsigned int flags)
 
342
                     aufs_bindex_t bwh, struct au_dtime *dt, unsigned int flags)
332
343
{
333
344
        int rerr;
334
345
        struct inode *dir;
335
346
 
336
347
        dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
337
348
        IMustLock(dir);
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));
340
351
        //rerr = -1;
341
352
        if (!rerr) {
342
 
                set_dbwh(dentry, bwh);
 
353
                au_set_dbwh(dentry, bwh);
343
354
                au_dtime_revert(dt);
344
355
                return 0;
345
356
        }
372
383
        parent = dentry->d_parent; /* dir inode is locked */
373
384
        di_write_lock_parent(parent);
374
385
 
375
 
        bstart = dbstart(dentry);
376
 
        bwh = dbwh(dentry);
 
386
        bstart = au_dbstart(dentry);
 
387
        bwh = au_dbwh(dentry);
377
388
        bindex = -1;
378
389
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt);
379
390
        //wh_dentry = ERR_PTR(-1);
382
393
                goto out;
383
394
 
384
395
        sb = dir->i_sb;
385
 
        dlgt = au_need_dlgt(sb);
 
396
        dlgt = !!au_opt_test_dlgt(au_mntflags(sb));
386
397
        h_dentry = au_h_dptr(dentry);
387
398
        dget(h_dentry);
388
399
 
406
417
                inode->i_nlink--;
407
418
#if 0 //todo: update plink
408
419
                if (unlikely(!inode->i_nlink
409
 
                             && au_test_plink(sb, inode)
 
420
                             && au_plink_test(sb, inode)
410
421
                             /* && atomic_read(&inode->i_count) == 2) */)) {
411
422
                        au_debug_on();
412
423
                        DbgInode(inode);
414
425
                }
415
426
#endif
416
427
                epilog(dir, dentry, bindex);
 
428
 
 
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;
 
433
                } else
 
434
                        //todo: this timestamp may be reverted later
 
435
                        inode->i_ctime = h_dir->i_ctime;
417
436
                goto out_unlock; /* success */
418
437
        }
419
438
 
431
450
        }
432
451
 
433
452
 out_unlock:
434
 
        hdir_unlock(h_dir, dir, bindex);
 
453
        au_hdir_unlock(h_dir, dir, bindex);
435
454
        dput(wh_dentry);
436
455
        dput(h_dentry);
437
456
 out:
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;
454
474
 
455
475
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
456
476
        IMustLock(dir);
478
498
        if (unlikely(err))
479
499
                goto out_args;
480
500
 
481
 
        bstart = dbstart(dentry);
482
 
        bwh = dbwh(dentry);
 
501
        bstart = au_dbstart(dentry);
 
502
        bwh = au_dbwh(dentry);
483
503
        bindex = -1;
484
504
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt);
485
505
        //wh_dentry = ERR_PTR(-1);
511
531
        }
512
532
 
513
533
        sb = dentry->d_sb;
 
534
        mnt_flags = au_mntflags(sb);
514
535
        if (!err) {
515
536
                //aufs_bindex_t bi, bend;
516
537
 
517
 
                if (unlikely(au_flag_test_udba_inotify(sb) && rmdir_later))
 
538
                if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
 
539
                             && rmdir_later))
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);
522
544
 
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);
526
548
                        args = NULL;
527
549
                }
528
550
 
536
558
                unsigned int rev_flags;
537
559
 
538
560
                rev_flags = 0;
539
 
                if (unlikely(au_need_dlgt(sb)))
 
561
                if (unlikely(au_opt_test_dlgt(mnt_flags)))
540
562
                        au_fset_rev(rev_flags, DLGT);
541
563
                rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, rev_flags);
542
564
                if (rerr)
544
566
        }
545
567
 
546
568
 out_unlock:
547
 
        hdir_unlock(h_dir, dir, bindex);
 
569
        au_hdir_unlock(h_dir, dir, bindex);
548
570
        dput(wh_dentry);
549
571
        dput(h_dentry);
550
572
 out_args: