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

« back to all changes in this revision

Viewing changes to fs/aufs/i_op_add.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2007-12-15 23:32:51 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071215233251-2vgs2lmg8mai5d9e
Tags: 0+20071211-1ubuntu1
* Merge from debian unstable (LP: #175705), remaining changes:
  - Fix for Ubuntu Kernels (updated)
* patches/01_vserver.dpatch: Removed
* patches/06_ubuntu.dpatch: Added (update of ubuntu patch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: i_op_add.c,v 1.39 2007/06/04 02:17:35 sfjro Exp $ */
 
19
/* $Id: i_op_add.c,v 1.56 2007/12/10 01:19:07 sfjro Exp $ */
20
20
 
21
 
//#include <linux/fs.h>
22
 
//#include <linux/namei.h>
23
21
#include "aufs.h"
24
22
 
25
23
/*
28
26
 * and update version.
29
27
 * if it failed, re-create the removed whiteout.
30
28
 */
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)
32
31
{
33
32
        int err, rerr;
34
33
        aufs_bindex_t bwh;
35
 
        struct inode *inode, *dir;
36
 
        struct dentry *wh, *parent;
37
 
        struct lkup_args lkup;
38
 
 
39
 
        LKTRTrace("wh %p, %.*s\n", wh_dentry, DLNPair(dentry));
40
 
 
41
 
        parent = NULL;
42
 
        lkup.dlgt = need_dlgt(dentry->d_sb);
 
34
        struct inode *inode, *h_dir;
 
35
        struct dentry *wh;
 
36
        struct aufs_ndx ndx;
 
37
 
 
38
        LKTRTrace("wh %p, %.*s\n", wh_dentry, AuDLNPair(dentry));
 
39
 
43
40
        bwh = -1;
44
41
        if (wh_dentry) {
45
 
                parent = dget_parent(wh_dentry);
 
42
                h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
 
43
                IMustLock(h_dir);
46
44
                bwh = dbwh(dentry);
47
 
                err = au_unlink_wh_dentry(parent->d_inode, wh_dentry, dentry,
48
 
                                          lkup.dlgt);
 
45
                err = au_unlink_wh_dentry(h_dir, wh_dentry, dentry, dir,
 
46
                                          /*dlgt*/0);
49
47
                //err = -1;
50
48
                if (unlikely(err))
51
49
                        goto out;
55
53
        //inode = ERR_PTR(-1);
56
54
        if (!IS_ERR(inode)) {
57
55
                d_instantiate(dentry, inode);
58
 
                dput(parent);
59
 
                parent = dget_parent(dentry);
60
 
                dir = parent->d_inode;
 
56
                dir = dentry->d_parent->d_inode; /* dir inode is locked */
 
57
                IMustLock(dir);
61
58
                /* or always cpup dir mtime? */
62
59
                if (ibstart(dir) == dbstart(dentry))
63
60
                        au_cpup_attr_timesizes(dir);
64
61
                dir->i_version++;
65
 
                dput(parent);
66
62
                return 0; /* success */
67
63
        }
68
64
 
71
67
                goto out;
72
68
 
73
69
        /* revert */
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);
 
72
        ndx.nd = NULL;
 
73
        //ndx.br = NULL;
 
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);
78
78
        if (!IS_ERR(wh)) {
79
79
                dput(wh);
80
80
                goto out;
81
81
        }
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);
84
84
        err = -EIO;
85
85
 
86
86
 out:
87
 
        dput(parent);
88
 
        TraceErr(err);
 
87
        AuTraceErr(err);
89
88
        return err;
90
89
}
91
90
 
95
94
 * lookup whiteout for the new entry.
96
95
 */
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)
100
99
{
101
 
        struct dentry *wh_dentry, *parent, *hidden_parent;
 
100
        struct dentry *wh_dentry, *parent, *h_parent;
102
101
        int err;
103
102
        aufs_bindex_t bstart, bcpup;
104
103
        struct inode *dir, *h_dir;
105
 
        struct lkup_args lkup;
106
 
 
107
 
        LKTRTrace("%.*s, src %p\n", DLNPair(dentry), src_dentry);
108
 
 
109
 
        parent = dget_parent(dentry);
 
104
        struct aufs_ndx ndx;
 
105
 
 
106
        LKTRTrace("%.*s, src %p\n", AuDLNPair(dentry), src_dentry);
 
107
 
 
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);
 
112
        bcpup = err;
112
113
        //err = -1;
113
114
        wh_dentry = ERR_PTR(err);
114
115
        if (unlikely(err < 0))
115
116
                goto out;
116
117
 
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);
121
122
        if (dt)
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 */
126
127
 
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);
 
130
        ndx.nd = NULL;
 
131
        //ndx.br = NULL;
 
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);
133
136
 
134
137
 out:
135
 
        dput(parent);
136
 
        TraceErrPtr(wh_dentry);
 
138
        AuTraceErrPtr(wh_dentry);
137
139
        return wh_dentry;
138
140
}
139
141
 
140
142
/* ---------------------------------------------------------------------- */
141
143
 
142
 
enum {Mknod, Symlink, Creat};
 
144
enum { Mknod, Symlink, Creat };
143
145
struct simple_arg {
144
146
        int type;
145
147
        union {
161
163
                      struct simple_arg *arg)
162
164
{
163
165
        int err, dlgt;
164
 
        struct dentry *hidden_dentry, *hidden_parent, *wh_dentry, *parent;
165
 
        struct inode *hidden_dir;
166
 
        struct dtime dt;
 
166
        struct dentry *h_dentry, *h_parent, *wh_dentry, *parent;
 
167
        struct inode *h_dir;
 
168
        struct au_dtime dt;
 
169
        struct vfsub_args vargs;
 
170
        struct super_block *sb;
 
171
        struct au_wr_dir_args wr_dir_args = {
 
172
                .force_btgt     = -1,
 
173
                .add_entry      = 1,
 
174
                .do_lock_srcdir = 0,
 
175
                .isdir          = 0
 
176
        };
167
177
 
168
 
        LKTRTrace("type %d, %.*s\n", arg->type, DLNPair(dentry));
 
178
        LKTRTrace("type %d, %.*s\n", arg->type, AuDLNPair(dentry));
169
179
        IMustLock(dir);
170
180
 
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);
 
185
                                      &wr_dir_args);
176
186
        //wh_dentry = ERR_PTR(-1);
177
187
        err = PTR_ERR(wh_dentry);
178
188
        if (IS_ERR(wh_dentry))
179
189
                goto out;
180
190
 
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;
 
194
        IMustLock(h_dir);
 
195
        sb = dir->i_sb;
 
196
        dlgt = au_need_dlgt(sb);
186
197
 
187
198
#if 1 // partial testing
188
199
        switch (arg->type) {
189
200
        case Creat:
190
 
#if 0
191
 
                if (arg->u.c.nd) {
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));
196
 
                        mntget(fake_nd.mnt);
197
 
                        err = vfsub_create(hidden_dir, hidden_dentry,
198
 
                                           arg->u.c.mode, &fake_nd, dlgt);
199
 
                        path_release(&fake_nd);
200
 
                } else
201
 
#endif
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)));
204
204
                break;
205
205
        case Symlink:
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);
208
208
                break;
209
209
        case Mknod:
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);
212
212
                break;
213
213
        default:
217
217
        err = -1;
218
218
#endif
219
219
        if (!err)
220
 
                err = epilog(wh_dentry, dentry);
 
220
                err = epilog(dir, wh_dentry, dentry);
221
221
        //err = -1;
222
222
 
223
223
        /* revert */
224
 
        if (unlikely(err && hidden_dentry->d_inode)) {
 
224
        if (unlikely(err && h_dentry->d_inode)) {
225
225
                int rerr;
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);
227
228
                //rerr = -1;
228
229
                if (rerr) {
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);
231
232
                        err = -EIO;
232
233
                }
233
 
                dtime_revert(&dt, !CPUP_LOCKED_GHDIR);
 
234
                //todo: inotify will be fired to the grand parent dir
 
235
                au_dtime_revert(&dt);
234
236
                d_drop(dentry);
235
237
        }
236
238
 
237
 
        hdir_unlock(hidden_dir, dir, dbstart(dentry));
238
 
        dput(hidden_parent);
 
239
        hdir_unlock(h_dir, dir, dbstart(dentry));
239
240
        dput(wh_dentry);
240
241
 
241
242
 out:
244
245
                d_drop(dentry);
245
246
        }
246
247
        di_write_unlock(parent);
247
 
        dput(parent);
248
 
        aufs_read_unlock(dentry, AUFS_D_WLOCK);
249
 
        TraceErr(err);
 
248
        aufs_read_unlock(dentry, AuLock_DW);
 
249
        AuTraceErr(err);
250
250
        return err;
251
251
}
252
252
 
254
254
{
255
255
        struct simple_arg arg = {
256
256
                .type = Mknod,
257
 
                .u.m = {.mode = mode, .dev = dev}
 
257
                .u.m = {
 
258
                        .mode   = mode,
 
259
                        .dev    = dev
 
260
                }
258
261
        };
259
262
        return add_simple(dir, dentry, &arg);
260
263
}
273
276
{
274
277
        struct simple_arg arg = {
275
278
                .type = Creat,
276
 
                .u.c = {.mode = mode, .nd = nd}
 
279
                .u.c = {
 
280
                        .mode   = mode,
 
281
                        .nd     = nd
 
282
                }
277
283
        };
278
284
        return add_simple(dir, dentry, &arg);
279
285
}
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;
288
294
};
289
295
 
290
296
static int cpup_before_link(struct dentry *src_dentry, struct inode *dir,
291
297
                            struct link_arg *a)
292
298
{
293
299
        int err;
294
 
        unsigned int flags;
295
300
        struct inode *hi, *hdir = NULL, *src_dir;
 
301
        struct au_cpup_flags cflags;
296
302
 
297
 
        TraceEnter();
 
303
        AuTraceEnter();
298
304
 
299
305
        err = 0;
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);
308
313
                //err = -1;
309
314
                if (!err) {
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);
313
317
                }
314
318
        }
315
319
 
316
320
        if (!err) {
 
321
                cflags.dtime = 1;
317
322
                hi = au_h_dptr(src_dentry)->d_inode;
318
 
                hi_lock_child(hi);
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);
320
325
                //err = -1;
321
 
                i_unlock(hi);
 
326
                vfsub_i_unlock(hi);
322
327
        }
323
328
 
324
329
        if (!a->issamedir) {
325
330
                if (hdir)
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);
329
334
        }
330
335
 
331
 
        TraceErr(err);
 
336
        AuTraceErr(err);
332
337
        return err;
333
338
}
334
339
 
339
344
        struct dentry *h_dentry;
340
345
        aufs_bindex_t bstart;
341
346
        struct super_block *sb;
 
347
        struct au_cpup_flags cflags;
342
348
 
343
 
        TraceEnter();
 
349
        AuTraceEnter();
344
350
 
345
351
        sb = src_dentry->d_sb;
346
352
        inode = src_dentry->d_inode;
351
357
        if (bstart <= a->bdst)
352
358
                h_dst_inode = au_h_iptr_i(inode, a->bdst);
353
359
 
354
 
        if (!h_dst_inode) {
 
360
        if (!h_dst_inode || !h_dst_inode->i_nlink) {
355
361
                /* copyup src_dentry as the name of dentry. */
 
362
                cflags.dtime = 0;
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,
 
367
                                         &cflags);
361
368
                //err = -1;
362
 
                i_unlock(h_inode);
 
369
                vfsub_i_unlock(h_inode);
363
370
                set_h_dptr(src_dentry, a->bdst, NULL);
364
371
                set_dbstart(src_dentry, a->bsrc);
365
372
        } else {
366
373
                /* the inode of src_dentry already exists on a.bdst branch */
367
374
                h_dentry = d_find_alias(h_dst_inode);
368
375
                if (h_dentry) {
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);
371
378
                        dput(h_dentry);
372
379
                } else {
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);
375
382
                        err = -EIO;
376
383
                }
377
384
        }
378
385
 
379
386
        if (!err)
380
 
                append_plink(sb, a->inode, a->hidden_dentry, a->bdst);
 
387
                au_append_plink(sb, a->inode, a->h_dentry, a->bdst);
381
388
 
382
 
        TraceErr(err);
 
389
        AuTraceErr(err);
383
390
        return err;
384
391
}
385
392
 
387
394
              struct dentry *dentry)
388
395
{
389
396
        int err, rerr;
390
 
        struct dentry *hidden_parent, *wh_dentry, *hidden_src_dentry;
391
 
        struct dtime dt;
 
397
        struct dentry *h_parent, *wh_dentry, *h_src_dentry;
 
398
        struct au_dtime dt;
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 = {
 
403
                //.force_btgt   = -1,
 
404
                .add_entry      = 1,
 
405
                //.do_lock_srcdir = 0,
 
406
                .isdir          = 0
 
407
        };
394
408
 
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));
397
411
        IMustLock(dir);
398
412
        IMustLock(src_dentry->d_inode);
 
413
        AuDebugOn(S_ISDIR(src_dentry->d_inode->i_mode));
399
414
 
400
 
        aufs_read_and_write_lock2(dentry, src_dentry, /*isdir*/0);
 
415
        aufs_read_and_write_lock2(dentry, src_dentry, /*flags*/0);
 
416
        sb = dentry->d_sb;
 
417
        a.dir = dir;
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))
409
429
                goto out;
410
430
 
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;
 
435
        IMustLock(a.h_dir);
416
436
 
417
437
        err = 0;
418
 
        sb = dentry->d_sb;
419
 
        a.dlgt = need_dlgt(sb);
 
438
        a.dlgt = au_need_dlgt(sb);
420
439
 
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))) {
426
445
                /*
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.
431
450
                 */
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);
435
454
                if (!err) {
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,
 
457
                                         a.h_dentry, a.dlgt);
439
458
                        //err = -1;
440
459
                }
441
460
        } else {
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);
445
464
                else {
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,
 
467
                                         a.h_dentry, a.dlgt);
449
468
                        //err = -1;
450
469
                }
451
470
        }
452
471
        if (unlikely(err))
453
472
                goto out_unlock;
454
473
        if (wh_dentry) {
455
 
                err = au_unlink_wh_dentry(a.hidden_dir, wh_dentry, dentry,
456
 
                                          a.dlgt);
 
474
                err = au_unlink_wh_dentry(a.h_dir, wh_dentry, dentry,
 
475
                                          dir, /*dlgt*/0);
457
476
                //err = -1;
458
477
                if (unlikely(err))
459
478
                        goto out_revert;
460
479
        }
461
480
 
 
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))) {
 
484
                LKTRLabel(here);
 
485
                d_drop(a.h_dentry);
 
486
                //d_drop(h_src_dentry);
 
487
                //d_drop(src_dentry);
 
488
                a.inode->i_nlink++;
 
489
                a.inode->i_ctime = dir->i_ctime;
 
490
        }
 
491
#endif
 
492
 
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++;
472
503
        } else
473
504
                /* nfs case (< 2.6.15) */
474
505
                d_drop(dentry);
475
 
#if 0
 
506
#if 0 // debug
476
507
        au_debug_on();
477
508
        DbgInode(a.inode);
478
509
        au_debug_off();
479
510
        {
480
511
                aufs_bindex_t i;
481
512
                for (i = ibstart(a.inode); i <= ibend(a.inode); i++) {
482
 
                        struct xino xino;
 
513
                        struct xino_entry xinoe;
483
514
                        struct inode *hi;
484
515
                        hi = au_h_iptr_i(a.inode, i);
485
516
                        if (hi) {
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);
488
519
                        }
489
520
                }
490
521
        }
493
524
 
494
525
 out_revert:
495
526
#if 0 // remove
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);
501
 
                // do not superio.
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)??,
 
535
                                au_need_dlgt(sb));
504
536
                rerr = PTR_ERR(d);
505
537
                if (IS_ERR(d))
506
538
                        goto out_rerr;
507
 
                dput(a.hidden_dentry);
508
 
                a.hidden_dentry = d;
 
539
                dput(a.h_dentry);
 
540
                a.h_dentry = d;
509
541
                AuDebugOn(!d->d_inode);
510
542
        }
511
543
#endif
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);
513
546
        //rerr = -1;
514
547
        if (!rerr)
515
548
                goto out_dt;
516
549
// out_rerr:
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);
518
552
        err = -EIO;
519
553
 out_dt:
520
554
        d_drop(dentry);
521
 
        dtime_revert(&dt, !CPUP_LOCKED_GHDIR);
 
555
        au_dtime_revert(&dt);
522
556
 out_unlock:
523
 
        hdir_unlock(a.hidden_dir, dir, a.bdst);
524
 
        dput(hidden_parent);
 
557
        hdir_unlock(a.h_dir, dir, a.bdst);
525
558
        dput(wh_dentry);
526
559
 out:
527
560
        if (unlikely(err)) {
529
562
                d_drop(dentry);
530
563
        }
531
564
        di_write_unlock(a.parent);
532
 
        dput(a.parent);
533
565
        dput(a.src_parent);
534
566
        aufs_read_and_write_unlock2(dentry, src_dentry);
535
 
        TraceErr(err);
 
567
        AuTraceErr(err);
536
568
        return err;
537
569
}
538
570
 
539
571
int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
540
572
{
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,
543
575
                *opq_dentry;
544
 
        struct inode *hidden_dir, *hidden_inode;
545
 
        struct dtime dt;
 
576
        struct inode *h_dir, *h_inode;
 
577
        struct au_dtime dt;
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 = {
 
582
                .force_btgt     = -1,
 
583
                .add_entry      = 1,
 
584
                .do_lock_srcdir = 0,
 
585
                .isdir          = 1
 
586
        };
548
587
 
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);
550
590
        IMustLock(dir);
551
591
 
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);
 
596
                                      &wr_dir_args);
557
597
        //wh_dentry = ERR_PTR(-1);
558
598
        err = PTR_ERR(wh_dentry);
559
599
        if (IS_ERR(wh_dentry))
561
601
 
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;
 
607
        IMustLock(h_dir);
 
608
        dlgt = au_need_dlgt(sb);
569
609
 
570
 
        err = vfsub_mkdir(hidden_dir, hidden_dentry, mode, dlgt);
 
610
        err = vfsub_mkdir(h_dir, h_dentry, mode, dlgt);
571
611
        //err = -1;
572
612
        if (unlikely(err))
573
613
                goto out_unlock;
574
 
        hidden_inode = hidden_dentry->d_inode;
 
614
        h_inode = h_dentry->d_inode;
575
615
 
576
616
        /* make the dir opaque */
577
617
        diropq = 0;
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))
585
625
                        goto out_dir;
587
627
                diropq = 1;
588
628
        }
589
629
 
590
 
        err = epilog(wh_dentry, dentry);
 
630
        err = epilog(dir, wh_dentry, dentry);
591
631
        //err = -1;
592
632
        if (!err) {
593
633
                dir->i_nlink++;
597
637
        /* revert */
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);
602
642
                //rerr = -1;
603
 
                i_unlock(hidden_inode);
 
643
                vfsub_i_unlock(h_inode);
604
644
                if (rerr) {
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);
607
647
                        err = -EIO;
608
648
                }
609
649
        }
610
650
 
611
651
 out_dir:
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);
614
655
        //rerr = -1;
615
656
        if (rerr) {
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);
618
659
                err = -EIO;
619
660
        }
620
661
        d_drop(dentry);
621
 
        dtime_revert(&dt, /*fake flag*/CPUP_LOCKED_GHDIR);
 
662
        au_dtime_revert(&dt);
622
663
 out_unlock:
623
 
        hdir_unlock(hidden_dir, dir, bindex);
624
 
        dput(hidden_parent);
 
664
        hdir_unlock(h_dir, dir, bindex);
625
665
        dput(wh_dentry);
626
666
 out:
627
667
        if (unlikely(err)) {
629
669
                d_drop(dentry);
630
670
        }
631
671
        di_write_unlock(parent);
632
 
        dput(parent);
633
 
        aufs_read_unlock(dentry, AUFS_D_WLOCK);
634
 
        TraceErr(err);
 
672
        aufs_read_unlock(dentry, AuLock_DW);
 
673
        AuTraceErr(err);
635
674
        return err;
636
675
}