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

« back to all changes in this revision

Viewing changes to fs/aufs25/i_op_del.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-08-21 14:58:54 UTC
  • mfrom: (1.1.8 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080821145854-4b49x09r4zmvlk5o
Tags: 0+20080719-4
01_vserver_apparmor.dpatch: [UPDATE] Disable vserver patches on kernel 
2.6.26, because they are not needed anymore. (Closes: #495921)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
/*
20
20
 * inode operations (del entry)
21
21
 *
22
 
 * $Id: i_op_del.c,v 1.6 2008/06/02 02:38:21 sfjro Exp $
 
22
 * $Id: i_op_del.c,v 1.9 2008/07/14 00:16:08 sfjro Exp $
23
23
 */
24
24
 
25
25
#include "aufs.h"
175
175
 
176
176
static struct dentry *
177
177
lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
178
 
                    struct au_dtime *dt)
 
178
                    struct au_dtime *dt, struct au_pin *pin)
179
179
{
180
180
        struct dentry *wh_dentry;
181
181
        int err, need_wh;
182
 
        struct dentry *h_parent, *parent, *gparent;
183
 
        struct inode *dir, *h_dir, *gdir;
 
182
        struct dentry *h_parent;
184
183
        struct au_ndx ndx;
185
184
        struct super_block *sb;
186
 
        struct au_hinode *hgdir;
187
185
        aufs_bindex_t bcpup;
188
186
        unsigned int mnt_flags;
189
187
 
195
193
        if (unlikely(err < 0))
196
194
                goto out;
197
195
 
198
 
        /* todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled. */
199
 
        hgdir = NULL;
 
196
        sb = dentry->d_sb;
 
197
        mnt_flags = au_mntflags(sb);
200
198
        bcpup = *rbcpup;
201
 
        sb = dentry->d_sb;
202
 
        mnt_flags = au_mntflags(sb);
203
 
        parent = dentry->d_parent; /* dir inode is locked */
204
 
        if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
205
 
                     && !IS_ROOT(parent))) {
206
 
                gparent = dget_parent(parent);
207
 
                gdir = gparent->d_inode;
208
 
                ii_read_lock_parent2(gdir);
209
 
                hgdir = au_hi(gdir, bcpup);
210
 
                ii_read_unlock(gdir);
211
 
                dput(gparent);
212
 
        }
213
 
        dir = parent->d_inode;
214
 
        IMustLock(dir);
215
 
        h_parent = au_h_dptr(parent, bcpup);
216
 
        h_dir = h_parent->d_inode;
217
 
 
218
 
        AuDbgSleep_UdbaRace();
219
 
        au_hdir_lock(h_dir, dir, bcpup);
220
 
        /* todo: revalidate the lower dentry? */
221
 
 
 
199
        au_pin(pin, dentry, bcpup, /*di_locked*/1,
 
200
               /*do_gp*/au_opt_test(mnt_flags, UDBA_INOTIFY));
 
201
        h_parent = au_pinned_h_parent(pin, bcpup);
222
202
        if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) {
223
203
                ndx.nfsmnt = au_nfsmnt(sb, bcpup);
224
204
                ndx.flags = 0;
230
210
                err = au_may_del(dentry, bcpup, h_parent, isdir, &ndx);
231
211
                wh_dentry = ERR_PTR(err);
232
212
                if (unlikely(err))
233
 
                        goto out_dir;
 
213
                        goto out_unpin;
234
214
        }
235
215
 
236
 
        au_dtime_store(dt, parent, h_parent, hgdir);
 
216
        au_dtime_store(dt, au_pinned_parent(pin), h_parent,
 
217
                       au_pinned_hdir(pin, bcpup), au_pinned_hgdir(pin, bcpup));
237
218
        wh_dentry = NULL;
238
219
        if (!need_wh)
239
220
                goto out; /* success, no need to create whiteout */
244
225
                au_fset_ndx(ndx.flags, DLGT);
245
226
        ndx.nd = NULL;
246
227
        /* ndx.br = NULL; */
247
 
        wh_dentry = au_wh_create(dir, dentry, bcpup, h_parent, &ndx);
 
228
        wh_dentry = au_wh_create(dentry, bcpup, h_parent, &ndx);
248
229
        if (!IS_ERR(wh_dentry))
249
230
                goto out; /* success */
250
231
        /* returns with the parent is locked and wh_dentry is DGETed */
251
232
 
252
 
 out_dir:
253
 
        au_hdir_unlock(h_dir, dir, bcpup);
 
233
 out_unpin:
 
234
        au_unpin(pin);
254
235
 out:
255
236
        AuTraceErrPtr(wh_dentry);
256
237
        return wh_dentry;
272
253
        if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) {
273
254
                inode = dentry->d_inode;
274
255
                h_inode = au_h_iptr(inode, bindex);
275
 
                au_hdir2_lock(h_inode, inode, bindex);
276
 
        }
277
 
        err = au_whtmp_ren(dir, dentry, bindex, /*noself*/1);
278
 
        if (unlikely(inode))
279
 
                au_hdir_unlock(h_inode, inode, bindex);
 
256
                mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
 
257
        }
 
258
        h_dentry = au_h_dptr(dentry, bindex);
 
259
        err = au_whtmp_ren(dir, bindex, h_dentry);
 
260
        if (unlikely(inode)) {
 
261
                /* todo: bad approach? */
 
262
                if (!err)
 
263
                        au_hin_suspend(au_hi(inode, bindex));
 
264
                mutex_unlock(&h_inode->i_mutex);
 
265
        }
280
266
        if (unlikely(err))
281
267
                goto out;
282
268
 
283
 
        h_dentry = au_h_dptr(dentry, bindex);
284
269
        if (!au_test_nfs(h_dentry->d_sb)) {
285
270
                const int dirwh = au_sbi(sb)->si_dirwh;
286
271
                rmdir_later = (dirwh <= 1);
291
276
                        return rmdir_later;
292
277
        }
293
278
 
294
 
        err = au_whtmp_rmdir(h_dentry, whlist, bindex, dir, dentry->d_inode,
295
 
                             /*noself*/1);
 
279
        err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
296
280
        if (unlikely(err)) {
297
281
                AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
298
282
                        AuDLNPair(h_dentry), bindex, err);
 
283
                /* we do not revert the inotify watch */
299
284
                err = 0;
300
285
        }
301
286
 
330
315
#define AuRev_DLGT      0
331
316
#endif
332
317
 
333
 
static int do_revert(int err, struct dentry *wh_dentry, struct dentry *dentry,
334
 
                     aufs_bindex_t bwh, struct au_dtime *dt, unsigned int flags)
 
318
static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh,
 
319
                     struct dentry *wh_dentry, struct dentry *dentry,
 
320
                     struct au_dtime *dt, unsigned int flags)
335
321
{
336
322
        int rerr;
337
 
        struct inode *dir;
338
323
 
339
 
        dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
340
 
        IMustLock(dir);
341
 
        rerr = au_wh_unlink_dentry(dir, wh_dentry, dentry, dir,
 
324
        rerr = au_wh_unlink_dentry(au_hi(dir, bwh), wh_dentry, dentry,
342
325
                                   au_ftest_rev(flags, DLGT));
343
326
        if (!rerr) {
344
327
                au_set_dbwh(dentry, bwh);
361
344
        struct au_dtime dt;
362
345
        aufs_bindex_t bwh, bindex, bstart;
363
346
        struct super_block *sb;
 
347
        struct au_hin_ignore ign;
364
348
        struct vfsub_args vargs;
 
349
        struct au_pin pin;
365
350
 
366
351
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
367
352
        IMustLock(dir);
377
362
        bstart = au_dbstart(dentry);
378
363
        bwh = au_dbwh(dentry);
379
364
        bindex = -1;
380
 
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt);
 
365
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
381
366
        err = PTR_ERR(wh_dentry);
382
367
        if (IS_ERR(wh_dentry))
383
368
                goto out;
389
374
        dget(h_dentry);
390
375
 
391
376
        if (bindex == bstart) {
392
 
                vfsub_args_init(&vargs, NULL, dlgt, 0);
393
 
                h_dir = h_dentry->d_parent->d_inode; /* dir inode is locked */
394
 
                IMustLock(h_dir);
 
377
                vfsub_args_init(&vargs, &ign, dlgt, 0);
 
378
                vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin,
 
379
                                                                   bstart));
 
380
                h_dir = au_pinned_h_dir(&pin);
395
381
                err = vfsub_unlink(h_dir, h_dentry, &vargs);
396
382
        } else {
397
383
                /* dir inode is locked */
433
419
                rev_flags = 0;
434
420
                if (unlikely(dlgt))
435
421
                        au_fset_rev(rev_flags, DLGT);
436
 
                rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, rev_flags);
 
422
                rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt,
 
423
                                 rev_flags);
437
424
                if (rerr)
438
425
                        err = rerr;
439
426
        }
440
427
 
441
428
 out_unlock:
442
 
        au_hdir_unlock(h_dir, dir, bindex);
 
429
        au_unpin(&pin);
443
430
        dput(wh_dentry);
444
431
        dput(h_dentry);
445
432
 out:
452
439
int aufs_rmdir(struct inode *dir, struct dentry *dentry)
453
440
{
454
441
        int err, rmdir_later;
455
 
        struct inode *inode, *h_dir;
 
442
        struct inode *inode;
456
443
        struct dentry *parent, *wh_dentry, *h_dentry;
457
444
        struct au_dtime dt;
458
445
        aufs_bindex_t bwh, bindex, bstart;
460
447
        struct au_nhash *whlist;
461
448
        struct super_block *sb;
462
449
        unsigned int mnt_flags;
 
450
        struct au_pin pin;
463
451
 
464
452
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
465
453
        IMustLock(dir);
466
454
        inode = dentry->d_inode;
 
455
        err = -ENOENT; /* possible? */
467
456
        if (unlikely(!inode))
468
 
                return -ENOENT; /* possible? */
 
457
                goto out;
469
458
        IMustLock(inode);
470
459
 
471
 
        whlist = au_nhash_new(GFP_TEMPORARY);
 
460
        whlist = au_nhash_new(GFP_NOFS);
472
461
        err = PTR_ERR(whlist);
473
462
        if (IS_ERR(whlist))
474
463
                goto out;
475
464
 
476
465
        err = -ENOMEM;
477
 
        args = kmalloc(sizeof(*args), GFP_TEMPORARY);
 
466
        args = kmalloc(sizeof(*args), GFP_NOFS);
478
467
        if (unlikely(!args))
479
468
                goto out_whlist;
480
469
 
488
477
        bstart = au_dbstart(dentry);
489
478
        bwh = au_dbwh(dentry);
490
479
        bindex = -1;
491
 
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt);
 
480
        wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
492
481
        err = PTR_ERR(wh_dentry);
493
482
        if (IS_ERR(wh_dentry))
494
483
                goto out_args;
499
488
 
500
489
        rmdir_later = 0;
501
490
        if (bindex == bstart) {
502
 
                h_dir = h_dentry->d_parent->d_inode; /* dir inode is locked */
503
 
                IMustLock(h_dir);
504
491
                err = renwh_and_rmdir(dentry, bstart, whlist, dir);
505
492
                if (err > 0) {
506
493
                        rmdir_later = err;
510
497
                /* dir inode is locked */
511
498
                AuDebugOn(!wh_dentry
512
499
                          || wh_dentry->d_parent != au_h_dptr(parent, bindex));
513
 
                h_dir = wh_dentry->d_parent->d_inode;
514
 
                IMustLock(h_dir);
 
500
                IMustLock(wh_dentry->d_parent->d_inode);
515
501
                err = 0;
516
502
        }
517
503
 
526
512
                epilog(dir, dentry, bindex);
527
513
 
528
514
                if (rmdir_later) {
529
 
                        au_whtmp_kick_rmdir(h_dentry, whlist, bstart, dir,
530
 
                                            inode, /*noself*/1, args);
 
515
                        au_whtmp_kick_rmdir(dir, bstart, h_dentry, whlist,
 
516
                                            args);
531
517
                        args = NULL;
532
518
                }
533
519
 
543
529
                rev_flags = 0;
544
530
                if (unlikely(au_test_dlgt(mnt_flags)))
545
531
                        au_fset_rev(rev_flags, DLGT);
546
 
                rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, rev_flags);
 
532
                rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt,
 
533
                                 rev_flags);
547
534
                if (rerr)
548
535
                        err = rerr;
549
536
        }
550
537
 
551
538
 out_unlock:
552
 
        au_hdir_unlock(h_dir, dir, bindex);
 
539
        au_unpin(&pin);
553
540
        dput(wh_dentry);
554
541
        dput(h_dentry);
555
542
 out_args: