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

« back to all changes in this revision

Viewing changes to fs/aufs25/cpup.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
 * copy-up functions, see wbr_policy.c for copy-down
21
21
 *
22
 
 * $Id: cpup.c,v 1.7 2008/06/02 02:37:17 sfjro Exp $
 
22
 * $Id: cpup.c,v 1.10 2008/07/14 00:14:12 sfjro Exp $
23
23
 */
24
24
 
25
25
#include <linux/fs_stack.h>
121
121
 
122
122
/* keep the timestamps of the parent dir when cpup */
123
123
void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
124
 
                    struct dentry *h_dentry, struct au_hinode *hdir)
 
124
                    struct dentry *h_dentry, struct au_hinode *hinode,
 
125
                    struct au_hinode *hdir)
125
126
{
126
 
        struct inode *inode;
 
127
        struct inode *h_inode;
127
128
 
128
129
        LKTRTrace("%.*s, hdir %d\n", AuDLNPair(dentry), !!hdir);
129
130
        AuDebugOn(!dentry || !h_dentry || !h_dentry->d_inode);
130
131
 
131
132
        dt->dt_dentry = dentry;
132
133
        dt->dt_h_dentry = h_dentry;
 
134
        dt->dt_hinode = hinode;
133
135
        dt->dt_hdir = hdir;
134
 
        inode = h_dentry->d_inode;
135
 
        dt->dt_atime = inode->i_atime;
136
 
        dt->dt_mtime = inode->i_mtime;
 
136
        h_inode = h_dentry->d_inode;
 
137
        dt->dt_atime = h_inode->i_atime;
 
138
        dt->dt_mtime = h_inode->i_mtime;
137
139
        /* smp_mb(); */
138
140
}
139
141
 
141
143
{
142
144
        struct iattr attr;
143
145
        int err;
144
 
        struct au_hin_ignore ign;
 
146
        struct au_hin_ignore ign[2];
145
147
        struct vfsub_args vargs;
146
148
 
147
149
        LKTRTrace("%.*s\n", AuDLNPair(dt->dt_dentry));
151
153
        attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
152
154
                | ATTR_ATIME | ATTR_ATIME_SET;
153
155
 
154
 
        vfsub_args_init(&vargs, &ign,
 
156
        vfsub_args_init(&vargs, ign,
155
157
                        au_test_dlgt(au_mntflags(dt->dt_dentry->d_sb)), 0);
156
 
        if (unlikely(dt->dt_hdir))
157
 
                vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hdir);
 
158
        /*
 
159
         * IN_ATTRIB should be divided into
 
160
         * IN_ATTRIB_ATIME, IN_ATTRIB_MTIME ...,
 
161
         * and define all ORed new IN_ATTRIB macro.
 
162
         */
 
163
        vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hinode);
 
164
        vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hdir);
158
165
        err = vfsub_notify_change(dt->dt_h_dentry, &attr, &vargs);
159
166
        if (unlikely(err))
160
167
                AuWarn("restoring timestamps failed(%d). ignored\n", err);
162
169
 
163
170
/* ---------------------------------------------------------------------- */
164
171
 
165
 
static noinline_for_stack int
166
 
cpup_iattr(struct dentry *h_dst, struct dentry *h_src, int dlgt)
 
172
static noinline_for_stack
 
173
int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
 
174
               int dlgt, struct au_hinode *hdir)
167
175
{
168
176
        int err, sbits;
 
177
        struct dentry *h_dst;
169
178
        struct iattr ia;
170
179
        struct inode *h_isrc, *h_idst;
 
180
        struct au_hin_ignore ign;
171
181
        struct vfsub_args vargs;
172
182
 
 
183
        h_dst = au_h_dptr(dst, bindex);
173
184
        LKTRTrace("%.*s\n", AuDLNPair(h_dst));
174
185
        h_idst = h_dst->d_inode;
175
186
        /* todo? IMustLock(h_idst); */
186
197
        ia.ia_mtime = h_isrc->i_mtime;
187
198
        sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
188
199
 
189
 
        vfsub_args_init(&vargs, NULL, dlgt, /*force_unlink*/0);
 
200
        vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0);
 
201
        vfsub_ign_hinode(&vargs, IN_ATTRIB, hdir);
190
202
        err = vfsub_notify_change(h_dst, &ia, &vargs);
191
203
 
192
204
        /* is this nfs only? */
193
205
        if (!err && sbits && au_test_nfs(h_dst->d_sb)) {
194
206
                ia.ia_valid = ATTR_FORCE | ATTR_MODE;
195
207
                ia.ia_mode = h_isrc->i_mode;
 
208
                vfsub_args_reinit(&vargs);
 
209
                vfsub_ign_hinode(&vargs, IN_ATTRIB, hdir);
196
210
                err = vfsub_notify_change(h_dst, &ia, &vargs);
197
211
        }
198
212
 
208
222
 * to support a sparse file which is opened with O_APPEND,
209
223
 * we need to close the file.
210
224
 */
211
 
static noinline_for_stack int
212
 
cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc,
213
 
             loff_t len)
 
225
static noinline_for_stack
 
226
int cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc,
 
227
                 loff_t len, struct au_hinode *hdir)
214
228
{
215
229
        int err, i;
216
230
        struct super_block *sb;
264
278
 
265
279
        /* stop updating while we copyup */
266
280
        IMustLock(hidden[SRC].dentry->d_inode);
267
 
        err = au_copy_file(hidden[DST].file, hidden[SRC].file, len, sb);
 
281
        err = au_copy_file(hidden[DST].file, hidden[SRC].file, len, hdir, sb);
268
282
 
269
283
 out_dst_file:
270
284
        fput(hidden[DST].file);
277
291
        return err;
278
292
}
279
293
 
280
 
static noinline_for_stack int
281
 
au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
282
 
                   aufs_bindex_t bsrc, loff_t len, struct inode *h_inode,
283
 
                   struct inode *h_dir, struct dentry *h_dst, int dlgt)
 
294
static noinline_for_stack
 
295
int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
 
296
                       aufs_bindex_t bsrc, loff_t len, struct inode *h_inode,
 
297
                       struct inode *h_dir, struct dentry *h_dst, int dlgt,
 
298
                       struct au_hinode *hdir)
284
299
{
285
300
        int err, rerr;
286
301
        loff_t l;
 
302
        struct au_hin_ignore ign;
287
303
        struct vfsub_args vargs;
288
304
 
289
305
        AuTraceEnter();
293
309
        if (len == -1 || l < len)
294
310
                len = l;
295
311
        if (len)
296
 
                err = cpup_regular(dentry, bdst, bsrc, len);
 
312
                err = cpup_regular(dentry, bdst, bsrc, len, hdir);
297
313
        if (!err)
298
314
                goto out; /* success */
299
315
 
300
 
        vfsub_args_init(&vargs, NULL, dlgt, 0);
 
316
        vfsub_args_init(&vargs, &ign, dlgt, 0);
 
317
        vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
301
318
        rerr = vfsub_unlink(h_dir, h_dst, &vargs);
302
319
        if (rerr) {
303
320
                AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
310
327
        return err;
311
328
}
312
329
 
313
 
static noinline_for_stack int
314
 
au_do_cpup_symlink(struct dentry *h_dst, struct dentry *h_src,
315
 
                   struct inode *h_dir, umode_t mode, int dlgt)
 
330
static int au_do_cpup_symlink(struct dentry *h_dst, struct dentry *h_src,
 
331
                              struct inode *h_dir, umode_t mode,
 
332
                              struct vfsub_args *vargs)
316
333
{
317
334
        int err, symlen;
318
335
        char *sym;
334
351
 
335
352
        if (symlen > 0) {
336
353
                sym[symlen] = 0;
337
 
                err = vfsub_symlink(h_dir, h_dst, sym, mode, dlgt);
 
354
                err = vfsub_symlink(h_dir, h_dst, sym, mode, vargs);
338
355
        }
339
356
        __putname(sym);
340
357
 
344
361
}
345
362
 
346
363
/* return with hidden dst inode is locked */
347
 
static noinline_for_stack int
348
 
cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc,
349
 
           loff_t len, unsigned int flags, int dlgt)
 
364
static noinline_for_stack
 
365
int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc,
 
366
               loff_t len, unsigned int flags, int dlgt,
 
367
               struct dentry *dst_parent)
350
368
{
351
369
        int err, isdir, hinotify;
352
 
        struct dentry *h_src, *h_dst, *h_parent, *parent;
 
370
        struct dentry *h_src, *h_dst, *h_parent;
353
371
        struct inode *h_inode, *h_dir;
354
372
        struct au_dtime dt;
355
373
        umode_t mode;
356
374
        struct super_block *sb;
357
 
        struct au_hinode *hgdir;
 
375
        struct au_hinode *hgdir, *hdir;
358
376
        const int do_dt = au_ftest_cpup(flags, DTIME);
359
377
        unsigned int mnt_flags;
 
378
        struct au_hin_ignore ign;
 
379
        struct vfsub_args vargs;
360
380
 
361
381
        LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, dtime %u\n",
362
382
                  AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len,
371
391
        AuDebugOn(!h_inode);
372
392
 
373
393
        /* stop referencing while we are creating */
374
 
        parent = dget_parent(dentry);
375
394
        h_dst = au_h_dptr(dentry, bdst);
376
395
        AuDebugOn(h_dst && h_dst->d_inode);
377
396
        h_parent = h_dst->d_parent; /* dir inode is locked */
378
397
        h_dir = h_parent->d_inode;
379
398
        IMustLock(h_dir);
 
399
        AuDebugOn(h_parent != h_dst->d_parent);
380
400
 
 
401
        hdir = NULL;
381
402
        mnt_flags = au_mntflags(sb);
382
403
        hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY);
 
404
        if (unlikely(hinotify)) {
 
405
                hdir = au_hi(dst_parent->d_inode, bdst);
 
406
                AuDebugOn(hdir->hi_inode != h_dir);
 
407
        }
 
408
 
383
409
        if (do_dt) {
384
410
                hgdir = NULL;
385
 
                if (unlikely(hinotify && !IS_ROOT(parent))) {
 
411
                if (unlikely(hinotify && !IS_ROOT(dst_parent))) {
386
412
                        struct dentry *gparent;
387
 
                        gparent = dget_parent(parent);
 
413
                        gparent = dget_parent(dst_parent);
388
414
                        hgdir = au_hi(gparent->d_inode, bdst);
 
415
                        IMustLock(hgdir->hi_inode);
389
416
                        dput(gparent);
390
417
                }
391
 
                au_dtime_store(&dt, parent, h_parent, hgdir);
 
418
                au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir);
392
419
        }
393
420
 
394
421
        isdir = 0;
 
422
        vfsub_args_init(&vargs, &ign, dlgt, 0);
 
423
        vfsub_ign_hinode(&vargs, IN_CREATE, hdir);
395
424
        mode = h_inode->i_mode;
396
425
        switch (mode & S_IFMT) {
397
426
        case S_IFREG:
398
427
                /* stop updating while we are referencing */
399
428
                IMustLock(h_inode);
400
 
                err = au_h_create(h_dir, h_dst, mode | S_IWUSR, dlgt, NULL,
 
429
                err = au_h_create(h_dir, h_dst, mode | S_IWUSR, &vargs, NULL,
401
430
                                  au_nfsmnt(sb, bdst));
402
431
                if (!err)
403
432
                        err = au_do_cpup_regular(dentry, bdst, bsrc, len,
404
 
                                                 h_inode, h_dir, h_dst, dlgt);
 
433
                                                 h_inode, h_dir, h_dst, dlgt,
 
434
                                                 hdir);
405
435
                break;
406
436
        case S_IFDIR:
407
437
                isdir = 1;
408
 
                err = vfsub_mkdir(h_dir, h_dst, mode, dlgt);
 
438
                err = vfsub_mkdir(h_dir, h_dst, mode, &vargs);
409
439
                if (!err) {
410
440
                        /* setattr case: dir is not locked */
411
 
                        if (0 && au_ibstart(parent->d_inode) == bdst)
412
 
                                au_cpup_attr_nlink(parent->d_inode);
 
441
                        if (0 && au_ibstart(dst_parent->d_inode) == bdst)
 
442
                                au_cpup_attr_nlink(dst_parent->d_inode);
413
443
                        au_cpup_attr_nlink(dentry->d_inode);
414
444
                }
415
445
                break;
416
446
        case S_IFLNK:
417
 
                err = au_do_cpup_symlink(h_dst, h_src, h_dir, mode, dlgt);
 
447
                err = au_do_cpup_symlink(h_dst, h_src, h_dir, mode, &vargs);
418
448
                break;
419
449
        case S_IFCHR:
420
450
        case S_IFBLK:
424
454
        case S_IFSOCK:
425
455
                err = vfsub_mknod(h_dir, h_dst, mode,
426
456
                                  au_h_rdev(h_inode, /*h_mnt*/NULL, h_src),
427
 
                                  dlgt);
 
457
                                  &vargs);
428
458
                break;
429
459
        default:
430
460
                AuIOErr("Unknown inode type 0%o\n", mode);
442
472
 
443
473
        if (do_dt)
444
474
                au_dtime_revert(&dt);
445
 
        dput(parent);
446
475
        AuTraceErr(err);
447
476
        return err;
448
477
}
452
481
 * the caller must set the both of hidden dentries.
453
482
 * @len is for truncating when it is -1 copyup the entire file.
454
483
 */
455
 
int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
456
 
                   aufs_bindex_t bsrc, loff_t len, unsigned int flags)
 
484
static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
 
485
                          aufs_bindex_t bsrc, loff_t len, unsigned int flags,
 
486
                          struct dentry *dst_parent)
457
487
{
458
 
        int err, rerr, isdir, dlgt, plink;
459
 
        struct dentry *h_src, *h_dst, *parent, *h_parent;
 
488
        int err, rerr;
 
489
        struct dentry *h_src, *h_dst, *h_parent;
460
490
        struct inode *dst_inode, *h_dir, *inode;
461
491
        struct super_block *sb;
462
492
        aufs_bindex_t old_ibstart;
463
493
        struct au_dtime dt;
 
494
        struct au_hin_ignore ign;
464
495
        struct vfsub_args vargs;
465
 
        struct au_hinode *hgdir;
 
496
        struct au_hinode *hgdir, *hdir;
466
497
        unsigned int mnt_flags;
 
498
        unsigned char isdir, dlgt, plink, hinotify;
467
499
 
468
500
        LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n",
469
501
                  AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len,
479
511
        AuDebugOn(!h_src || !h_src->d_inode);
480
512
        inode = dentry->d_inode;
481
513
        IiMustWriteLock(inode);
482
 
        parent = dget_parent(dentry);
 
514
        if (!dst_parent)
 
515
                dst_parent = dget_parent(dentry);
 
516
        else
 
517
                dget(dst_parent);
483
518
 
484
519
        mnt_flags = au_mntflags(sb);
485
520
        dlgt = !!au_test_dlgt(mnt_flags);
486
521
        plink = !!au_opt_test(mnt_flags, PLINK);
 
522
        hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY);
 
523
        hdir = NULL;
 
524
        if (unlikely(hinotify))
 
525
                hdir = au_hi(dst_parent->d_inode, bdst);
487
526
        dst_inode = au_h_iptr(inode, bdst);
488
527
        if (unlikely(dst_inode)) {
489
528
                if (unlikely(!plink)) {
494
533
                }
495
534
 
496
535
                if (dst_inode->i_nlink) {
 
536
                        const int do_dt = au_ftest_cpup(flags, DTIME);
 
537
 
497
538
                        h_src = au_plink_lkup(sb, bdst, inode);
498
539
                        err = PTR_ERR(h_src);
499
540
                        if (IS_ERR(h_src))
500
541
                                goto out;
501
542
                        AuDebugOn(!h_src->d_inode);
502
 
                        err = vfsub_link(h_src, h_dir, h_dst, dlgt);
 
543
 
 
544
                        if (do_dt) {
 
545
                                hgdir = NULL;
 
546
                                if (unlikely(hinotify && !IS_ROOT(dst_parent))) {
 
547
                                        struct dentry *gparent;
 
548
                                        gparent = dget_parent(dst_parent);
 
549
                                        hgdir = au_hi(gparent->d_inode, bdst);
 
550
                                        IMustLock(hgdir->hi_inode);
 
551
                                        dput(gparent);
 
552
                                }
 
553
                                au_dtime_store(&dt, dst_parent, h_parent, hdir,
 
554
                                               hgdir);
 
555
                        }
 
556
                        vfsub_args_init(&vargs, &ign, dlgt, 0);
 
557
                        vfsub_ign_hinode(&vargs, IN_CREATE, hdir);
 
558
                        err = vfsub_link(h_src, h_dir, h_dst, &vargs);
 
559
                        if (do_dt)
 
560
                                au_dtime_revert(&dt);
503
561
                        dput(h_src);
504
562
                        goto out;
505
563
                } else
509
567
        }
510
568
 
511
569
        old_ibstart = au_ibstart(inode);
512
 
        err = cpup_entry(dentry, bdst, bsrc, len, flags, dlgt);
 
570
        err = cpup_entry(dentry, bdst, bsrc, len, flags, dlgt, dst_parent);
513
571
        if (unlikely(err))
514
572
                goto out;
515
573
        dst_inode = h_dst->d_inode;
516
574
        mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
517
575
 
518
576
        /* todo: test dlgt? */
519
 
        err = cpup_iattr(h_dst, h_src, dlgt);
 
577
        err = cpup_iattr(dentry, bdst, h_src, dlgt, hdir);
520
578
#if 0 /* reserved for future use */
521
579
        if (0 && !err)
522
580
                err = cpup_xattrs(h_src, h_dst);
539
597
        mutex_unlock(&dst_inode->i_mutex);
540
598
        hgdir = NULL;
541
599
        if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
542
 
                     && !IS_ROOT(parent))) {
 
600
                     && !IS_ROOT(dst_parent))) {
543
601
                struct dentry *gparent;
544
 
                gparent = dget_parent(parent);
 
602
                gparent = dget_parent(dst_parent);
545
603
                hgdir = au_hi(gparent->d_inode, bdst);
546
604
                dput(gparent);
547
605
        }
548
 
        au_dtime_store(&dt, parent, h_parent, hgdir);
549
 
        vfsub_args_init(&vargs, NULL, dlgt, 0);
 
606
        au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir);
 
607
        vfsub_args_init(&vargs, &ign, dlgt, 0);
 
608
        vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
550
609
        if (!isdir)
551
610
                rerr = vfsub_unlink(h_dir, h_dst, &vargs);
552
611
        else
558
617
        }
559
618
 
560
619
 out:
561
 
        dput(parent);
 
620
        dput(dst_parent);
562
621
        AuTraceErr(err);
563
622
        return err;
564
623
}
569
628
        aufs_bindex_t bdst, bsrc;
570
629
        loff_t len;
571
630
        unsigned int flags;
 
631
        struct dentry *dst_parent;
572
632
};
573
633
 
574
634
static void au_call_cpup_single(void *args)
575
635
{
576
636
        struct au_cpup_single_args *a = args;
577
637
        *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
578
 
                                  a->flags);
 
638
                                  a->flags, a->dst_parent);
579
639
}
580
640
 
581
641
int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
582
 
                       aufs_bindex_t bsrc, loff_t len, unsigned int flags)
 
642
                       aufs_bindex_t bsrc, loff_t len, unsigned int flags,
 
643
                       struct dentry *dst_parent)
583
644
{
584
645
        int err, wkq_err;
585
646
        struct dentry *h_dentry;
593
654
        mode = h_dentry->d_inode->i_mode & S_IFMT;
594
655
        if ((mode != S_IFCHR && mode != S_IFBLK)
595
656
            || capable(CAP_MKNOD))
596
 
                err = au_cpup_single(dentry, bdst, bsrc, len, flags);
 
657
                err = au_cpup_single(dentry, bdst, bsrc, len, flags,
 
658
                                     dst_parent);
597
659
        else {
598
660
                struct au_cpup_single_args args = {
599
661
                        .errp           = &err,
601
663
                        .bdst           = bdst,
602
664
                        .bsrc           = bsrc,
603
665
                        .len            = len,
604
 
                        .flags          = flags
 
666
                        .flags          = flags,
 
667
                        .dst_parent     = dst_parent
605
668
                };
606
669
                wkq_err = au_wkq_wait(au_call_cpup_single, &args, /*dlgt*/0);
607
670
                if (unlikely(wkq_err))
616
679
 * copyup the @dentry from the first active hidden branch to @bdst,
617
680
 * using au_cpup_single().
618
681
 */
619
 
int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
620
 
                   unsigned int flags)
 
682
static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
 
683
                          unsigned int flags)
621
684
{
622
685
        int err;
623
686
        struct inode *inode;
636
699
 
637
700
        err = au_lkup_neg(dentry, bdst);
638
701
        if (!err) {
639
 
                err = au_cpup_single(dentry, bdst, bsrc, len, flags);
 
702
                err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
640
703
                if (!err)
641
704
                        return 0; /* success */
642
705
 
711
774
 
712
775
/* ---------------------------------------------------------------------- */
713
776
 
714
 
static noinline_for_stack int
715
 
au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
716
 
              struct dentry *wh_dentry, struct file *file, loff_t len)
 
777
static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
 
778
                         struct dentry *wh_dentry, struct file *file,
 
779
                         loff_t len)
717
780
{
718
781
        int err;
719
782
        struct au_dinfo *dinfo;
731
794
        if (file)
732
795
                dinfo->di_hdentry[0 + bstart].hd_dentry
733
796
                        = au_h_fptr(file, au_fbstart(file))->f_dentry;
734
 
        err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME);
 
797
        err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, NULL);
735
798
        if (!err && file) {
736
799
                err = au_reopen_nondir(file);
737
800
                dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_bstart;
754
817
        struct super_block *sb;
755
818
        unsigned int mnt_flags;
756
819
        struct au_dtime dt;
 
820
        struct au_hin_ignore ign;
757
821
        struct vfsub_args vargs;
758
 
        struct au_hinode *hgdir;
 
822
        struct au_hinode *hgdir, *hdir;
759
823
        struct au_ndx ndx = {
760
824
                .nd     = NULL,
761
825
                .flags  = 0,
785
849
        if (IS_ERR(wh_dentry))
786
850
                goto out;
787
851
 
 
852
        hdir = NULL;
788
853
        hgdir = NULL;
789
 
        if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY)
790
 
                     && !IS_ROOT(parent))) {
791
 
                struct dentry *gparent;
792
 
                gparent = dget_parent(parent);
793
 
                hgdir = au_hi(gparent->d_inode, bdst);
794
 
                dput(gparent);
 
854
        if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY))) {
 
855
                hdir = au_hi(parent->d_inode, bdst);
 
856
                if (!IS_ROOT(parent)) {
 
857
                        struct dentry *gparent;
 
858
                        gparent = dget_parent(parent);
 
859
                        hgdir = au_hi(gparent->d_inode, bdst);
 
860
                        dput(gparent);
 
861
                }
795
862
        }
796
 
        au_dtime_store(&dt, parent, h_parent, hgdir);
 
863
        au_dtime_store(&dt, parent, h_parent, hdir, hgdir);
797
864
        err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
798
865
        if (unlikely(err))
799
866
                goto out_wh;
801
868
        AuDebugOn(!d_unhashed(dentry));
802
869
        /* dget first to force sillyrename on nfs */
803
870
        dget(wh_dentry);
804
 
        vfsub_args_init(&vargs, NULL, dlgt, 0);
 
871
        vfsub_args_init(&vargs, &ign, dlgt, 0);
 
872
        vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
805
873
        err = vfsub_unlink(h_parent->d_inode, wh_dentry, &vargs);
806
874
        if (unlikely(err)) {
807
875
                AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
900
968
        }
901
969
 
902
970
        /* slow loop, keep it simple and stupid */
 
971
        /* todo: try au_pin() */
903
972
        real_parent = parent;
904
973
        hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY);
905
974
        while (1) {
927
996
 
928
997
                /* somebody else might create while we were sleeping */
929
998
                if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
930
 
                        struct inode *h_dir = h_parent->d_inode,
931
 
                                *dir = parent->d_inode;
 
999
                        struct inode *h_gdir, *gdir,
 
1000
                                *h_dir = h_parent->d_inode;
932
1001
 
 
1002
                        /* todo: try au_pin() */
933
1003
                        if (au_h_dptr(d, bdst))
934
1004
                                au_update_dbstart(d);
935
1005
                        if (parent != locked)
936
1006
                                di_read_lock_parent3(parent, AuLock_IR);
937
1007
                        gparent = NULL;
 
1008
                        gdir = NULL;
 
1009
                        h_gdir = NULL;
938
1010
                        if (unlikely(hinotify && !IS_ROOT(parent))) {
939
1011
                                gparent = dget_parent(parent);
 
1012
                                gdir = gparent->d_inode;
940
1013
                                if (gparent != locked)
941
 
                                        ii_read_lock_parent4(gparent->d_inode);
942
 
                                else {
943
 
                                        dput(gparent);
944
 
                                        gparent = NULL;
945
 
                                }
 
1014
                                        ii_read_lock_parent4(gdir);
 
1015
                                h_gdir = au_h_iptr(gdir, bdst);
 
1016
                                mutex_lock_nested(&h_gdir->i_mutex,
 
1017
                                                  AuLsc_I_PARENT);
946
1018
                        }
947
 
                        au_hdir_lock(h_dir, dir, bdst);
 
1019
                        mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT2);
948
1020
                        err = cp(d, bdst, h_parent, arg);
949
 
                        au_hdir_unlock(h_dir, dir, bdst);
 
1021
                        mutex_unlock(&h_dir->i_mutex);
950
1022
                        if (unlikely(gparent)) {
951
 
                                ii_read_unlock(gparent->d_inode);
 
1023
                                mutex_unlock(&h_gdir->i_mutex);
 
1024
                                if (gparent != locked)
 
1025
                                        ii_read_unlock(gdir);
952
1026
                                dput(gparent);
953
1027
                        }
954
1028
                        if (parent != locked)
1008
1082
                goto out;
1009
1083
 
1010
1084
        di_read_unlock(parent, AuLock_IR);
1011
 
        di_write_lock_parent2(parent);
 
1085
        di_write_lock_parent(parent);
1012
1086
        /* someone else might change our inode while we were sleeping */
1013
1087
        if (unlikely(!au_h_iptr(dir, bdst)))
1014
1088
                err = au_cpup_dirs(dentry, bdst, locked);