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

« back to all changes in this revision

Viewing changes to fs/aufs25/i_op_ren.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-05-06 18:35:50 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080506183550-0b6c974kkgc46oeh
Tags: 0+20080506-1
* New upstream release, supports Kernel 2.6.25 (Closes: #479717)
* Fix building with older Kernels (Closes: #475042)
* Update the patches 01, 04 and 07 to also patch fs/aufs25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2005-2008 Junjiro Okajima
 
3
 *
 
4
 * This program, aufs is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 */
 
18
 
 
19
/*
 
20
 * inode operation (rename entry)
 
21
 * todo: this is monster
 
22
 *
 
23
 * $Id: i_op_ren.c,v 1.4 2008/05/04 23:51:40 sfjro Exp $
 
24
 */
 
25
 
 
26
#include "aufs.h"
 
27
 
 
28
enum { SRC, DST };
 
29
 
 
30
#define AuRen_ISDIR     1
 
31
#define AuRen_ISSAMEDIR (1 << 1)
 
32
#define AuRen_WHSRC     (1 << 2)
 
33
#define AuRen_WHDST     (1 << 3)
 
34
#define AuRen_DLGT      (1 << 4)
 
35
#define au_ftest_ren(flags, name)       ((flags) & AuRen_##name)
 
36
#define au_fset_ren(flags, name)        { (flags) |= AuRen_##name; }
 
37
#define au_fclr_ren(flags, name)        { (flags) &= ~AuRen_##name; }
 
38
#ifndef CONFIG_AUFS_DLGT
 
39
#undef AuRen_DLGT
 
40
#define AuRen_DLGT      0
 
41
#endif
 
42
 
 
43
struct rename_args {
 
44
        struct dentry *h_dentry[2], *parent[2], *h_parent[2], *h_trap;
 
45
        struct au_nhash whlist;
 
46
        aufs_bindex_t btgt, bstart[2];
 
47
        struct super_block *sb;
 
48
        unsigned int flags;
 
49
        unsigned int mnt_flags;
 
50
};
 
51
 
 
52
static noinline_for_stack int
 
53
do_rename(struct inode *src_dir, struct dentry *src_dentry,
 
54
          struct inode *dir, struct dentry *dentry, struct rename_args *a)
 
55
{
 
56
        int err, need_diropq, bycpup, rerr;
 
57
        struct au_whtmp_rmdir_args *thargs;
 
58
        struct dentry *wh_dentry[2], *h_dst, *h_src;
 
59
        struct inode *h_dir[2];
 
60
        aufs_bindex_t bindex, bend;
 
61
        struct au_hin_ignore ign;
 
62
        struct vfsub_args vargs;
 
63
        struct au_ndx ndx = {
 
64
                .flags  = 0,
 
65
                .nd     = NULL,
 
66
                //.br   = NULL
 
67
        };
 
68
 
 
69
        LKTRTrace("%.*s/%.*s, %.*s/%.*s, "
 
70
                  "hd{%p, %p}, hp{%p, %p}, wh %p, btgt %d, bstart{%d, %d}, "
 
71
                  "flags 0x%x\n",
 
72
                  AuDLNPair(a->parent[SRC]), AuDLNPair(src_dentry),
 
73
                  AuDLNPair(a->parent[DST]), AuDLNPair(dentry),
 
74
                  a->h_dentry[SRC], a->h_dentry[DST],
 
75
                  a->h_parent[SRC], a->h_parent[DST],
 
76
                  &a->whlist, a->btgt,
 
77
                  a->bstart[SRC], a->bstart[DST],
 
78
                  a->flags);
 
79
 
 
80
        h_dir[SRC] = a->h_parent[SRC]->d_inode;
 
81
        h_dir[DST] = a->h_parent[DST]->d_inode;
 
82
 
 
83
        /* prepare workqueue args */
 
84
        h_dst = NULL;
 
85
        thargs = NULL;
 
86
        if (au_ftest_ren(a->flags, ISDIR) && a->h_dentry[DST]->d_inode) {
 
87
                err = -ENOMEM;
 
88
                thargs = kmalloc(sizeof(*thargs), GFP_TEMPORARY);
 
89
                //thargs = NULL;
 
90
                if (unlikely(!thargs))
 
91
                        goto out;
 
92
                h_dst = dget(a->h_dentry[DST]);
 
93
        }
 
94
 
 
95
        wh_dentry[SRC] = NULL;
 
96
        wh_dentry[DST] = NULL;
 
97
        ndx.nfsmnt = au_nfsmnt(a->sb, a->btgt);
 
98
        if (unlikely(au_ftest_ren(a->flags, DLGT)))
 
99
                au_fset_ndx(ndx.flags, DLGT);
 
100
 
 
101
        /* create whiteout for src_dentry */
 
102
        if (au_ftest_ren(a->flags, WHSRC)) {
 
103
                wh_dentry[SRC] = au_wh_create(src_dir, src_dentry, a->btgt,
 
104
                                              a->h_parent[SRC], &ndx);
 
105
                //wh_dentry[SRC] = ERR_PTR(-1);
 
106
                err = PTR_ERR(wh_dentry[SRC]);
 
107
                if (IS_ERR(wh_dentry[SRC]))
 
108
                        goto out_thargs;
 
109
        }
 
110
 
 
111
        /* lookup whiteout for dentry */
 
112
        if (au_ftest_ren(a->flags, WHDST)) {
 
113
                struct dentry *d;
 
114
 
 
115
                d = au_wh_lkup(a->h_parent[DST], &dentry->d_name, &ndx);
 
116
                //d = ERR_PTR(-1);
 
117
                err = PTR_ERR(d);
 
118
                if (IS_ERR(d))
 
119
                        goto out_whsrc;
 
120
                if (!d->d_inode)
 
121
                        dput(d);
 
122
                else
 
123
                        wh_dentry[DST] = d;
 
124
        }
 
125
 
 
126
        /* rename dentry to tmpwh */
 
127
        if (thargs) {
 
128
                err = au_whtmp_ren(dir, dentry, a->btgt, /*noself*/0);
 
129
                //err = -1;
 
130
                if (unlikely(err))
 
131
                        goto out_whdst;
 
132
                au_set_h_dptr(dentry, a->btgt, NULL);
 
133
                err = au_lkup_neg(dentry, a->btgt);
 
134
                //err = -1;
 
135
                if (unlikely(err))
 
136
                        goto out_whtmp;
 
137
                a->h_dentry[DST] = au_h_dptr(dentry, a->btgt);
 
138
        }
 
139
 
 
140
        /* cpup src */
 
141
        if (a->h_dentry[DST]->d_inode && a->bstart[SRC] != a->btgt) {
 
142
                mutex_lock_nested(&a->h_dentry[SRC]->d_inode->i_mutex,
 
143
                                  AuLsc_I_CHILD);
 
144
                err = au_sio_cpup_simple(src_dentry, a->btgt, -1,
 
145
                                         !AuCpup_DTIME);
 
146
                //err = -1; // untested dir
 
147
                mutex_unlock(&a->h_dentry[SRC]->d_inode->i_mutex);
 
148
                if (unlikely(err))
 
149
                        goto out_whtmp;
 
150
        }
 
151
 
 
152
        /* rename by vfs_rename or cpup */
 
153
        need_diropq = au_ftest_ren(a->flags, ISDIR)
 
154
                && (wh_dentry[DST]
 
155
                    || au_dbdiropq(dentry) == a->btgt
 
156
                    /* hide the lower to keep xino */
 
157
                    || a->btgt < au_dbend(dentry)
 
158
                    || au_opt_test(a->mnt_flags, ALWAYS_DIROPQ));
 
159
        bycpup = 0;
 
160
        if (au_dbstart(src_dentry) == a->btgt) {
 
161
                if (need_diropq && au_dbdiropq(src_dentry) == a->btgt)
 
162
                        need_diropq = 0;
 
163
                vfsub_args_init(&vargs, &ign, au_ftest_ren(a->flags, DLGT), 0);
 
164
                if (unlikely(au_opt_test(a->mnt_flags, UDBA_INOTIFY)
 
165
                             && au_ftest_ren(a->flags, ISDIR)))
 
166
                        vfsub_ign_hinode(&vargs, IN_MOVE_SELF,
 
167
                                         au_hi(src_dentry->d_inode, a->btgt));
 
168
                AuDebugOn(au_dbstart(src_dentry) != a->btgt);
 
169
                err = vfsub_rename(h_dir[SRC], au_h_dptr(src_dentry, a->btgt),
 
170
                                   h_dir[DST], a->h_dentry[DST], &vargs);
 
171
                //err = -1;
 
172
        } else {
 
173
                bycpup = 1;
 
174
                mutex_lock_nested(&a->h_dentry[SRC]->d_inode->i_mutex,
 
175
                                  AuLsc_I_CHILD);
 
176
                au_set_dbstart(src_dentry, a->btgt);
 
177
                au_set_h_dptr(src_dentry, a->btgt, dget(a->h_dentry[DST]));
 
178
                err = au_sio_cpup_single(src_dentry, a->btgt, a->bstart[SRC],
 
179
                                         -1, !AuCpup_DTIME);
 
180
                //err = -1; // untested dir
 
181
                if (unlikely(err)) {
 
182
                        au_set_h_dptr(src_dentry, a->btgt, NULL);
 
183
                        au_set_dbstart(src_dentry, a->bstart[SRC]);
 
184
                }
 
185
                mutex_unlock(&a->h_dentry[SRC]->d_inode->i_mutex);
 
186
        }
 
187
        if (unlikely(err))
 
188
                goto out_whtmp;
 
189
 
 
190
        /* make dir opaque */
 
191
        if (need_diropq) {
 
192
                struct dentry *diropq;
 
193
                struct inode *h_inode;
 
194
 
 
195
                h_inode = au_h_dptr(src_dentry, a->btgt)->d_inode;
 
196
                au_hdir_lock(h_inode, src_dentry->d_inode, a->btgt);
 
197
                diropq = au_diropq_create(src_dentry, a->btgt,
 
198
                                          au_ftest_ren(a->flags, DLGT));
 
199
                //diropq = ERR_PTR(-1);
 
200
                au_hdir_unlock(h_inode, src_dentry->d_inode, a->btgt);
 
201
                err = PTR_ERR(diropq);
 
202
                if (IS_ERR(diropq))
 
203
                        goto out_rename;
 
204
                dput(diropq);
 
205
        }
 
206
 
 
207
        /* update target timestamps */
 
208
        AuDebugOn(au_dbstart(src_dentry) != a->btgt);
 
209
        h_src = au_h_dptr(src_dentry, a->btgt);
 
210
        au_update_fuse_h_inode(NULL, h_src); /*ignore*/
 
211
        //fsstack_copy_attr_atime(src_dentry->d_inode, h_src->d_inode);
 
212
        src_dentry->d_inode->i_ctime = h_src->d_inode->i_ctime;
 
213
 
 
214
        /* remove whiteout for dentry */
 
215
        if (wh_dentry[DST]) {
 
216
                err = au_wh_unlink_dentry(h_dir[DST], wh_dentry[DST],
 
217
                                          dentry, dir, /*dlgt*/0);
 
218
                //err = -1;
 
219
                if (unlikely(err))
 
220
                        goto out_diropq;
 
221
        }
 
222
 
 
223
        /* remove whtmp */
 
224
        if (thargs) {
 
225
                if (au_test_nfs(h_dst->d_sb)
 
226
                    || !au_nhash_test_longer_wh(&a->whlist, a->btgt,
 
227
                                                au_sbi(a->sb)->si_dirwh)) {
 
228
                        err = au_whtmp_rmdir(h_dst, &a->whlist, a->btgt, dir,
 
229
                                             dentry->d_inode, /*noself*/0);
 
230
                        if (unlikely(err))
 
231
                                AuWarn("failed removing whtmp dir %.*s (%d), "
 
232
                                       "ignored.\n", AuDLNPair(h_dst), err);
 
233
                } else {
 
234
                        au_whtmp_kick_rmdir(h_dst, &a->whlist, a->btgt, dir,
 
235
                                            dentry->d_inode, /*noself*/0,
 
236
                                            thargs);
 
237
                        dput(h_dst);
 
238
                        thargs = NULL;
 
239
                }
 
240
        }
 
241
        err = 0;
 
242
        goto out_success;
 
243
 
 
244
#define RevertFailure(fmt, args...) do { \
 
245
                AuIOErrWhck("revert failure: " fmt " (%d, %d)\n", \
 
246
                            ##args, err, rerr); \
 
247
                err = -EIO; \
 
248
        } while (0)
 
249
 
 
250
 out_diropq:
 
251
        if (need_diropq) {
 
252
                struct inode *h_inode;
 
253
 
 
254
                h_inode = au_h_dptr(src_dentry, a->btgt)->d_inode;
 
255
                //br_wh_read_lock(au_sbr(a->sb, a->btgt));
 
256
                /* i_lock simply since inotify is not set to h_inode. */
 
257
                mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_PARENT);
 
258
                //au_hdir_lock(h_inode, src_dentry->d_inode, a->btgt);
 
259
                rerr = au_diropq_remove(src_dentry, a->btgt,
 
260
                                        au_ftest_ren(a->flags, DLGT));
 
261
                //rerr = -1;
 
262
                //au_hdir_unlock(h_inode, src_dentry->d_inode, a->btgt);
 
263
                mutex_unlock(&h_inode->i_mutex);
 
264
                //br_wh_read_unlock(au_sbr(a->sb, a->btgt));
 
265
                if (rerr)
 
266
                        RevertFailure("remove diropq %.*s",
 
267
                                      AuDLNPair(src_dentry));
 
268
        }
 
269
 out_rename:
 
270
        if (!bycpup) {
 
271
                struct dentry *d;
 
272
                struct qstr *name = &src_dentry->d_name;
 
273
 
 
274
                d = au_lkup_one(name->name, a->h_parent[SRC], name->len, &ndx);
 
275
                //d = ERR_PTR(-1);
 
276
                rerr = PTR_ERR(d);
 
277
                if (IS_ERR(d)) {
 
278
                        RevertFailure("au_lkup_one %.*s",
 
279
                                      AuDLNPair(src_dentry));
 
280
                        goto out_whtmp;
 
281
                }
 
282
                AuDebugOn(d->d_inode);
 
283
                vfsub_args_init(&vargs, &ign, au_ftest_ren(a->flags, DLGT), 0);
 
284
                if (unlikely(au_opt_test(a->mnt_flags, UDBA_INOTIFY)
 
285
                             && au_ftest_ren(a->flags, ISDIR)))
 
286
                        vfsub_ign_hinode(&vargs, IN_MOVE_SELF,
 
287
                                         au_hi(src_dentry->d_inode, a->btgt));
 
288
                rerr = vfsub_rename(h_dir[DST], au_h_dptr(src_dentry, a->btgt),
 
289
                                    h_dir[SRC], d, &vargs);
 
290
                //rerr = -1;
 
291
                d_drop(d);
 
292
                dput(d);
 
293
                //au_set_h_dptr(src_dentry, a->btgt, NULL);
 
294
                if (rerr)
 
295
                        RevertFailure("rename %.*s", AuDLNPair(src_dentry));
 
296
        } else {
 
297
                vfsub_args_init(&vargs, NULL, au_ftest_ren(a->flags, DLGT), 0);
 
298
                rerr = vfsub_unlink(h_dir[DST], a->h_dentry[DST], &vargs);
 
299
                //rerr = -1;
 
300
                au_set_h_dptr(src_dentry, a->btgt, NULL);
 
301
                au_set_dbstart(src_dentry, a->bstart[SRC]);
 
302
                if (rerr)
 
303
                        RevertFailure("unlink %.*s",
 
304
                                      AuDLNPair(a->h_dentry[DST]));
 
305
        }
 
306
 out_whtmp:
 
307
        if (thargs) {
 
308
                struct dentry *d;
 
309
                struct qstr *name = &dentry->d_name;
 
310
 
 
311
                d = au_lkup_one(name->name, a->h_parent[DST], name->len, &ndx);
 
312
                //d = ERR_PTR(-1);
 
313
                rerr = PTR_ERR(d);
 
314
                if (IS_ERR(d)) {
 
315
                        RevertFailure("lookup %.*s", AuLNPair(name));
 
316
                        goto out_whdst;
 
317
                }
 
318
                if (d->d_inode) {
 
319
                        d_drop(d);
 
320
                        dput(d);
 
321
                        goto out_whdst;
 
322
                }
 
323
                AuDebugOn(d->d_inode);
 
324
                vfsub_args_init(&vargs, &ign, au_ftest_ren(a->flags, DLGT), 0);
 
325
                if (unlikely(0 && au_opt_test(a->mnt_flags, UDBA_INOTIFY)
 
326
                             && au_ftest_ren(a->flags, ISDIR)))
 
327
                        vfsub_ign_hinode(&vargs, IN_MOVE_SELF,
 
328
                                         au_hi(dentry->d_inode, a->btgt));
 
329
                rerr = vfsub_rename(h_dir[DST], h_dst, h_dir[DST], d, &vargs);
 
330
                //rerr = -1;
 
331
                d_drop(d);
 
332
                dput(d);
 
333
                if (rerr) {
 
334
                        RevertFailure("rename %.*s", AuDLNPair(h_dst));
 
335
                        goto out_whdst;
 
336
                }
 
337
                au_set_h_dptr(dentry, a->btgt, NULL);
 
338
                au_set_h_dptr(dentry, a->btgt, dget(h_dst));
 
339
        }
 
340
 out_whdst:
 
341
        dput(wh_dentry[DST]);
 
342
        wh_dentry[DST] = NULL;
 
343
 out_whsrc:
 
344
        if (wh_dentry[SRC]) {
 
345
                rerr = au_wh_unlink_dentry(h_dir[SRC], wh_dentry[SRC],
 
346
                                           src_dentry, src_dir, /*dlgt*/0);
 
347
                //rerr = -1;
 
348
                if (rerr)
 
349
                        RevertFailure("unlink %.*s", AuDLNPair(wh_dentry[SRC]));
 
350
        }
 
351
#undef RevertFailure
 
352
        d_drop(src_dentry);
 
353
        bend = au_dbend(src_dentry);
 
354
        for (bindex = au_dbstart(src_dentry); bindex <= bend; bindex++) {
 
355
                struct dentry *hd;
 
356
 
 
357
                hd = au_h_dptr(src_dentry, bindex);
 
358
                if (hd)
 
359
                        d_drop(hd);
 
360
        }
 
361
        d_drop(dentry);
 
362
        bend = au_dbend(dentry);
 
363
        for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
 
364
                struct dentry *hd;
 
365
 
 
366
                hd = au_h_dptr(dentry, bindex);
 
367
                if (hd)
 
368
                        d_drop(hd);
 
369
        }
 
370
        au_update_dbstart(dentry);
 
371
        if (thargs)
 
372
                d_drop(h_dst);
 
373
 out_success:
 
374
        dput(wh_dentry[SRC]);
 
375
        dput(wh_dentry[DST]);
 
376
 out_thargs:
 
377
        if (thargs) {
 
378
                dput(h_dst);
 
379
                kfree(thargs);
 
380
        }
 
381
 out:
 
382
        AuTraceErr(err);
 
383
        return err;
 
384
}
 
385
 
 
386
/*
 
387
 * test if @dentry dir can be rename destination or not.
 
388
 * success means, it is a logically empty dir.
 
389
 */
 
390
static int may_rename_dstdir(struct dentry *dentry, aufs_bindex_t btgt,
 
391
                             struct au_nhash *whlist)
 
392
{
 
393
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
 
394
 
 
395
        return au_test_empty(dentry, whlist);
 
396
}
 
397
 
 
398
/*
 
399
 * test if @dentry dir can be rename source or not.
 
400
 * if it can, return 0 and @children is filled.
 
401
 * success means,
 
402
 * - or, it is a logically empty dir.
 
403
 * - or, it exists on writable branch and has no children including whiteouts
 
404
 *       on the lower branch.
 
405
 */
 
406
static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
 
407
{
 
408
        int err;
 
409
        aufs_bindex_t bstart;
 
410
 
 
411
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
 
412
 
 
413
        bstart = au_dbstart(dentry);
 
414
        if (bstart != btgt) {
 
415
                struct au_nhash *whlist;
 
416
 
 
417
                whlist = au_nhash_new(GFP_TEMPORARY);
 
418
                err = PTR_ERR(whlist);
 
419
                if (IS_ERR(whlist))
 
420
                        goto out;
 
421
                err = au_test_empty(dentry, whlist);
 
422
                au_nhash_del(whlist);
 
423
                goto out;
 
424
        }
 
425
 
 
426
        if (bstart == au_dbtaildir(dentry))
 
427
                return 0; /* success */
 
428
 
 
429
        err = au_test_empty_lower(dentry);
 
430
 
 
431
 out:
 
432
        if (/* unlikely */(err == -ENOTEMPTY)) {
 
433
                AuWarn1("renaming dir who has child(ren) on multiple branches,"
 
434
                      " is not supported\n");
 
435
                err = -EXDEV;
 
436
        }
 
437
        AuTraceErr(err);
 
438
        return err;
 
439
}
 
440
 
 
441
/* mainly for link(2) and rename(2) */
 
442
int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
 
443
{
 
444
        aufs_bindex_t bdiropq, bwh;
 
445
        struct dentry *parent;
 
446
 
 
447
        LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), btgt);
 
448
        parent = dentry->d_parent;
 
449
        IMustLock(parent->d_inode); /* dir is locked */
 
450
 
 
451
        bdiropq = au_dbdiropq(parent);
 
452
        bwh = au_dbwh(dentry);
 
453
        if (au_br_rdonly(au_sbr(dentry->d_sb, btgt))
 
454
                     || (0 <= bdiropq && bdiropq < btgt)
 
455
                     || (0 <= bwh && bwh < btgt))
 
456
                btgt = -1;
 
457
 
 
458
        LKTRTrace("btgt %d\n", btgt);
 
459
        return btgt;
 
460
}
 
461
 
 
462
//todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled.
 
463
static void au_hgdirs(struct au_hinode **hgdir, struct rename_args *a)
 
464
{
 
465
        struct dentry *gparent[2];
 
466
        struct inode *gdir;
 
467
 
 
468
        if (!au_opt_test(a->mnt_flags, UDBA_INOTIFY))
 
469
                return;
 
470
 
 
471
        gparent[SRC] = NULL;
 
472
        if (!IS_ROOT(a->parent[SRC])) {
 
473
                gparent[SRC] = dget_parent(a->parent[SRC]);
 
474
                gdir = gparent[SRC]->d_inode;
 
475
                if (gparent[SRC] != a->parent[DST]) {
 
476
                        ii_read_lock_parent3(gdir);
 
477
                        hgdir[SRC] = au_hi(gdir, a->btgt);
 
478
                        ii_read_unlock(gdir);
 
479
                } else
 
480
                        hgdir[SRC] = au_hi(gdir, a->btgt);
 
481
                dput(gparent[SRC]);
 
482
        }
 
483
 
 
484
        if (!au_ftest_ren(a->flags, ISSAMEDIR)
 
485
            && !IS_ROOT(a->parent[DST])
 
486
            && a->parent[DST] != gparent[SRC]) {
 
487
                gparent[DST] = dget_parent(a->parent[DST]);
 
488
                gdir = gparent[DST]->d_inode;
 
489
                if (gparent[DST] != a->parent[SRC]) {
 
490
                        ii_read_lock_parent3(gdir);
 
491
                        hgdir[DST] = au_hi(gdir, a->btgt);
 
492
                        ii_read_unlock(gdir);
 
493
                } else
 
494
                        hgdir[DST] = au_hi(gdir, a->btgt);
 
495
                dput(gparent[DST]);
 
496
        }
 
497
}
 
498
 
 
499
/*
 
500
 * simple tests for rename.
 
501
 * following the checks in vfs, plus the parent-child relationship.
 
502
 */
 
503
static int au_may_ren(struct inode *src_dir, struct dentry *src_dentry,
 
504
                      struct inode *dir, struct dentry *dentry,
 
505
                      struct rename_args *a, struct au_ndx *ndx)
 
506
{
 
507
        int err;
 
508
        struct inode *h_inode;
 
509
 
 
510
        AuTraceEnter();
 
511
 
 
512
        if (a->bstart[SRC] == a->btgt) {
 
513
                err = au_may_del(src_dentry, a->btgt, a->h_parent[SRC],
 
514
                                 au_ftest_ren(a->flags, ISDIR), ndx);
 
515
                if (unlikely(err))
 
516
                        goto out;
 
517
                err = -EINVAL;
 
518
                if (unlikely(a->h_dentry[SRC] == a->h_trap))
 
519
                        goto out;
 
520
        }
 
521
 
 
522
        err = 0;
 
523
        if (a->bstart[DST] != a->btgt)
 
524
                goto out;
 
525
 
 
526
        err = -EIO;
 
527
        h_inode = a->h_dentry[DST]->d_inode;
 
528
        if (!dentry->d_inode) {
 
529
                if (unlikely(h_inode))
 
530
                        goto out;
 
531
                err = au_may_add(dentry, a->btgt, a->h_parent[DST],
 
532
                                 au_ftest_ren(a->flags, ISDIR), ndx);
 
533
        } else {
 
534
                if (unlikely(!h_inode || !h_inode->i_nlink))
 
535
                        goto out;
 
536
                err = au_may_del(dentry, a->btgt, a->h_parent[DST],
 
537
                                 au_ftest_ren(a->flags, ISDIR), ndx);
 
538
                if (unlikely(err))
 
539
                        goto out;
 
540
                err = -ENOTEMPTY;
 
541
                if (unlikely(a->h_dentry[DST] == a->h_trap))
 
542
                        goto out;
 
543
                err = 0;
 
544
        }
 
545
 
 
546
 out:
 
547
        if (unlikely(err == -ENOENT || err == -EEXIST))
 
548
                err = -EIO;
 
549
        AuTraceErr(err);
 
550
        return err;
 
551
}
 
552
 
 
553
int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
 
554
                struct inode *dir, struct dentry *dentry)
 
555
{
 
556
        int err, do_dt_dstdir, flags;
 
557
        aufs_bindex_t bend, bindex;
 
558
        struct inode *inode[2], *dirs[2];
 
559
        struct au_hinode *hgdir[2], *hdir;
 
560
        enum { PARENT, CHILD };
 
561
        /* reduce stack space */
 
562
        struct {
 
563
                struct rename_args a;
 
564
                struct au_dtime dt[2][2];
 
565
        } *p;
 
566
        struct au_wr_dir_args wr_dir_args = {
 
567
                //.force_btgt   = -1,
 
568
                .flags          = AuWrDir_ADD_ENTRY
 
569
        };
 
570
 
 
571
        LKTRTrace("i%lu, %.*s, i%lu, %.*s\n",
 
572
                  src_dir->i_ino, AuDLNPair(src_dentry),
 
573
                  dir->i_ino, AuDLNPair(dentry));
 
574
        IMustLock(src_dir);
 
575
        IMustLock(dir);
 
576
        inode[DST] = dentry->d_inode;
 
577
        if (inode[DST]) {
 
578
                IMustLock(inode[DST]);
 
579
                igrab(inode[DST]);
 
580
        }
 
581
 
 
582
        err = -ENOMEM;
 
583
        BUILD_BUG_ON(sizeof(*p) > PAGE_SIZE);
 
584
        p = kmalloc(sizeof(*p), GFP_TEMPORARY);
 
585
        if (unlikely(!p))
 
586
                goto out;
 
587
 
 
588
        err = -ENOTDIR;
 
589
        p->a.sb = src_dentry->d_sb;
 
590
        inode[SRC] = src_dentry->d_inode;
 
591
        flags = 0;
 
592
        p->a.flags = 0;
 
593
        if (S_ISDIR(inode[SRC]->i_mode)) {
 
594
                flags = AuLock_DIR;
 
595
                au_fset_ren(p->a.flags, ISDIR);
 
596
                if (unlikely(inode[DST] && !S_ISDIR(inode[DST]->i_mode)))
 
597
                        goto out_free;
 
598
        }
 
599
 
 
600
        aufs_read_and_write_lock2(dentry, src_dentry, flags);
 
601
        p->a.mnt_flags = au_mntflags(p->a.sb);
 
602
        if (unlikely(au_opt_test_dlgt(p->a.mnt_flags)))
 
603
                au_fset_ren(p->a.flags, DLGT);
 
604
        p->a.parent[SRC] = src_dentry->d_parent; /* dir inode is locked */
 
605
        p->a.parent[DST] = dentry->d_parent; /* dir inode is locked */
 
606
        if (src_dir == dir) {
 
607
                au_fset_ren(p->a.flags, ISSAMEDIR);
 
608
                di_write_lock_parent(p->a.parent[DST]);
 
609
        } else
 
610
                di_write_lock2_parent(p->a.parent[SRC], p->a.parent[DST],
 
611
                                      /*isdir*/1);
 
612
 
 
613
        /* which branch we process */
 
614
        p->a.bstart[SRC] = au_dbstart(src_dentry);
 
615
        p->a.bstart[DST] = au_dbstart(dentry);
 
616
        if (au_ftest_ren(p->a.flags, ISDIR))
 
617
                au_fset_wrdir(wr_dir_args.flags, ISDIR);
 
618
        wr_dir_args.force_btgt = p->a.bstart[SRC];
 
619
        if (dentry->d_inode && p->a.bstart[DST] < p->a.bstart[SRC])
 
620
                wr_dir_args.force_btgt = p->a.bstart[DST];
 
621
        wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
 
622
        err = au_wr_dir(dentry, src_dentry, &wr_dir_args);
 
623
        p->a.btgt = err;
 
624
        if (unlikely(err < 0))
 
625
                goto out_unlock;
 
626
 
 
627
        /* are they available to be renamed */
 
628
        err = 0;
 
629
        au_nhash_init(&p->a.whlist);
 
630
        if (au_ftest_ren(p->a.flags, ISDIR) && inode[DST]) {
 
631
                au_set_dbstart(dentry, p->a.bstart[DST]);
 
632
                err = may_rename_dstdir(dentry, p->a.btgt, &p->a.whlist);
 
633
                au_set_dbstart(dentry, p->a.btgt);
 
634
        }
 
635
        p->a.h_dentry[DST] = au_h_dptr(dentry, au_dbstart(dentry));
 
636
        if (unlikely(err))
 
637
                goto out_unlock;
 
638
        //todo: minor optimize, their sb may be same while their bindex differs.
 
639
        p->a.h_dentry[SRC] = au_h_dptr(src_dentry, au_dbstart(src_dentry));
 
640
        if (au_ftest_ren(p->a.flags, ISDIR)) {
 
641
                err = may_rename_srcdir(src_dentry, p->a.btgt);
 
642
                if (unlikely(err))
 
643
                        goto out_children;
 
644
        }
 
645
 
 
646
        /* prepare the writable parent dir on the same branch */
 
647
        err = au_wr_dir_need_wh(src_dentry, au_ftest_ren(p->a.flags, ISDIR),
 
648
                                &p->a.btgt,
 
649
                                au_ftest_ren(p->a.flags, ISSAMEDIR)
 
650
                                ? NULL : p->a.parent[DST]);
 
651
        if (unlikely(err < 0))
 
652
                goto out_children;
 
653
        if (err)
 
654
                au_fset_ren(p->a.flags, WHSRC);
 
655
        if (p->a.bstart[DST] == p->a.btgt) {
 
656
                au_fset_ren(p->a.flags, WHDST);
 
657
        } else {
 
658
                err = au_cpup_dirs(dentry, p->a.btgt,
 
659
                                   au_ftest_ren(p->a.flags, ISSAMEDIR)
 
660
                                   ? NULL : p->a.parent[SRC]);
 
661
                if (unlikely(err))
 
662
                        goto out_children;
 
663
        }
 
664
 
 
665
        hgdir[SRC] = NULL;
 
666
        hgdir[DST] = NULL;
 
667
        au_hgdirs(hgdir, &p->a);
 
668
        p->a.h_parent[SRC] = au_h_dptr(p->a.parent[SRC], p->a.btgt);
 
669
        p->a.h_parent[DST] = au_h_dptr(p->a.parent[DST], p->a.btgt);
 
670
        dirs[0] = src_dir;
 
671
        dirs[1] = dir;
 
672
 
 
673
        AuDbgSleep_UdbaRace();
 
674
        p->a.h_trap = au_hdir_lock_rename(p->a.h_parent, dirs, p->a.btgt,
 
675
                                          au_ftest_ren(p->a.flags, ISSAMEDIR));
 
676
        //todo: revalidate the lower dentries?
 
677
 
 
678
        if (!au_opt_test(p->a.mnt_flags, UDBA_NONE)) {
 
679
                struct au_ndx ndx = {
 
680
                        .nfsmnt = au_nfsmnt(p->a.sb, p->a.btgt),
 
681
                        .flags  = 0,
 
682
                        .nd     = NULL,
 
683
                        //.br   = NULL
 
684
                };
 
685
                if (unlikely(au_ftest_ren(p->a.flags, DLGT)))
 
686
                        au_fset_ndx(ndx.flags, DLGT);
 
687
                err = au_may_ren(src_dir, src_dentry, dir, dentry, &p->a, &ndx);
 
688
                if (unlikely(err))
 
689
                        goto out_hdir;
 
690
        }
 
691
 
 
692
        /* store timestamps to be revertible */
 
693
        au_dtime_store(p->dt[PARENT] + SRC, p->a.parent[SRC],
 
694
                       p->a.h_parent[SRC], hgdir[SRC]);
 
695
        if (!au_ftest_ren(p->a.flags, ISSAMEDIR))
 
696
                au_dtime_store(p->dt[PARENT] + DST, p->a.parent[DST],
 
697
                               p->a.h_parent[DST], hgdir[DST]);
 
698
        do_dt_dstdir = 0;
 
699
        if (au_ftest_ren(p->a.flags, ISDIR)) {
 
700
                hdir = NULL;
 
701
                if (unlikely(au_opt_test(p->a.mnt_flags, UDBA_INOTIFY)))
 
702
                        hdir = au_hi(p->a.parent[SRC]->d_inode, p->a.btgt);
 
703
                au_dtime_store(p->dt[CHILD] + SRC, src_dentry,
 
704
                               p->a.h_dentry[SRC], hdir);
 
705
                if (p->a.h_dentry[DST]->d_inode) {
 
706
                        do_dt_dstdir = 1;
 
707
                        if (unlikely(au_opt_test(p->a.mnt_flags, UDBA_INOTIFY)))
 
708
                                hdir = au_hi(p->a.parent[DST]->d_inode,
 
709
                                             p->a.btgt);
 
710
                        au_dtime_store(p->dt[CHILD] + DST, dentry,
 
711
                                       p->a.h_dentry[DST], hdir);
 
712
                }
 
713
        }
 
714
 
 
715
        err = do_rename(src_dir, src_dentry, dir, dentry, &p->a);
 
716
        if (unlikely(err))
 
717
                goto out_dt;
 
718
        au_hdir_unlock_rename(p->a.h_parent, dirs, p->a.btgt,
 
719
                              au_ftest_ren(p->a.flags, ISSAMEDIR));
 
720
 
 
721
        /* update dir attributes */
 
722
        dir->i_version++;
 
723
        if (au_ftest_ren(p->a.flags, ISDIR)) {
 
724
                /* is this updating defined in POSIX? */
 
725
                //mutex_lock(&inode[SRC]->i_mutex);
 
726
                au_cpup_attr_timesizes(inode[SRC]);
 
727
                //mutex_unlock(&inode[SRC]->i_mutex);
 
728
 
 
729
                au_cpup_attr_nlink(dir);
 
730
                if (inode[DST]) {
 
731
                        clear_nlink(inode[DST]);
 
732
                        au_cpup_attr_timesizes(inode[DST]);
 
733
                }
 
734
        }
 
735
        if (au_ibstart(dir) == p->a.btgt)
 
736
                au_cpup_attr_timesizes(dir);
 
737
 
 
738
        if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) {
 
739
                src_dir->i_version++;
 
740
                if (au_ftest_ren(p->a.flags, ISDIR))
 
741
                        au_cpup_attr_nlink(src_dir);
 
742
                if (au_ibstart(src_dir) == p->a.btgt)
 
743
                        au_cpup_attr_timesizes(src_dir);
 
744
        }
 
745
 
 
746
#if 0 // todo: test it
 
747
        d_drop(src_dentry);
 
748
#else
 
749
        /* dput/iput all lower dentries */
 
750
        au_set_dbwh(src_dentry, -1);
 
751
        bend = au_dbend(src_dentry);
 
752
        for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) {
 
753
                struct dentry *hd;
 
754
                hd = au_h_dptr(src_dentry, bindex);
 
755
                if (hd)
 
756
                        au_set_h_dptr(src_dentry, bindex, NULL);
 
757
        }
 
758
        au_set_dbend(src_dentry, p->a.btgt);
 
759
 
 
760
        bend = au_ibend(inode[SRC]);
 
761
        for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) {
 
762
                struct inode *hi;
 
763
                hi = au_h_iptr(inode[SRC], bindex);
 
764
                if (hi) {
 
765
                        //AuDbg("hi%lu, i%lu\n", hi->i_ino, 0LU);
 
766
                        au_xino_write0(p->a.sb, bindex, hi->i_ino, 0);
 
767
                        /* ignore this error */
 
768
                        au_set_h_iptr(inode[SRC], bindex, NULL, 0);
 
769
                }
 
770
        }
 
771
        au_set_ibend(inode[SRC], p->a.btgt);
 
772
#endif
 
773
 
 
774
#if 0 // remove this
 
775
        if (inode[DST]) {
 
776
                struct inode *h_i;
 
777
 
 
778
                bend = au_ibend(inode[DST]);
 
779
                for (bindex = au_ibstart(inode[DST]); bindex <= bend;
 
780
                     bindex++) {
 
781
                        h_i = au_h_iptr(inode[DST], bindex);
 
782
                        if (h_i)
 
783
                                au_xino_write0(p->a.sb, bindex, h_i->i_ino, 0);
 
784
                        /* ignore this error */
 
785
                        /* bad action? */
 
786
                }
 
787
        }
 
788
#endif
 
789
 
 
790
        goto out_children; /* success */
 
791
 
 
792
 out_dt:
 
793
        au_dtime_revert(p->dt[PARENT] + SRC);
 
794
        if (!au_ftest_ren(p->a.flags, ISSAMEDIR))
 
795
                au_dtime_revert(p->dt[PARENT] + DST);
 
796
        if (au_ftest_ren(p->a.flags, ISDIR) && err != -EIO) {
 
797
                struct dentry *hd;
 
798
 
 
799
                hd = p->dt[CHILD][SRC].dt_h_dentry;
 
800
                mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD);
 
801
                au_dtime_revert(p->dt[CHILD] + SRC);
 
802
                mutex_unlock(&hd->d_inode->i_mutex);
 
803
                if (do_dt_dstdir) {
 
804
                        hd = p->dt[CHILD][DST].dt_h_dentry;
 
805
                        mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD);
 
806
                        au_dtime_revert(p->dt[CHILD] + DST);
 
807
                        mutex_unlock(&hd->d_inode->i_mutex);
 
808
                }
 
809
        }
 
810
 out_hdir:
 
811
        au_hdir_unlock_rename(p->a.h_parent, dirs, p->a.btgt,
 
812
                              au_ftest_ren(p->a.flags, ISSAMEDIR));
 
813
 out_children:
 
814
        au_nhash_fin(&p->a.whlist);
 
815
 out_unlock:
 
816
        //if (unlikely(err /* && au_ftest_ren(p->a.flags, ISDIR) */)) {
 
817
        if (unlikely(err && au_ftest_ren(p->a.flags, ISDIR))) {
 
818
                au_update_dbstart(dentry);
 
819
                d_drop(dentry);
 
820
        }
 
821
        if (au_ftest_ren(p->a.flags, ISSAMEDIR))
 
822
                di_write_unlock(p->a.parent[DST]);
 
823
        else
 
824
                di_write_unlock2(p->a.parent[SRC], p->a.parent[DST]);
 
825
        aufs_read_and_write_unlock2(dentry, src_dentry);
 
826
 out_free:
 
827
        kfree(p);
 
828
 out:
 
829
        iput(inode[DST]);
 
830
        AuTraceErr(err);
 
831
        return err;
 
832
}