28
26
* and update version.
29
27
* if it failed, re-create the removed whiteout.
31
static int epilog(struct dentry *wh_dentry, struct dentry *dentry)
29
static int epilog(struct inode *dir, struct dentry *wh_dentry,
30
struct dentry *dentry)
35
struct inode *inode, *dir;
36
struct dentry *wh, *parent;
37
struct lkup_args lkup;
39
LKTRTrace("wh %p, %.*s\n", wh_dentry, DLNPair(dentry));
42
lkup.dlgt = need_dlgt(dentry->d_sb);
34
struct inode *inode, *h_dir;
38
LKTRTrace("wh %p, %.*s\n", wh_dentry, AuDLNPair(dentry));
45
parent = dget_parent(wh_dentry);
42
h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
46
44
bwh = dbwh(dentry);
47
err = au_unlink_wh_dentry(parent->d_inode, wh_dentry, dentry,
45
err = au_unlink_wh_dentry(h_dir, wh_dentry, dentry, dir,
74
lkup.nfsmnt = au_nfsmnt(dentry->d_sb, bwh);
75
wh = simple_create_wh(dentry, bwh, parent, &lkup);
70
ndx.dlgt = au_need_dlgt(dentry->d_sb);
71
ndx.nfsmnt = au_nfsmnt(dentry->d_sb, bwh);
74
/* dir inode is locked */
75
wh = simple_create_wh(dir, dentry, bwh, wh_dentry->d_parent, &ndx);
76
76
//wh = ERR_PTR(-1);
77
77
rerr = PTR_ERR(wh);
82
IOErr("%.*s reverting whiteout failed(%d, %d)\n",
83
DLNPair(dentry), err, rerr);
82
AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
83
AuDLNPair(dentry), err, rerr);
95
94
* lookup whiteout for the new entry.
97
96
static struct dentry *
98
lock_hdir_lkup_wh(struct dentry *dentry, struct dtime *dt,
99
struct dentry *src_dentry, int do_lock_srcdir)
97
lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
98
struct dentry *src_dentry, struct au_wr_dir_args *wr_dir_args)
101
struct dentry *wh_dentry, *parent, *hidden_parent;
100
struct dentry *wh_dentry, *parent, *h_parent;
103
102
aufs_bindex_t bstart, bcpup;
104
103
struct inode *dir, *h_dir;
105
struct lkup_args lkup;
107
LKTRTrace("%.*s, src %p\n", DLNPair(dentry), src_dentry);
109
parent = dget_parent(dentry);
106
LKTRTrace("%.*s, src %p\n", AuDLNPair(dentry), src_dentry);
108
parent = dentry->d_parent; /* dir inode is locked */
109
IMustLock(parent->d_inode);
110
110
bstart = dbstart(dentry);
111
bcpup = err = wr_dir(dentry, 1, src_dentry, -1, do_lock_srcdir);
111
err = au_wr_dir(dentry, src_dentry, wr_dir_args);
113
114
wh_dentry = ERR_PTR(err);
114
115
if (unlikely(err < 0))
117
118
dir = parent->d_inode;
118
hidden_parent = au_h_dptr_i(parent, bcpup);
119
h_dir = hidden_parent->d_inode;
119
h_parent = au_h_dptr_i(parent, bcpup);
120
h_dir = h_parent->d_inode;
120
121
hdir_lock(h_dir, dir, bcpup);
122
dtime_store(dt, parent, hidden_parent);
123
au_dtime_store(dt, parent, bcpup, h_parent);
123
124
wh_dentry = NULL;
124
125
if (/* bcpup != bstart || */ bcpup != dbwh(dentry))
125
126
goto out; /* success */
127
lkup.nfsmnt = au_nfsmnt(parent->d_sb, bcpup);
128
lkup.dlgt = need_dlgt(parent->d_sb);
129
wh_dentry = lkup_wh(hidden_parent, &dentry->d_name, &lkup);
128
ndx.nfsmnt = au_nfsmnt(parent->d_sb, bcpup);
129
ndx.dlgt = au_need_dlgt(parent->d_sb);
132
wh_dentry = lkup_wh(h_parent, &dentry->d_name, &ndx);
130
133
//wh_dentry = ERR_PTR(-1);
131
134
if (IS_ERR(wh_dentry))
132
135
hdir_unlock(h_dir, dir, bcpup);
136
TraceErrPtr(wh_dentry);
138
AuTraceErrPtr(wh_dentry);
137
139
return wh_dentry;
140
142
/* ---------------------------------------------------------------------- */
142
enum {Mknod, Symlink, Creat};
144
enum { Mknod, Symlink, Creat };
143
145
struct simple_arg {
161
163
struct simple_arg *arg)
164
struct dentry *hidden_dentry, *hidden_parent, *wh_dentry, *parent;
165
struct inode *hidden_dir;
166
struct dentry *h_dentry, *h_parent, *wh_dentry, *parent;
169
struct vfsub_args vargs;
170
struct super_block *sb;
171
struct au_wr_dir_args wr_dir_args = {
168
LKTRTrace("type %d, %.*s\n", arg->type, DLNPair(dentry));
178
LKTRTrace("type %d, %.*s\n", arg->type, AuDLNPair(dentry));
171
aufs_read_lock(dentry, AUFS_D_WLOCK);
172
parent = dget_parent(dentry);
181
aufs_read_lock(dentry, AuLock_DW);
182
parent = dentry->d_parent; /* dir inode is locked */
173
183
di_write_lock_parent(parent);
174
184
wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL,
175
/*do_lock_srcdir*/0);
176
186
//wh_dentry = ERR_PTR(-1);
177
187
err = PTR_ERR(wh_dentry);
178
188
if (IS_ERR(wh_dentry))
181
hidden_dentry = au_h_dptr(dentry);
182
hidden_parent = dget_parent(hidden_dentry);
183
hidden_dir = hidden_parent->d_inode;
184
IMustLock(hidden_dir);
185
dlgt = need_dlgt(dir->i_sb);
191
h_dentry = au_h_dptr(dentry);
192
h_parent = h_dentry->d_parent; /* dir inode is locked */
193
h_dir = h_parent->d_inode;
196
dlgt = au_need_dlgt(sb);
187
198
#if 1 // partial testing
188
199
switch (arg->type) {
192
struct nameidata fake_nd;
193
fake_nd = *arg->u.c.nd;
194
fake_nd.dentry = dget(hidden_parent);
195
fake_nd.mnt = sbr_mnt(dentry->d_sb, dbstart(dentry));
197
err = vfsub_create(hidden_dir, hidden_dentry,
198
arg->u.c.mode, &fake_nd, dlgt);
199
path_release(&fake_nd);
202
err = vfsub_create(hidden_dir, hidden_dentry,
203
arg->u.c.mode, NULL, dlgt);
201
AuDebugOn(au_test_nfs(h_dir->i_sb) && !arg->u.c.nd);
202
err = au_h_create(h_dir, h_dentry, arg->u.c.mode, dlgt,
203
arg->u.c.nd, au_nfsmnt(sb, dbstart(dentry)));
206
err = vfsub_symlink(hidden_dir, hidden_dentry,
206
err = vfsub_symlink(h_dir, h_dentry,
207
207
arg->u.s.symname, S_IALLUGO, dlgt);
210
err = vfsub_mknod(hidden_dir, hidden_dentry,
210
err = vfsub_mknod(h_dir, h_dentry,
211
211
arg->u.m.mode, arg->u.m.dev, dlgt);
220
err = epilog(wh_dentry, dentry);
220
err = epilog(dir, wh_dentry, dentry);
224
if (unlikely(err && hidden_dentry->d_inode)) {
224
if (unlikely(err && h_dentry->d_inode)) {
226
rerr = vfsub_unlink(hidden_dir, hidden_dentry, dlgt);
226
vfsub_args_init(&vargs, NULL, dlgt, 0);
227
rerr = vfsub_unlink(h_dir, h_dentry, &vargs);
229
IOErr("%.*s revert failure(%d, %d)\n",
230
DLNPair(dentry), err, rerr);
230
AuIOErr("%.*s revert failure(%d, %d)\n",
231
AuDLNPair(dentry), err, rerr);
233
dtime_revert(&dt, !CPUP_LOCKED_GHDIR);
234
//todo: inotify will be fired to the grand parent dir
235
au_dtime_revert(&dt);
237
hdir_unlock(hidden_dir, dir, dbstart(dentry));
239
hdir_unlock(h_dir, dir, dbstart(dentry));
283
289
struct link_arg {
284
290
aufs_bindex_t bdst, bsrc;
285
291
int issamedir, dlgt;
286
struct dentry *src_parent, *parent, *hidden_dentry;
287
struct inode *hidden_dir, *inode;
292
struct dentry *src_parent, *parent, *h_dentry;
293
struct inode *h_dir, *inode, *dir;
290
296
static int cpup_before_link(struct dentry *src_dentry, struct inode *dir,
291
297
struct link_arg *a)
295
300
struct inode *hi, *hdir = NULL, *src_dir;
301
struct au_cpup_flags cflags;
300
flags = au_flags_cpup(CPUP_DTIME, a->parent);
301
306
src_dir = a->src_parent->d_inode;
302
307
if (!a->issamedir) {
303
308
// todo: dead lock?
304
di_read_lock_parent2(a->src_parent, AUFS_I_RLOCK);
305
// this temporary unlock/lock is safe
306
hdir_unlock(a->hidden_dir, dir, a->bdst);
307
err = test_and_cpup_dirs(src_dentry, a->bdst, a->parent);
309
di_read_lock_parent2(a->src_parent, AuLock_IR);
310
/* this temporary unlock/lock is safe */
311
hdir_unlock(a->h_dir, dir, a->bdst);
312
err = au_test_and_cpup_dirs(src_dentry, a->bdst, a->parent);
310
315
hdir = au_h_iptr_i(src_dir, a->bdst);
311
316
hdir_lock(hdir, src_dir, a->bdst);
312
flags = au_flags_cpup(CPUP_DTIME, a->src_parent);
317
322
hi = au_h_dptr(src_dentry)->d_inode;
319
err = sio_cpup_simple(src_dentry, a->bdst, -1, flags);
323
vfsub_i_lock_nested(hi, AuLsc_I_CHILD);
324
err = au_sio_cpup_simple(src_dentry, a->bdst, -1, &cflags);
324
329
if (!a->issamedir) {
326
331
hdir_unlock(hdir, src_dir, a->bdst);
327
hdir_lock(a->hidden_dir, dir, a->bdst);
328
di_read_unlock(a->src_parent, AUFS_I_RLOCK);
332
hdir_lock(a->h_dir, dir, a->bdst);
333
di_read_unlock(a->src_parent, AuLock_IR);
351
357
if (bstart <= a->bdst)
352
358
h_dst_inode = au_h_iptr_i(inode, a->bdst);
360
if (!h_dst_inode || !h_dst_inode->i_nlink) {
355
361
/* copyup src_dentry as the name of dentry. */
356
363
set_dbstart(src_dentry, a->bdst);
357
set_h_dptr(src_dentry, a->bdst, dget(a->hidden_dentry));
358
hi_lock_child(h_inode);
359
err = sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1,
360
au_flags_cpup(!CPUP_DTIME, a->parent));
364
set_h_dptr(src_dentry, a->bdst, dget(a->h_dentry));
365
vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD);
366
err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1,
369
vfsub_i_unlock(h_inode);
363
370
set_h_dptr(src_dentry, a->bdst, NULL);
364
371
set_dbstart(src_dentry, a->bsrc);
366
373
/* the inode of src_dentry already exists on a.bdst branch */
367
374
h_dentry = d_find_alias(h_dst_inode);
369
err = vfsub_link(h_dentry, a->hidden_dir,
370
a->hidden_dentry, a->dlgt);
376
err = vfsub_link(h_dentry, a->h_dir,
377
a->h_dentry, a->dlgt);
373
IOErr("no dentry found for i%lu on b%d\n",
374
h_dst_inode->i_ino, a->bdst);
380
AuIOErr("no dentry found for i%lu on b%d\n",
381
h_dst_inode->i_ino, a->bdst);
380
append_plink(sb, a->inode, a->hidden_dentry, a->bdst);
387
au_append_plink(sb, a->inode, a->h_dentry, a->bdst);
387
394
struct dentry *dentry)
390
struct dentry *hidden_parent, *wh_dentry, *hidden_src_dentry;
397
struct dentry *h_parent, *wh_dentry, *h_src_dentry;
392
399
struct link_arg a;
393
400
struct super_block *sb;
401
struct vfsub_args vargs;
402
struct au_wr_dir_args wr_dir_args = {
405
//.do_lock_srcdir = 0,
395
409
LKTRTrace("src %.*s, i%lu, dst %.*s\n",
396
DLNPair(src_dentry), dir->i_ino, DLNPair(dentry));
410
AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry));
398
412
IMustLock(src_dentry->d_inode);
413
AuDebugOn(S_ISDIR(src_dentry->d_inode->i_mode));
400
aufs_read_and_write_lock2(dentry, src_dentry, /*isdir*/0);
415
aufs_read_and_write_lock2(dentry, src_dentry, /*flags*/0);
401
418
a.src_parent = dget_parent(src_dentry);
402
a.parent = dget_parent(dentry);
419
a.parent = dentry->d_parent; /* dir inode is locked */
403
420
a.issamedir = (a.src_parent == a.parent);
421
wr_dir_args.do_lock_srcdir = !a.issamedir;
422
wr_dir_args.force_btgt = dbstart(src_dentry);
404
423
di_write_lock_parent(a.parent);
405
wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, !a.issamedir);
424
wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
425
wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &wr_dir_args);
406
426
//wh_dentry = ERR_PTR(-1);
407
427
err = PTR_ERR(wh_dentry);
408
428
if (IS_ERR(wh_dentry))
411
431
a.inode = src_dentry->d_inode;
412
a.hidden_dentry = au_h_dptr(dentry);
413
hidden_parent = dget_parent(a.hidden_dentry);
414
a.hidden_dir = hidden_parent->d_inode;
415
IMustLock(a.hidden_dir);
432
a.h_dentry = au_h_dptr(dentry);
433
h_parent = a.h_dentry->d_parent; /* dir inode is locked */
434
a.h_dir = h_parent->d_inode;
419
a.dlgt = need_dlgt(sb);
438
a.dlgt = au_need_dlgt(sb);
421
440
//todo: minor optimize, their sb may be same while their bindex differs.
422
441
a.bsrc = dbstart(src_dentry);
423
442
a.bdst = dbstart(dentry);
424
hidden_src_dentry = au_h_dptr(src_dentry);
425
if (unlikely(!au_flag_test(sb, AuFlag_PLINK))) {
443
h_src_dentry = au_h_dptr(src_dentry);
444
if (unlikely(!AuFlag(stosi(sb), f_plink))) {
427
446
* copyup src_dentry to the branch we process,
428
447
* and then link(2) to it.
430
449
* since nlink may be one and some applications will not work.
432
451
if (a.bdst < a.bsrc
433
/* && hidden_src_dentry->d_sb != a.hidden_dentry->d_sb */)
452
/* && h_src_dentry->d_sb != a.h_dentry->d_sb */)
434
453
err = cpup_before_link(src_dentry, dir, &a);
436
hidden_src_dentry = au_h_dptr(src_dentry);
437
err = vfsub_link(hidden_src_dentry, a.hidden_dir,
438
a.hidden_dentry, a.dlgt);
455
h_src_dentry = au_h_dptr(src_dentry);
456
err = vfsub_link(h_src_dentry, a.h_dir,
442
461
if (a.bdst < a.bsrc
443
/* && hidden_src_dentry->d_sb != a.hidden_dentry->d_sb */)
462
/* && h_src_dentry->d_sb != a.h_dentry->d_sb */)
444
463
err = cpup_or_link(src_dentry, &a);
446
hidden_src_dentry = au_h_dptr(src_dentry);
447
err = vfsub_link(hidden_src_dentry, a.hidden_dir,
448
a.hidden_dentry, a.dlgt);
465
h_src_dentry = au_h_dptr(src_dentry);
466
err = vfsub_link(h_src_dentry, a.h_dir,
452
471
if (unlikely(err))
455
err = au_unlink_wh_dentry(a.hidden_dir, wh_dentry, dentry,
474
err = au_unlink_wh_dentry(a.h_dir, wh_dentry, dentry,
458
477
if (unlikely(err))
481
#if 0 // cannot support it
482
/* fuse has different memory inode for the same inode number */
483
if (unlikely(au_test_fuse(a.h_dentry->d_sb))) {
486
//d_drop(h_src_dentry);
487
//d_drop(src_dentry);
489
a.inode->i_ctime = dir->i_ctime;
462
493
dir->i_version++;
463
494
if (ibstart(dir) == dbstart(dentry))
464
495
au_cpup_attr_timesizes(dir);
465
if (!d_unhashed(a.hidden_dentry)
466
/* || hidden_old_inode->i_nlink <= nlink */
467
/* || SB_NFS(hidden_src_dentry->d_sb) */) {
496
if (!d_unhashed(a.h_dentry)
497
/* || h_old_inode->i_nlink <= nlink */
498
/* || SB_NFS(h_src_dentry->d_sb) */) {
468
499
dentry->d_inode = igrab(a.inode);
469
500
d_instantiate(dentry, a.inode);
470
501
a.inode->i_nlink++;
473
504
/* nfs case (< 2.6.15) */
477
508
DbgInode(a.inode);
481
512
for (i = ibstart(a.inode); i <= ibend(a.inode); i++) {
513
struct xino_entry xinoe;
483
514
struct inode *hi;
484
515
hi = au_h_iptr_i(a.inode, i);
486
xino_read(sb, i, hi->i_ino, &xino);
487
Dbg("hi%lu, i%lu\n", hi->i_ino, xino.ino);
517
xino_read(sb, i, hi->i_ino, &xinoe);
518
AuDbg("hi%lu, i%lu\n", hi->i_ino, xinoe.ino);
496
if (d_unhashed(a.hidden_dentry)) {
527
if (d_unhashed(a.h_dentry)) {
497
528
/* hardlink on nfs (< 2.6.15) */
498
529
struct dentry *d;
499
const struct qstr *name = &a.hidden_dentry->d_name;
500
AuDebugOn(a.hidden_dentry->d_parent->d_inode != a.hidden_dir);
502
d = lkup_one(name->name, a.hidden_dentry->d_parent, name->len,
503
au_nfsmnt(sb, a.bdst)??, need_dlgt(sb));
530
const struct qstr *name = &a.h_dentry->d_name;
531
AuDebugOn(a.h_dentry->d_parent->d_inode != a.h_dir);
532
/* do not superio. */
533
d = au_lkup_one(name->name, a.h_dentry->d_parent,
534
name->len, au_nfsmnt(sb, a.bdst)??,
504
536
rerr = PTR_ERR(d);
507
dput(a.hidden_dentry);
509
541
AuDebugOn(!d->d_inode);
512
rerr = vfsub_unlink(a.hidden_dir, a.hidden_dentry, a.dlgt);
544
vfsub_args_init(&vargs, NULL, a.dlgt, 0);
545
rerr = vfsub_unlink(a.h_dir, a.h_dentry, &vargs);
517
IOErr("%.*s reverting failed(%d, %d)\n", DLNPair(dentry), err, rerr);
550
AuIOErr("%.*s reverting failed(%d, %d)\n",
551
AuDLNPair(dentry), err, rerr);
521
dtime_revert(&dt, !CPUP_LOCKED_GHDIR);
555
au_dtime_revert(&dt);
523
hdir_unlock(a.hidden_dir, dir, a.bdst);
557
hdir_unlock(a.h_dir, dir, a.bdst);
527
560
if (unlikely(err)) {
531
564
di_write_unlock(a.parent);
533
565
dput(a.src_parent);
534
566
aufs_read_and_write_unlock2(dentry, src_dentry);
539
571
int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
541
573
int err, rerr, diropq, dlgt;
542
struct dentry *hidden_dentry, *hidden_parent, *wh_dentry, *parent,
574
struct dentry *h_dentry, *h_parent, *wh_dentry, *parent,
544
struct inode *hidden_dir, *hidden_inode;
576
struct inode *h_dir, *h_inode;
546
578
aufs_bindex_t bindex;
547
579
struct super_block *sb;
580
struct vfsub_args vargs;
581
struct au_wr_dir_args wr_dir_args = {
549
LKTRTrace("i%lu, %.*s, mode 0%o\n", dir->i_ino, DLNPair(dentry), mode);
588
LKTRTrace("i%lu, %.*s, mode 0%o\n",
589
dir->i_ino, AuDLNPair(dentry), mode);
552
aufs_read_lock(dentry, AUFS_D_WLOCK);
553
parent = dget_parent(dentry);
592
aufs_read_lock(dentry, AuLock_DW);
593
parent = dentry->d_parent; /* dir inode is locked */
554
594
di_write_lock_parent(parent);
555
595
wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL,
556
/*do_lock_srcdir*/0);
557
597
//wh_dentry = ERR_PTR(-1);
558
598
err = PTR_ERR(wh_dentry);
559
599
if (IS_ERR(wh_dentry))
562
602
sb = dentry->d_sb;
563
603
bindex = dbstart(dentry);
564
hidden_dentry = au_h_dptr(dentry);
565
hidden_parent = dget_parent(hidden_dentry);
566
hidden_dir = hidden_parent->d_inode;
567
IMustLock(hidden_dir);
568
dlgt = need_dlgt(sb);
604
h_dentry = au_h_dptr(dentry);
605
h_parent = h_dentry->d_parent; /* dir inode is locked */
606
h_dir = h_parent->d_inode;
608
dlgt = au_need_dlgt(sb);
570
err = vfsub_mkdir(hidden_dir, hidden_dentry, mode, dlgt);
610
err = vfsub_mkdir(h_dir, h_dentry, mode, dlgt);
572
612
if (unlikely(err))
574
hidden_inode = hidden_dentry->d_inode;
614
h_inode = h_dentry->d_inode;
576
616
/* make the dir opaque */
578
if (unlikely(wh_dentry || au_flag_test(sb, AuFlag_ALWAYS_DIROPQ))) {
579
hi_lock_child(hidden_inode);
580
opq_dentry = create_diropq(dentry, bindex, dlgt);
618
if (unlikely(wh_dentry || AuFlag(stosi(sb), f_always_diropq))) {
619
vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD);
620
opq_dentry = create_diropq(dentry, bindex, /*dlgt*/0);
581
621
//opq_dentry = ERR_PTR(-1);
582
i_unlock(hidden_inode);
622
vfsub_i_unlock(h_inode);
583
623
err = PTR_ERR(opq_dentry);
584
624
if (IS_ERR(opq_dentry))
598
638
if (unlikely(diropq)) {
599
639
LKTRLabel(revert opq);
600
hi_lock_child(hidden_inode);
640
vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD);
601
641
rerr = remove_diropq(dentry, bindex, dlgt);
603
i_unlock(hidden_inode);
643
vfsub_i_unlock(h_inode);
605
IOErr("%.*s reverting diropq failed(%d, %d)\n",
606
DLNPair(dentry), err, rerr);
645
AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
646
AuDLNPair(dentry), err, rerr);
612
652
LKTRLabel(revert dir);
613
rerr = vfsub_rmdir(hidden_dir, hidden_dentry, dlgt);
653
vfsub_args_init(&vargs, NULL, dlgt, 0);
654
rerr = vfsub_rmdir(h_dir, h_dentry, &vargs);
616
IOErr("%.*s reverting dir failed(%d, %d)\n",
617
DLNPair(dentry), err, rerr);
657
AuIOErr("%.*s reverting dir failed(%d, %d)\n",
658
AuDLNPair(dentry), err, rerr);
621
dtime_revert(&dt, /*fake flag*/CPUP_LOCKED_GHDIR);
662
au_dtime_revert(&dt);
623
hdir_unlock(hidden_dir, dir, bindex);
664
hdir_unlock(h_dir, dir, bindex);
627
667
if (unlikely(err)) {