~ubuntu-branches/ubuntu/quantal/aufs/quantal

« back to all changes in this revision

Viewing changes to fs/aufs/dentry.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-04-01 18:26:37 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080401182637-ujuqq47eiggw4y5w
Tags: 0+20080401-1
* New upstream snapshot
  - Remove bashisms in script (Closes: #471288)
* debian/conf.mk, linux-patch-aufs.kpatches.sysfs_get_dentry:
  - Remove support for this patch, no longer used
* debian/conf.mk:
  - Add hacks for arm to armel (Closes: #473767)
* debian/control:
  - Add Dm-Upload-Allowed
* debian/copyright:
  - Use http://wiki.debian.org/Proposals/CopyrightFormat
* debian/linux-patch-aufs.kpatches.{splice,put_filp}:
  - Add support for Kernel 2.6.24 (and 2.6.25)
* debian/patches:
  - 01_vserver_apparmor: Update patch
  - 06_rt: Add patch for realtime kernel
  - 07_splice_hack: Add hack to support splice operations (Closes: #473430)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2005, 2006, 2007 Junjiro Okajima
 
2
 * Copyright (C) 2005, 2006, 2007, 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: dentry.c,v 1.65 2008/01/21 04:57:48 sfjro Exp $ */
 
19
/* $Id: dentry.c,v 1.72 2008/03/31 07:42:05 sfjro Exp $ */
20
20
 
21
21
//#include <linux/fs.h>
22
22
//#include <linux/namei.h>
132
132
        struct qstr this;
133
133
        unsigned int c;
134
134
        struct nameidata tmp_nd, *ndo;
135
 
        int err;
 
135
        int err, dirperm1;
136
136
 
137
137
        dentry = ERR_PTR(-EACCES);
138
138
        this.name = name;
163
163
        tmp_nd.dentry = dget(parent);
164
164
        tmp_nd.mnt = mntget(ndx->nfsmnt);
165
165
#ifndef CONFIG_AUFS_DLGT
 
166
        dirperm1 = 0;
166
167
        dentry = vfsub__lookup_hash(&this, parent, &tmp_nd);
167
168
#else
168
 
        if (!ndx->dlgt)
 
169
        dirperm1 = au_ftest_ndx(ndx->flags, DIRPERM1);
 
170
        if (!dirperm1 && !au_ftest_ndx(ndx->flags, DLGT))
169
171
                dentry = vfsub__lookup_hash(&this, parent, &tmp_nd);
170
172
        else {
171
173
                int wkq_err;
175
177
                        .base   = parent,
176
178
                        .nd     = &tmp_nd
177
179
                };
178
 
                wkq_err = au_wkq_wait(au_call_lookup_hash, &args, /*dlgt*/1);
 
180
                wkq_err = au_wkq_wait(au_call_lookup_hash, &args,
 
181
                                      /*dlgt*/!dirperm1);
179
182
                if (unlikely(wkq_err))
180
183
                        dentry = ERR_PTR(wkq_err);
181
184
        }
249
252
{
250
253
        struct dentry *dentry;
251
254
 
252
 
        LKTRTrace("%.*s/%.*s, ndx{%d, %d}\n",
253
 
                  AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->dlgt);
 
255
        LKTRTrace("%.*s/%.*s, ndx{%d, 0x%x}\n",
 
256
                  AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->flags);
254
257
 
255
258
        ndx->nd_file = NULL;
256
259
        if (!ndx->nfsmnt) {
257
260
#ifndef CONFIG_AUFS_DLGT
258
261
                dentry = vfsub_lookup_one_len(name, parent, len);
259
262
#else
260
 
                if (!ndx->dlgt)
 
263
                int dirperm1 = au_ftest_ndx(ndx->flags, DIRPERM1);
 
264
                if (!dirperm1 && !au_ftest_ndx(ndx->flags, DLGT))
261
265
                        dentry = vfsub_lookup_one_len(name, parent, len);
262
266
                else {
263
267
                        int wkq_err;
268
272
                                .len    = len
269
273
                        };
270
274
                        wkq_err = au_wkq_wait(au_call_lookup_one_len, &args,
271
 
                                              /*dlgt*/1);
 
275
                                              /*dlgt*/!dirperm1);
272
276
                        if (unlikely(wkq_err))
273
277
                                dentry = ERR_PTR(wkq_err);
274
278
                }
282
286
}
283
287
#endif /* !defined(AuNoNfsBranch) || defined(CONFIG_AUFS_DLGT) */
284
288
 
 
289
#ifdef CONFIG_AUFS_ROBR
 
290
static int au_test_robr_wh(struct qstr *name, struct dentry *h_parent,
 
291
                           struct qstr *wh_name, int try_sio,
 
292
                           struct aufs_ndx *ndx)
 
293
{
 
294
        if (strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
 
295
                return au_test_wh(h_parent, wh_name, try_sio, ndx);
 
296
        return -EPERM;
 
297
}
 
298
 
 
299
static int au_test_robr_shwh(struct super_block *sb, const struct qstr *name)
 
300
{
 
301
        return 0;
 
302
}
 
303
 
 
304
#else
 
305
 
 
306
static int au_test_robr_wh(struct qstr *name, struct dentry *h_parent,
 
307
                           struct qstr *wh_name, int try_sio,
 
308
                           struct aufs_ndx *ndx)
 
309
{
 
310
        return au_test_wh(h_parent, wh_name, try_sio, ndx);
 
311
}
 
312
 
 
313
static int au_test_robr_shwh(struct super_block *sb, const struct qstr *name)
 
314
{
 
315
        if (unlikely(!au_flag_test_shwh(sb)
 
316
                     && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
 
317
                return -EPERM;
 
318
        return 0;
 
319
}
 
320
 
 
321
#endif /* CONFIG_AUFS_ROBR */
 
322
 
285
323
struct au_lkup_one_args {
286
324
        struct dentry **errp;
287
325
        const char *name;
296
334
        *a->errp = au_lkup_one(a->name, a->parent, a->len, a->ndx);
297
335
}
298
336
 
 
337
#define AuLkup_ALLOW_NEG        1
 
338
#define AuLkup_DLGT             (1 << 1)
 
339
#define AuLkup_DIRPERM1         (1 << 2)
 
340
#define au_ftest_lkup(flags, name)      ((flags) & AuLkup_##name)
 
341
#define au_fset_lkup(flags, name)       { (flags) |= AuLkup_##name; }
 
342
#define au_fclr_lkup(flags, name)       { (flags) &= ~AuLkup_##name; }
 
343
 
299
344
struct au_do_lookup_args {
300
 
        unsigned int            allow_neg:1;
301
 
        unsigned int            dlgt:1;
 
345
        unsigned int            flags;
302
346
        mode_t                  type;
303
347
        struct nameidata        *nd;
304
348
};
314
358
{
315
359
        struct dentry *h_dentry;
316
360
        int wh_found, wh_able, opq;
317
 
        struct inode *h_dir, *h_inode;
 
361
        struct inode *h_dir, *h_inode, *inode;
318
362
        struct qstr *name;
319
363
        struct super_block *sb;
320
364
        struct nameidata tmp_nd;
321
365
        struct aufs_ndx ndx = {
322
 
                .dlgt   = args->dlgt,
 
366
                .flags  = 0,
323
367
                .nd     = args->nd
324
368
        };
 
369
        const int allow_neg = au_ftest_lkup(args->flags, ALLOW_NEG);
325
370
 
326
 
        LKTRTrace("%.*s/%.*s, b%d, {allow_neg %d, type 0%o, dlgt %d, nd %d}\n",
 
371
        LKTRTrace("%.*s/%.*s, b%d, {flags 0x%x, type 0%o, nd %d}\n",
327
372
                  AuDLNPair(h_parent), AuDLNPair(dentry), bindex,
328
 
                  args->allow_neg, args->type, args->dlgt, !!args->nd);
 
373
                  args->flags, args->type, !!args->nd);
329
374
        AuDebugOn(IS_ROOT(dentry));
330
375
        h_dir = h_parent->d_inode;
331
376
 
332
377
        wh_found = 0;
333
378
        sb = dentry->d_sb;
334
379
        ndx.nfsmnt = au_nfsmnt(sb, bindex);
 
380
        if (unlikely(au_ftest_lkup(args->flags, DLGT)))
 
381
                au_fset_ndx(ndx.flags, DLGT);
 
382
        if (unlikely(au_ftest_lkup(args->flags, DIRPERM1)))
 
383
                au_fset_ndx(ndx.flags, DIRPERM1);
335
384
        LKTRTrace("nfsmnt %p\n", ndx.nfsmnt);
336
385
        ndx.br = stobr(sb, bindex);
337
386
        wh_able = br_whable(ndx.br->br_perm);
338
387
        name = &dentry->d_name;
339
 
        if (unlikely(wh_able)) {
340
 
#ifdef CONFIG_AUFS_ROBR
341
 
                wh_found = -EPERM;
342
 
                if (strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
343
 
                        wh_found = au_test_wh(h_parent, wh_name, /*try_sio*/0,
344
 
                                              &ndx);
345
 
#else
346
 
                wh_found = au_test_wh(h_parent, wh_name, /*try_sio*/0, &ndx);
347
 
#endif
348
 
        }
 
388
        if (unlikely(wh_able))
 
389
                wh_found = au_test_robr_wh(name, h_parent, wh_name,
 
390
                                           /*try_sio*/0, &ndx);
349
391
        //if (LktrCond) wh_found = -1;
350
392
        h_dentry = ERR_PTR(wh_found);
351
393
        if (!wh_found)
356
398
        /* We found a whiteout */
357
399
        //set_dbend(dentry, bindex);
358
400
        set_dbwh(dentry, bindex);
359
 
        if (!args->allow_neg)
 
401
        if (!allow_neg)
360
402
                return NULL; /* success */
361
403
        if (unlikely(ndx.nd
362
404
                     && au_test_nfs(h_parent->d_sb)
375
417
        AuDebugOn(d_unhashed(h_dentry));
376
418
        h_inode = h_dentry->d_inode;
377
419
        if (!h_inode) {
378
 
                if (!args->allow_neg)
 
420
                if (!allow_neg)
379
421
                        goto out_neg;
380
422
        } else if (wh_found
381
423
                   || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
404
446
        }
405
447
#endif
406
448
 
407
 
        if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able)
 
449
        inode = dentry->d_inode;
 
450
        if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
 
451
            || (inode && !S_ISDIR(inode->i_mode)))
408
452
                return h_dentry; /* success */
409
453
 
410
454
        vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD);
430
474
/*
431
475
 * returns the number of hidden positive dentries,
432
476
 * otherwise an error.
 
477
 * can be called at unlinking with @type is zero.
433
478
 */
434
479
int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
435
480
                   struct nameidata *nd)
436
481
{
437
 
        int npositive, err;
 
482
        int npositive, err, isdir;
438
483
        struct dentry *parent;
439
 
        aufs_bindex_t bindex, btail;
 
484
        aufs_bindex_t bindex, btail, bdiropq;
440
485
        const struct qstr *name = &dentry->d_name;
441
486
        struct qstr whname;
442
487
        struct super_block *sb;
 
488
        struct inode *inode;
443
489
        struct au_do_lookup_args args = {
444
490
                .type   = type,
445
491
                .nd     = nd
451
497
        /* dir may not be locked */
452
498
        parent = dget_parent(dentry);
453
499
 
454
 
#ifndef CONFIG_AUFS_ROBR
455
 
        err = -EPERM;
456
 
        if (unlikely(!strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
 
500
        err = au_test_robr_shwh(dentry->d_sb, name);
 
501
        if (unlikely(err))
457
502
                goto out;
458
 
#endif
459
503
 
460
504
        err = au_alloc_whname(name->name, name->len, &whname);
461
505
        //if (LktrCond) {au_free_whname(&whname); err = -1;}
463
507
                goto out;
464
508
 
465
509
        sb = dentry->d_sb;
466
 
        args.dlgt = !!au_need_dlgt(sb);
467
 
        args.allow_neg = !type;
 
510
        inode = dentry->d_inode;
 
511
        isdir = (inode && S_ISDIR(inode->i_mode));
 
512
        args.flags = 0;
 
513
        if (unlikely(au_need_dlgt(sb)))
 
514
                au_fset_lkup(args.flags, DLGT);
 
515
        if (unlikely(au_need_dirperm1(sb)))
 
516
                au_fset_lkup(args.flags, DIRPERM1);
 
517
        if (!type)
 
518
                au_fset_lkup(args.flags, ALLOW_NEG);
468
519
        npositive = 0;
469
520
        btail = dbtaildir(parent);
470
521
        for (bindex = bstart; bindex <= btail; bindex++) {
495
546
                err = PTR_ERR(h_dentry);
496
547
                if (IS_ERR(h_dentry))
497
548
                        goto out_wh;
498
 
                args.allow_neg = 0;
 
549
                au_fclr_lkup(args.flags, ALLOW_NEG);
499
550
 
500
551
                if (dbwh(dentry) >= 0)
501
552
                        break;
509
560
                        args.type = h_inode->i_mode & S_IFMT;
510
561
                if (args.type != S_IFDIR)
511
562
                        break;
512
 
                else if (dbdiropq(dentry) >= 0)
513
 
                        break;
 
563
                else if (isdir) {
 
564
                        /* the type of lowers may be different */
 
565
                        bdiropq = dbdiropq(dentry);
 
566
                        if (bdiropq >= 0 && bdiropq <= bindex)
 
567
                                break;
 
568
                }
514
569
        }
515
570
 
516
571
        if (npositive) {
535
590
 
536
591
        LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name);
537
592
 
538
 
        if (!au_test_perm(parent->d_inode, MAY_EXEC, ndx->dlgt))
 
593
        if (!au_test_perm_sio(parent->d_inode, MAY_EXEC,
 
594
                              au_ftest_ndx(ndx->flags, DLGT)))
539
595
                dentry = au_lkup_one(name, parent, len, ndx);
540
596
        else {
541
597
                // ugly
542
 
                int dlgt = ndx->dlgt;
 
598
                unsigned int flags = ndx->flags;
543
599
                struct au_lkup_one_args args = {
544
600
                        .errp   = &dentry,
545
601
                        .name   = name,
548
604
                        .ndx    = ndx
549
605
                };
550
606
 
551
 
                ndx->dlgt = 0;
 
607
                au_fclr_ndx(ndx->flags, DLGT);
 
608
                au_fclr_ndx(ndx->flags, DIRPERM1);
552
609
                wkq_err = au_wkq_wait(au_call_lkup_one, &args, /*dlgt*/0);
553
610
                if (unlikely(wkq_err))
554
611
                        dentry = ERR_PTR(wkq_err);
555
 
                ndx->dlgt = dlgt;
 
612
                ndx->flags = flags;
556
613
        }
557
614
 
558
615
        AuTraceErrPtr(dentry);
568
625
        struct dentry *parent, *h_parent, *h_dentry;
569
626
        struct inode *h_dir;
570
627
        struct aufs_ndx ndx = {
 
628
                .flags  = 0,
571
629
                .nd     = NULL,
572
630
                //.br   = NULL
573
631
        };
585
643
 
586
644
        sb = dentry->d_sb;
587
645
        ndx.nfsmnt = au_nfsmnt(sb, bindex);
588
 
        ndx.dlgt = au_need_dlgt(sb);
 
646
        if (unlikely(au_need_dlgt(sb)))
 
647
                au_fset_ndx(ndx.flags, DLGT);
 
648
        if (unlikely(au_need_dirperm1(sb)))
 
649
                au_fset_ndx(ndx.flags, DIRPERM1);
589
650
        h_dentry = au_sio_lkup_one(dentry->d_name.name, h_parent,
590
651
                                   dentry->d_name.len, &ndx);
591
652
        //if (LktrCond) {dput(h_dentry); h_dentry = ERR_PTR(-1);}
625
686
        struct dentry *parent;
626
687
        aufs_bindex_t bindex, parent_bend, parent_bstart, bwh, bdiropq, bend;
627
688
        struct aufs_hdentry *p;
 
689
        au_gen_t sgen;
628
690
 
629
691
        LKTRTrace("%.*s, type 0%o\n", AuDLNPair(dentry), type);
630
692
        DiMustWriteLock(dentry);
631
693
        sb = dentry->d_sb;
632
694
        AuDebugOn(IS_ROOT(dentry));
 
695
        sgen = au_sigen(sb);
633
696
        parent = dget_parent(dentry);
634
 
        AuDebugOn(au_digen(parent) != au_sigen(sb));
 
697
        AuDebugOn(au_digen(parent) != sgen
 
698
                  || au_iigen(parent->d_inode) != sgen);
635
699
 
636
700
        npositive = -ENOMEM;
637
701
        new_sz = sizeof(*dinfo->di_hdentry) * (sbend(sb) + 1);
669
733
                if (dinfo->di_bdiropq == bindex)
670
734
                        bdiropq = new_bindex;
671
735
                if (new_bindex < 0) { // test here
672
 
                        hdput(p);
 
736
                        hdput(p, /*do_free*/0);
673
737
                        p->hd_dentry = NULL;
674
738
                        continue;
675
739
                }
727
791
        return npositive;
728
792
}
729
793
 
 
794
#ifdef CONFIG_AUFS_FAKE_DM
 
795
 
 
796
static int au_lock_nd(struct dentry *dentry, struct nameidata *nd)
 
797
{
 
798
        return 0;
 
799
}
 
800
 
 
801
static void au_unlock_nd(int locked, struct nameidata *nd)
 
802
{
 
803
        /* empty */
 
804
}
 
805
 
 
806
#else
 
807
 
 
808
static int au_lock_nd(struct dentry *dentry, struct nameidata *nd)
 
809
{
 
810
        int locked = 0;
 
811
        if (nd && dentry != nd->dentry) {
 
812
                di_read_lock_parent(nd->dentry, 0);
 
813
                locked = 1;
 
814
        }
 
815
        return locked;
 
816
}
 
817
 
 
818
static void au_unlock_nd(int locked, struct nameidata *nd)
 
819
{
 
820
        if (locked)
 
821
                di_read_unlock(nd->dentry, 0);
 
822
}
 
823
 
 
824
#endif /* CONFIG_AUFS_FAKE_DM */
 
825
 
730
826
static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
731
827
                          struct nameidata *nd, int do_udba)
732
828
{
773
869
        btail = bstart;
774
870
        if (inode && S_ISDIR(inode->i_mode))
775
871
                btail = dbtaildir(dentry);
776
 
        locked = 0;
777
 
#ifndef CONFIG_AUFS_FAKE_DM
778
 
        if (nd && dentry != nd->dentry) {
779
 
                di_read_lock_parent(nd->dentry, 0);
780
 
                locked = 1;
781
 
        }
782
 
#endif
 
872
        locked = au_lock_nd(dentry, nd);
783
873
        for (bindex = bstart; bindex <= btail; bindex++) {
784
874
                h_dentry = au_h_dptr_i(dentry, bindex);
785
 
                if (unlikely(!h_dentry))
 
875
                if (!h_dentry)
786
876
                        continue;
 
877
 
 
878
                LKTRTrace("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
 
879
//#define TestingFuse
 
880
#ifdef TestingFuse
 
881
                /* force re-lookup for fuse, in order to update attributes */
 
882
                if (unlikely(au_test_fuse(h_dentry->d_sb)))
 
883
                        goto err;
 
884
#endif
 
885
 
787
886
                if (unlikely(do_udba
788
887
                             && !is_root
789
888
                             && (unhashed != d_unhashed(h_dentry)
830
929
                                AuDebugOn(!nd);
831
930
                                e = au_hin_after_reval(p, dentry, bindex,
832
931
                                                       nd->intent.open.file);
 
932
#ifndef TestingFuse
833
933
                                au_update_fuse_h_inode(p->mnt, h_dentry);
834
934
                                /*ignore*/
 
935
#endif
835
936
                                if (unlikely(e && !err))
836
937
                                        err = e;
837
 
                        } else
 
938
                        }
 
939
#ifndef TestingFuse
 
940
                        else
838
941
                                au_update_fuse_h_inode(NULL, h_dentry);
839
942
                        /*ignore*/
 
943
#endif
840
944
                        au_fake_dm_release(p);
841
945
                        if (unlikely(err)) {
842
946
                                //AuDbg("here\n");
880
984
                err = -EINVAL;
881
985
                break;
882
986
        }
883
 
#ifndef CONFIG_AUFS_FAKE_DM
884
 
        if (unlikely(locked))
885
 
                di_read_unlock(nd->dentry, 0);
886
 
#endif
 
987
        au_unlock_nd(locked, nd);
887
988
 
888
989
        /*
889
990
         * judging by timestamps is meaningless since some filesystem uses
917
1018
        inode = dentry->d_inode;
918
1019
        AuDebugOn(!inode);
919
1020
 
920
 
        if (au_digen(dentry) == sgen)
 
1021
        if (au_digen(dentry) == sgen && au_iigen(inode) == sgen)
921
1022
                return 0;
922
1023
 
923
1024
        parent = dget_parent(dentry);
924
1025
        di_read_lock_parent(parent, AuLock_IR);
925
 
        AuDebugOn(au_digen(parent) != sgen);
 
1026
        AuDebugOn(au_digen(parent) != sgen
 
1027
                  || au_iigen(parent->d_inode) != sgen);
926
1028
#ifdef CONFIG_AUFS_DEBUG
927
1029
        {
928
1030
                int i, j;
965
1067
        AuDebugOn(!dentry->d_inode);
966
1068
        DiMustWriteLock(dentry);
967
1069
 
968
 
        if (!stosi(dentry->d_sb)->si_failed_refresh_dirs)
 
1070
        if (!au_ftest_si(stosi(dentry->d_sb), FAILED_REFRESH_DIRS))
969
1071
                return simple_reval_dpath(dentry, sgen);
970
1072
 
971
1073
        /* slow loop, keep it simple and stupid */
972
1074
        /* cf: au_cpup_dirs() */
973
1075
        err = 0;
974
1076
        parent = NULL;
975
 
        while (au_digen(dentry) != sgen) {
 
1077
        while (au_digen(dentry) != sgen || au_iigen(dentry->d_inode) != sgen) {
976
1078
                d = dentry;
977
1079
                while (1) {
978
1080
                        dput(parent);
979
1081
                        parent = dget_parent(d);
980
 
                        if (au_digen(parent) == sgen)
 
1082
                        if (au_digen(parent) == sgen
 
1083
                            && au_iigen(parent->d_inode) == sgen)
981
1084
                                break;
982
1085
                        d = parent;
983
1086
                }
989
1092
                }
990
1093
 
991
1094
                /* someone might update our dentry while we were sleeping */
992
 
                if (au_digen(d) != sgen) {
 
1095
                if (au_digen(d) != sgen || au_iigen(d->d_inode) != sgen) {
993
1096
                        di_read_lock_parent(parent, AuLock_IR);
994
1097
                        /* returns a number of positive dentries */
995
1098
                        err = au_refresh_hdentry(d, inode->i_mode & S_IFMT);
1048
1151
#ifdef ForceInotify
1049
1152
                AuDbg("UDBA or digen, %.*s\n", AuDLNPair(dentry));
1050
1153
#endif
1051
 
                //di_read_lock_child(dentry, AuLock_IR);err = -EINVAL; goto out;
1052
 
                //vfsub_i_lock(inode);
1053
1154
                di_write_lock_child(dentry);
1054
1155
                if (inode)
1055
1156
                        err = au_reval_dpath(dentry, sgen);
1056
1157
                //err = -1;
1057
1158
                di_downgrade_lock(dentry, AuLock_IR);
1058
 
                //vfsub_i_unlock(inode);
1059
1159
                if (unlikely(err))
1060
1160
                        goto out;
1061
 
                ii_read_unlock(inode);
1062
 
                AuDebugOn(au_iigen(inode) != sgen);
 
1161
                if (inode)
 
1162
                        ii_read_unlock(inode);
 
1163
                AuDebugOn(au_digen(dentry) != sgen);
1063
1164
        }
1064
1165
 
1065
1166
        if (inode) {
1073
1174
                        //AuDbgInode(inode);
1074
1175
                        //au_debug_off();
1075
1176
#endif
1076
 
                        //ii_read_lock_child(inode);err = -EINVAL; goto out;
1077
1177
                        ii_write_lock_child(inode);
1078
1178
                        err = au_refresh_hinode(inode, dentry);
1079
1179
                        ii_downgrade_lock(inode);
1094
1194
        }
1095
1195
#endif
1096
1196
 
 
1197
        AuDebugOn(au_digen(dentry) != sgen);
 
1198
        AuDebugOn(inode && au_iigen(inode) != sgen);
1097
1199
        err = -EINVAL;
1098
1200
        sbinfo = stosi(sb);
1099
1201
        do_udba = (AuFlag(sbinfo, f_udba) != AuUdba_NONE);
1147
1249
                p = dinfo->di_hdentry + bindex;
1148
1250
                while (bindex++ <= bend) {
1149
1251
                        if (p->hd_dentry)
1150
 
                                hdput(p);
 
1252
                                hdput(p, /*do_free*/1);
1151
1253
                        p++;
1152
1254
                }
1153
1255
        }