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

« back to all changes in this revision

Viewing changes to fs/aufs25/branch.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
 * branch management
 
21
 *
 
22
 * $Id: branch.c,v 1.4 2008/05/04 23:51:26 sfjro Exp $
 
23
 */
 
24
 
 
25
#include <linux/iso_fs.h>
 
26
#include <linux/loop.h>
 
27
#include <linux/romfs_fs.h>
 
28
#include <linux/smp_lock.h>
 
29
#include "aufs.h"
 
30
 
 
31
static void free_branch(struct au_branch *br)
 
32
{
 
33
        AuTraceEnter();
 
34
 
 
35
        if (br->br_xino)
 
36
                fput(br->br_xino);
 
37
        dput(br->br_wh);
 
38
        dput(br->br_plink);
 
39
        if (!au_test_nfs(br->br_mnt->mnt_sb))
 
40
                mntput(br->br_mnt);
 
41
        else {
 
42
                lockdep_off();
 
43
                mntput(br->br_mnt);
 
44
                lockdep_on();
 
45
        }
 
46
        AuDebugOn(au_br_count(br) || atomic_read(&br->br_wh_running));
 
47
        //AuDbg("free\n");
 
48
        kfree(br);
 
49
}
 
50
 
 
51
/*
 
52
 * frees all branches
 
53
 */
 
54
void au_br_free(struct au_sbinfo *sbinfo)
 
55
{
 
56
        aufs_bindex_t bmax;
 
57
        struct au_branch **br;
 
58
 
 
59
        AuTraceEnter();
 
60
        bmax = sbinfo->si_bend + 1;
 
61
        br = sbinfo->si_branch;
 
62
        while (bmax--)
 
63
                free_branch(*br++);
 
64
}
 
65
 
 
66
/*
 
67
 * find the index of a branch which is specified by @br_id.
 
68
 */
 
69
int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
 
70
{
 
71
        aufs_bindex_t bindex, bend;
 
72
 
 
73
        AuTraceEnter();
 
74
 
 
75
        bend = au_sbend(sb);
 
76
        for (bindex = 0; bindex <= bend; bindex++)
 
77
                if (au_sbr_id(sb, bindex) == br_id)
 
78
                        return bindex;
 
79
        return -1;
 
80
}
 
81
 
 
82
/*
 
83
 * test if the @h_sb is real-readonly.
 
84
 */
 
85
int au_test_def_rr(struct super_block *h_sb)
 
86
{
 
87
        switch (h_sb->s_magic) {
 
88
#ifdef CONFIG_AUFS_RR_SQUASHFS
 
89
        case SQUASHFS_MAGIC_LZMA:
 
90
        case SQUASHFS_MAGIC:
 
91
        case SQUASHFS_MAGIC_LZMA_SWAP:
 
92
        case SQUASHFS_MAGIC_SWAP:
 
93
                return 1; /* real readonly */
 
94
#endif
 
95
 
 
96
#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
 
97
        case ISOFS_SUPER_MAGIC:
 
98
                return 1;
 
99
#endif
 
100
 
 
101
#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
 
102
        case CRAMFS_MAGIC:
 
103
                return 1;
 
104
#endif
 
105
 
 
106
#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
 
107
        case ROMFS_MAGIC:
 
108
                return 1;
 
109
#endif
 
110
 
 
111
        default:
 
112
                return 0;
 
113
        }
 
114
}
 
115
 
 
116
/* ---------------------------------------------------------------------- */
 
117
 
 
118
/*
 
119
 * test if two hidden_dentries have overlapping branches.
 
120
 */
 
121
static int do_test_overlap(struct super_block *sb, struct dentry *h_d1,
 
122
                           struct dentry *h_d2)
 
123
{
 
124
        int err;
 
125
 
 
126
        LKTRTrace("%.*s, %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2));
 
127
 
 
128
        err = au_test_subdir(h_d1, h_d2);
 
129
        AuTraceErr(err);
 
130
        return err;
 
131
}
 
132
 
 
133
static int test_overlap_loopback(struct super_block *sb, struct dentry *h_d1,
 
134
                                 struct dentry *h_d2)
 
135
{
 
136
#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
 
137
        struct inode *h_inode;
 
138
        struct loop_device *l;
 
139
 
 
140
        h_inode = h_d1->d_inode;
 
141
        if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR)
 
142
                return 0;
 
143
 
 
144
        l = h_inode->i_sb->s_bdev->bd_disk->private_data;
 
145
        h_d1 = l->lo_backing_file->f_dentry;
 
146
        if (unlikely(h_d1->d_sb == sb))
 
147
                return 1;
 
148
        return do_test_overlap(sb, h_d1, h_d2);
 
149
#else
 
150
        return 0;
 
151
#endif
 
152
}
 
153
 
 
154
static int test_overlap(struct super_block *sb, struct dentry *h_d1,
 
155
                        struct dentry *h_d2)
 
156
{
 
157
        LKTRTrace("d1 %.*s, d2 %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2));
 
158
 
 
159
        if (unlikely(h_d1 == h_d2))
 
160
                return 1;
 
161
        return do_test_overlap(sb, h_d1, h_d2)
 
162
                || do_test_overlap(sb, h_d2, h_d1)
 
163
                || test_overlap_loopback(sb, h_d1, h_d2)
 
164
                || test_overlap_loopback(sb, h_d2, h_d1);
 
165
}
 
166
 
 
167
/* ---------------------------------------------------------------------- */
 
168
 
 
169
static int init_br_wh(struct super_block *sb, aufs_bindex_t bindex,
 
170
                      struct au_branch *br, int new_perm,
 
171
                      struct dentry *h_root, struct vfsmount *h_mnt)
 
172
{
 
173
        int err, old_perm;
 
174
        struct inode *dir, *h_dir;
 
175
        const int new = (bindex < 0);
 
176
 
 
177
        LKTRTrace("b%d, new_perm %d\n", bindex, new_perm);
 
178
 
 
179
        dir = sb->s_root->d_inode;
 
180
        h_dir = h_root->d_inode;
 
181
        if (new)
 
182
                mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
 
183
        else
 
184
                au_hdir_lock(h_dir, dir, bindex);
 
185
 
 
186
        br_wh_write_lock(br);
 
187
        old_perm = br->br_perm;
 
188
        br->br_perm = new_perm;
 
189
        err = au_wh_init(h_root, br, au_do_nfsmnt(h_mnt), sb);
 
190
        br->br_perm = old_perm;
 
191
        br_wh_write_unlock(br);
 
192
 
 
193
        if (new)
 
194
                mutex_unlock(&h_dir->i_mutex);
 
195
        else
 
196
                au_hdir_unlock(h_dir, dir, bindex);
 
197
 
 
198
        AuTraceErr(err);
 
199
        return err;
 
200
}
 
201
 
 
202
/* ---------------------------------------------------------------------- */
 
203
 
 
204
/*
 
205
 * returns a newly allocated branch. @new_nbranch is a number of branches
 
206
 * after adding a branch.
 
207
 */
 
208
static struct au_branch *alloc_addbr(struct super_block *sb, int new_nbranch)
 
209
{
 
210
        struct au_branch **branchp, *add_branch;
 
211
        int sz;
 
212
        void *p;
 
213
        struct dentry *root;
 
214
        struct inode *inode;
 
215
        struct au_hinode *hinodep;
 
216
        struct au_hdentry *hdentryp;
 
217
 
 
218
        LKTRTrace("new_nbranch %d\n", new_nbranch);
 
219
        SiMustWriteLock(sb);
 
220
        root = sb->s_root;
 
221
        DiMustWriteLock(root);
 
222
        inode = root->d_inode;
 
223
        IiMustWriteLock(inode);
 
224
 
 
225
        add_branch = kmalloc(sizeof(*add_branch), GFP_KERNEL);
 
226
        //if (LktrCond) {kfree(add_branch); add_branch = NULL;}
 
227
        if (unlikely(!add_branch))
 
228
                goto out;
 
229
 
 
230
        sz = sizeof(*branchp) * (new_nbranch - 1);
 
231
        if (unlikely(!sz))
 
232
                sz = sizeof(*branchp);
 
233
        p = au_sbi(sb)->si_branch;
 
234
        branchp = au_kzrealloc(p, sz, sizeof(*branchp) * new_nbranch,
 
235
                               GFP_KERNEL);
 
236
        //if (LktrCond) branchp = NULL;
 
237
        if (unlikely(!branchp))
 
238
                goto out_br;
 
239
        au_sbi(sb)->si_branch = branchp;
 
240
 
 
241
        sz = sizeof(*hdentryp) * (new_nbranch - 1);
 
242
        if (unlikely(!sz))
 
243
                sz = sizeof(*hdentryp);
 
244
        p = au_di(root)->di_hdentry;
 
245
        hdentryp = au_kzrealloc(p, sz, sizeof(*hdentryp) * new_nbranch,
 
246
                                GFP_KERNEL);
 
247
        //if (LktrCond) hdentryp = NULL;
 
248
        if (unlikely(!hdentryp))
 
249
                goto out_br;
 
250
        au_di(root)->di_hdentry = hdentryp;
 
251
 
 
252
        sz = sizeof(*hinodep) * (new_nbranch - 1);
 
253
        if (unlikely(!sz))
 
254
                sz = sizeof(*hinodep);
 
255
        p = au_ii(inode)->ii_hinode;
 
256
        hinodep = au_kzrealloc(p, sz, sizeof(*hinodep) * new_nbranch,
 
257
                               GFP_KERNEL);
 
258
        //if (LktrCond) hinodep = NULL; // unavailable test
 
259
        if (unlikely(!hinodep))
 
260
                goto out_br;
 
261
        au_ii(inode)->ii_hinode = hinodep;
 
262
        return add_branch; /* success */
 
263
 
 
264
 out_br:
 
265
        kfree(add_branch);
 
266
 out:
 
267
        AuTraceErr(-ENOMEM);
 
268
        return ERR_PTR(-ENOMEM);
 
269
}
 
270
 
 
271
/*
 
272
 * test if the branch permission is legal or not.
 
273
 */
 
274
static int test_br(struct super_block *sb, struct inode *inode, int brperm,
 
275
                   char *path)
 
276
{
 
277
        int err;
 
278
 
 
279
        err = 0;
 
280
        if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) {
 
281
                AuErr("write permission for readonly fs or inode, %s\n", path);
 
282
                err = -EINVAL;
 
283
        }
 
284
 
 
285
        AuTraceErr(err);
 
286
        return err;
 
287
}
 
288
 
 
289
/*
 
290
 * returns:
 
291
 * 0: success, the caller will add it
 
292
 * plus: success, it is already unified, the caller should ignore it
 
293
 * minus: error
 
294
 */
 
295
static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
 
296
{
 
297
        int err;
 
298
        struct dentry *root;
 
299
        struct inode *inode, *h_inode;
 
300
        aufs_bindex_t bend, bindex;
 
301
 
 
302
        LKTRTrace("%s, remo%d\n", add->path, remount);
 
303
 
 
304
        root = sb->s_root;
 
305
        bend = au_sbend(sb);
 
306
        if (unlikely(bend >= 0
 
307
                     && au_find_dbindex(root, add->nd.path.dentry) >= 0)) {
 
308
                err = 1;
 
309
                if (!remount) {
 
310
                        err = -EINVAL;
 
311
                        AuErr("%s duplicated\n", add->path);
 
312
                }
 
313
                goto out;
 
314
        }
 
315
 
 
316
        err = -ENOSPC; //-E2BIG;
 
317
        //if (LktrCond) bend = AUFS_BRANCH_MAX;
 
318
        if (unlikely(AUFS_BRANCH_MAX <= add->bindex
 
319
                     || AUFS_BRANCH_MAX - 1 <= bend)) {
 
320
                AuErr("number of branches exceeded %s\n", add->path);
 
321
                goto out;
 
322
        }
 
323
 
 
324
        err = -EDOM;
 
325
        if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
 
326
                AuErr("bad index %d\n", add->bindex);
 
327
                goto out;
 
328
        }
 
329
 
 
330
        inode = add->nd.path.dentry->d_inode;
 
331
        AuDebugOn(!inode || !S_ISDIR(inode->i_mode));
 
332
        err = -ENOENT;
 
333
        if (unlikely(!inode->i_nlink)) {
 
334
                AuErr("no existence %s\n", add->path);
 
335
                goto out;
 
336
        }
 
337
 
 
338
        err = -EINVAL;
 
339
        if (unlikely(inode->i_sb == sb)) {
 
340
                AuErr("%s must be outside\n", add->path);
 
341
                goto out;
 
342
        }
 
343
 
 
344
        if (unlikely(au_test_nested(inode->i_sb))) {
 
345
                AuErr("nested " AUFS_NAME " %s\n", add->path);
 
346
                goto out;
 
347
        }
 
348
 
 
349
        if (unlikely(!strcmp(au_sbtype(inode->i_sb), "unionfs"))) {
 
350
                AuErr("unsupported filesystem, %s\n", add->path);
 
351
                goto out;
 
352
        }
 
353
 
 
354
        if (unlikely(au_test_unsupported_nfs(inode->i_sb))) {
 
355
                AuErr(AuNoNfsBranchMsg " %s\n", add->path);
 
356
                goto out;
 
357
        }
 
358
 
 
359
        err = test_br(sb, add->nd.path.dentry->d_inode, add->perm, add->path);
 
360
        if (unlikely(err))
 
361
                goto out;
 
362
 
 
363
        if (bend < 0)
 
364
                return 0; /* success */
 
365
 
 
366
        h_inode = au_h_dptr(root, 0)->d_inode;
 
367
        if (unlikely(au_opt_test(au_mntflags(sb), WARN_PERM)
 
368
                     && ((h_inode->i_mode & S_IALLUGO)
 
369
                         != (inode->i_mode & S_IALLUGO)
 
370
                         || h_inode->i_uid != inode->i_uid
 
371
                         || h_inode->i_gid != inode->i_gid)))
 
372
                AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
 
373
                       add->path,
 
374
                       inode->i_uid, inode->i_gid, (inode->i_mode & S_IALLUGO),
 
375
                       h_inode->i_uid, h_inode->i_gid,
 
376
                       (h_inode->i_mode & S_IALLUGO));
 
377
 
 
378
        err = -EINVAL;
 
379
        for (bindex = 0; bindex <= bend; bindex++)
 
380
                if (unlikely(test_overlap(sb, add->nd.path.dentry,
 
381
                                          au_h_dptr(root, bindex)))) {
 
382
                        AuErr("%s is overlapped\n", add->path);
 
383
                        goto out;
 
384
                }
 
385
        err = 0;
 
386
 
 
387
 out:
 
388
        AuTraceErr(err);
 
389
        return err;
 
390
}
 
391
 
 
392
static int au_br_init(struct au_branch *br, struct super_block *sb,
 
393
                      struct au_opt_add *add)
 
394
{
 
395
        int err;
 
396
 
 
397
        AuTraceEnter();
 
398
 
 
399
        err = 0;
 
400
        au_rw_init_nolock(&br->br_wh_rwsem);
 
401
        br->br_plink = NULL;
 
402
        br->br_wh = NULL;
 
403
        if (unlikely(au_br_writable(add->perm))) {
 
404
                err = init_br_wh(sb, /*bindex*/-1, br, add->perm,
 
405
                                 add->nd.path.dentry, add->nd.path.mnt);
 
406
                if (unlikely(err))
 
407
                        goto out;
 
408
        }
 
409
 
 
410
        br->br_xino = NULL;
 
411
        br->br_mnt = mntget(add->nd.path.mnt);
 
412
        if (au_opt_test(au_mntflags(sb), XINO)) {
 
413
                err = au_xino_br(sb, br, add->nd.path.dentry->d_inode->i_ino,
 
414
                                 au_sbr(sb, 0)->br_xino, /*do_test*/1);
 
415
                if (unlikely(err)) {
 
416
                        AuDebugOn(br->br_xino);
 
417
                        goto out;
 
418
                }
 
419
        }
 
420
 
 
421
        atomic_set(&br->br_wh_running, 0);
 
422
        br->br_id = au_new_br_id(sb);
 
423
        br->br_perm = add->perm;
 
424
        atomic_set(&br->br_count, 0);
 
425
        br->br_bytes = 0;
 
426
        br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
 
427
        atomic_set(&br->br_xino_running, 0);
 
428
        sysaufs_br_init(br);
 
429
        br->br_generation = au_sigen(sb);
 
430
        //smp_mb(); /* atomic_set */
 
431
 
 
432
 out:
 
433
        AuTraceErr(err);
 
434
        return err;
 
435
}
 
436
 
 
437
int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
 
438
{
 
439
        int err, amount;
 
440
        aufs_bindex_t bend, add_bindex;
 
441
        struct dentry *root, *dentry;
 
442
        struct au_iinfo *iinfo;
 
443
        struct au_sbinfo *sbinfo;
 
444
        struct au_dinfo *dinfo;
 
445
        struct inode *root_inode, *inode;
 
446
        unsigned long long maxb;
 
447
        struct au_branch **branchp, *add_branch;
 
448
        struct au_hdentry *hdentryp;
 
449
        struct au_hinode *hinodep;
 
450
 
 
451
        dentry = add->nd.path.dentry;
 
452
        LKTRTrace("b%d, %s, 0x%x, %.*s\n",
 
453
                  add->bindex, add->path, add->perm, AuDLNPair(dentry));
 
454
        SiMustWriteLock(sb);
 
455
        root = sb->s_root;
 
456
        DiMustWriteLock(root);
 
457
        root_inode = root->d_inode;
 
458
        IMustLock(root_inode);
 
459
        IiMustWriteLock(root_inode);
 
460
 
 
461
        err = test_add(sb, add, remount);
 
462
        if (unlikely(err < 0))
 
463
                goto out;
 
464
        if (err)
 
465
                return 0; /* success */
 
466
 
 
467
        bend = au_sbend(sb);
 
468
        add_branch = alloc_addbr(sb, bend + 2);
 
469
        err = PTR_ERR(add_branch);
 
470
        if (IS_ERR(add_branch))
 
471
                goto out;
 
472
        err = au_br_init(add_branch, sb, add);
 
473
        if (unlikely(err)) {
 
474
                kfree(add_branch);
 
475
                goto out;
 
476
        }
 
477
 
 
478
        add_bindex = add->bindex;
 
479
        if (remount)
 
480
                sysaufs_brs_del(sb, add_bindex);
 
481
 
 
482
        sbinfo = au_sbi(sb);
 
483
        dinfo = au_di(root);
 
484
        iinfo = au_ii(root_inode);
 
485
 
 
486
        amount = bend + 1 - add_bindex;
 
487
        branchp = sbinfo->si_branch + add_bindex;
 
488
        memmove(branchp + 1, branchp, sizeof(*branchp) * amount);
 
489
        *branchp = add_branch;
 
490
        hdentryp = dinfo->di_hdentry + add_bindex;
 
491
        memmove(hdentryp + 1, hdentryp, sizeof(*hdentryp) * amount);
 
492
        au_h_dentry_init(hdentryp);
 
493
        hinodep = iinfo->ii_hinode + add_bindex;
 
494
        memmove(hinodep + 1, hinodep, sizeof(*hinodep) * amount);
 
495
        hinodep->hi_inode = NULL;
 
496
        au_hin_init(hinodep, NULL);
 
497
 
 
498
        sbinfo->si_bend++;
 
499
        dinfo->di_bend++;
 
500
        iinfo->ii_bend++;
 
501
        if (unlikely(bend < 0)) {
 
502
                sbinfo->si_bend = 0;
 
503
                dinfo->di_bstart = 0;
 
504
                iinfo->ii_bstart = 0;
 
505
        }
 
506
        inode = dentry->d_inode;
 
507
        au_set_h_dptr(root, add_bindex, dget(dentry));
 
508
        au_set_h_iptr(root_inode, add_bindex, igrab(inode), 0);
 
509
        if (remount)
 
510
                sysaufs_brs_add(sb, add_bindex);
 
511
 
 
512
        if (!add_bindex)
 
513
                au_cpup_attr_all(root_inode);
 
514
        else
 
515
                au_add_nlink(root_inode, inode);
 
516
        maxb = dentry->d_sb->s_maxbytes;
 
517
        if (sb->s_maxbytes < maxb)
 
518
                sb->s_maxbytes = maxb;
 
519
 
 
520
 out:
 
521
        AuTraceErr(err);
 
522
        return err;
 
523
}
 
524
 
 
525
/* ---------------------------------------------------------------------- */
 
526
 
 
527
#define AuVerbose(do_info, fmt, args...) do { \
 
528
        if (!do_info) \
 
529
                LKTRTrace(fmt, ##args); \
 
530
        else \
 
531
                AuInfo(fmt, ##args); \
 
532
} while (0)
 
533
 
 
534
/*
 
535
 * test if the branch is deletable or not.
 
536
 */
 
537
static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
 
538
                            au_gen_t sigen)
 
539
{
 
540
        int err, i, j, ndentry, verbose;
 
541
        struct au_dcsub_pages dpages;
 
542
        struct au_dpage *dpage;
 
543
        struct dentry *d;
 
544
        aufs_bindex_t bstart, bend;
 
545
        struct inode *inode;
 
546
 
 
547
        LKTRTrace("b%d, gen%d\n", bindex, sigen);
 
548
        SiMustWriteLock(root->d_sb);
 
549
 
 
550
        err = au_dpages_init(&dpages, GFP_TEMPORARY);
 
551
        if (unlikely(err))
 
552
                goto out;
 
553
        err = au_dcsub_pages(&dpages, root, NULL, NULL);
 
554
        if (unlikely(err))
 
555
                goto out_dpages;
 
556
 
 
557
        verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE);
 
558
        for (i = 0; !err && i < dpages.ndpage; i++) {
 
559
                dpage = dpages.dpages + i;
 
560
                ndentry = dpage->ndentry;
 
561
                for (j = 0; !err && j < ndentry; j++) {
 
562
                        d = dpage->dentries[j];
 
563
                        AuDebugOn(!atomic_read(&d->d_count));
 
564
                        inode = d->d_inode;
 
565
                        AuDebugOn(!inode);
 
566
                        if (au_digen(d) == sigen
 
567
                            && au_iigen(inode) == sigen)
 
568
                                di_read_lock_child(d, AuLock_IR);
 
569
                        else {
 
570
                                di_write_lock_child(d);
 
571
                                err = au_reval_dpath(d, sigen);
 
572
                                if (!err)
 
573
                                        di_downgrade_lock(d, AuLock_IR);
 
574
                                else {
 
575
                                        di_write_unlock(d);
 
576
                                        break;
 
577
                                }
 
578
                        }
 
579
 
 
580
                        bstart = au_dbstart(d);
 
581
                        bend = au_dbend(d);
 
582
                        if (bstart <= bindex
 
583
                            && bindex <= bend
 
584
                            && au_h_dptr(d, bindex)
 
585
                            && (!S_ISDIR(d->d_inode->i_mode)
 
586
                                || bstart == bend)) {
 
587
                                err = -EBUSY;
 
588
                                AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
 
589
                        }
 
590
                        di_read_unlock(d, AuLock_IR);
 
591
                }
 
592
        }
 
593
 
 
594
 out_dpages:
 
595
        au_dpages_free(&dpages);
 
596
 out:
 
597
        AuTraceErr(err);
 
598
        return err;
 
599
}
 
600
 
 
601
static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
 
602
                           au_gen_t sigen)
 
603
{
 
604
        int err, verbose;
 
605
        struct inode *i;
 
606
        aufs_bindex_t bstart, bend;
 
607
 
 
608
        LKTRTrace("b%d, gen%d\n", bindex, sigen);
 
609
        SiMustWriteLock(sb);
 
610
 
 
611
        err = 0;
 
612
        verbose = !!au_opt_test(au_mntflags(sb), VERBOSE);
 
613
        list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
 
614
                AuDebugOn(!atomic_read(&i->i_count));
 
615
                if (!list_empty(&i->i_dentry))
 
616
                        continue;
 
617
 
 
618
                if (au_iigen(i) == sigen)
 
619
                        ii_read_lock_child(i);
 
620
                else {
 
621
                        ii_write_lock_child(i);
 
622
                        err = au_refresh_hinode_self(i);
 
623
                        if (!err)
 
624
                                ii_downgrade_lock(i);
 
625
                        else {
 
626
                                ii_write_unlock(i);
 
627
                                break;
 
628
                        }
 
629
                }
 
630
 
 
631
                bstart = au_ibstart(i);
 
632
                bend = au_ibend(i);
 
633
                if (bstart <= bindex
 
634
                    && bindex <= bend
 
635
                    && au_h_iptr(i, bindex)
 
636
                    && (!S_ISDIR(i->i_mode) || bstart == bend)) {
 
637
                        err = -EBUSY;
 
638
                        AuVerbose(verbose, "busy i%lu\n", i->i_ino);
 
639
                        //au_debug_on();
 
640
                        //DbgInode(i);
 
641
                        //au_debug_off();
 
642
                        ii_read_unlock(i);
 
643
                        break;
 
644
                }
 
645
                ii_read_unlock(i);
 
646
        }
 
647
 
 
648
        AuTraceErr(err);
 
649
        return err;
 
650
}
 
651
 
 
652
static int test_children_busy(struct dentry *root, aufs_bindex_t bindex)
 
653
{
 
654
        int err;
 
655
        au_gen_t sigen;
 
656
 
 
657
        LKTRTrace("b%d\n", bindex);
 
658
        SiMustWriteLock(root->d_sb);
 
659
        DiMustWriteLock(root);
 
660
        AuDebugOn(!kernel_locked());
 
661
 
 
662
        sigen = au_sigen(root->d_sb);
 
663
        DiMustNoWaiters(root);
 
664
        IiMustNoWaiters(root->d_inode);
 
665
        di_write_unlock(root);
 
666
        err = test_dentry_busy(root, bindex, sigen);
 
667
        if (!err)
 
668
                err = test_inode_busy(root->d_sb, bindex, sigen);
 
669
        di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
 
670
 
 
671
        AuTraceErr(err);
 
672
        return err;
 
673
}
 
674
 
 
675
int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
 
676
{
 
677
        int err, do_wh, rerr, verbose;
 
678
        struct dentry *root;
 
679
        struct inode *inode, *hidden_dir;
 
680
        aufs_bindex_t bindex, bend, br_id;
 
681
        struct au_sbinfo *sbinfo;
 
682
        struct au_dinfo *dinfo;
 
683
        struct au_iinfo *iinfo;
 
684
        struct au_branch *br;
 
685
        unsigned int mnt_flags;
 
686
 
 
687
        //au_debug_on();
 
688
        LKTRTrace("%s, %.*s\n", del->path, AuDLNPair(del->h_root));
 
689
        SiMustWriteLock(sb);
 
690
        root = sb->s_root;
 
691
        DiMustWriteLock(root);
 
692
        inode = root->d_inode;
 
693
        IiMustWriteLock(inode);
 
694
 
 
695
        err = 0;
 
696
        bindex = au_find_dbindex(root, del->h_root);
 
697
        if (bindex < 0) {
 
698
                if (remount)
 
699
                        goto out; /* success */
 
700
                err = -ENOENT;
 
701
                AuErr("%s no such branch\n", del->path);
 
702
                goto out;
 
703
        }
 
704
        LKTRTrace("bindex b%d\n", bindex);
 
705
 
 
706
        err = -EBUSY;
 
707
        mnt_flags = au_mntflags(sb);
 
708
        verbose = au_opt_test(mnt_flags, VERBOSE);
 
709
        bend = au_sbend(sb);
 
710
        if (unlikely(!bend)) {
 
711
                AuVerbose(verbose, "no more branches left\n");
 
712
                goto out;
 
713
        }
 
714
        br = au_sbr(sb, bindex);
 
715
        if (unlikely(au_br_count(br))) {
 
716
                AuVerbose(verbose, "%d file(s) opened\n", au_br_count(br));
 
717
                goto out;
 
718
        }
 
719
 
 
720
        do_wh = 0;
 
721
        hidden_dir = del->h_root->d_inode;
 
722
        if (br->br_wh || br->br_plink) {
 
723
#if 0 // rfu
 
724
                /* remove whiteout base */
 
725
                err = init_br_wh(sb, bindex, br, AuBr_RO, del->h_root,
 
726
                                 br->br_mnt);
 
727
                if (unlikely(err))
 
728
                        goto out;
 
729
#else
 
730
                dput(br->br_wh);
 
731
                dput(br->br_plink);
 
732
                br->br_plink = NULL;
 
733
                br->br_wh = NULL;
 
734
#endif
 
735
                do_wh = 1;
 
736
        }
 
737
 
 
738
        err = test_children_busy(root, bindex);
 
739
        if (unlikely(err)) {
 
740
                if (unlikely(do_wh))
 
741
                        goto out_wh;
 
742
                goto out;
 
743
        }
 
744
 
 
745
        err = 0;
 
746
        if (remount)
 
747
                sysaufs_brs_del(sb, bindex);
 
748
        sbinfo = au_sbi(sb);
 
749
        dinfo = au_di(root);
 
750
        iinfo = au_ii(inode);
 
751
 
 
752
        dput(au_h_dptr(root, bindex));
 
753
        au_hiput(iinfo->ii_hinode + bindex);
 
754
        br_id = br->br_id;
 
755
        free_branch(br);
 
756
 
 
757
        //todo: realloc and shrink memory
 
758
        if (bindex < bend) {
 
759
                const aufs_bindex_t n = bend - bindex;
 
760
                struct au_branch **brp;
 
761
                struct au_hdentry *hdp;
 
762
                struct au_hinode *hip;
 
763
 
 
764
                brp = sbinfo->si_branch + bindex;
 
765
                memmove(brp, brp + 1, sizeof(*brp) * n);
 
766
                hdp = dinfo->di_hdentry + bindex;
 
767
                memmove(hdp, hdp + 1, sizeof(*hdp) * n);
 
768
                hip = iinfo->ii_hinode + bindex;
 
769
                memmove(hip, hip + 1, sizeof(*hip) * n);
 
770
        }
 
771
        sbinfo->si_branch[0 + bend] = NULL;
 
772
        dinfo->di_hdentry[0 + bend].hd_dentry = NULL;
 
773
        iinfo->ii_hinode[0 + bend].hi_inode = NULL;
 
774
        au_hin_init(iinfo->ii_hinode + bend, NULL);
 
775
 
 
776
        sbinfo->si_bend--;
 
777
        dinfo->di_bend--;
 
778
        iinfo->ii_bend--;
 
779
        if (remount)
 
780
                sysaufs_brs_add(sb, bindex);
 
781
 
 
782
        if (!bindex)
 
783
                au_cpup_attr_all(inode);
 
784
        else
 
785
                au_sub_nlink(inode, del->h_root->d_inode);
 
786
        if (au_opt_test(mnt_flags, PLINK))
 
787
                au_plink_half_refresh(sb, br_id);
 
788
 
 
789
        if (sb->s_maxbytes == del->h_root->d_sb->s_maxbytes) {
 
790
                bend--;
 
791
                sb->s_maxbytes = 0;
 
792
                for (bindex = 0; bindex <= bend; bindex++) {
 
793
                        unsigned long long maxb;
 
794
                        maxb = au_sbr_sb(sb, bindex)->s_maxbytes;
 
795
                        if (sb->s_maxbytes < maxb)
 
796
                                sb->s_maxbytes = maxb;
 
797
                }
 
798
        }
 
799
        goto out; /* success */
 
800
 
 
801
 out_wh:
 
802
        /* revert */
 
803
        rerr = init_br_wh(sb, bindex, br, br->br_perm, del->h_root, br->br_mnt);
 
804
        if (rerr)
 
805
                AuWarn("failed re-creating base whiteout, %s. (%d)\n",
 
806
                       del->path, rerr);
 
807
 out:
 
808
        AuTraceErr(err);
 
809
        //au_debug_off();
 
810
        return err;
 
811
}
 
812
 
 
813
static int do_need_sigen_inc(int a, int b)
 
814
{
 
815
        return (au_br_whable(a) && !au_br_whable(b));
 
816
}
 
817
 
 
818
static int need_sigen_inc(int old, int new)
 
819
{
 
820
        return (do_need_sigen_inc(old, new)
 
821
                || do_need_sigen_inc(new, old));
 
822
}
 
823
 
 
824
int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
 
825
              int *do_update)
 
826
{
 
827
        int err;
 
828
        struct dentry *root;
 
829
        aufs_bindex_t bindex;
 
830
        struct au_branch *br;
 
831
        struct inode *hidden_dir;
 
832
 
 
833
        LKTRTrace("%s, %.*s, 0x%x\n",
 
834
                  mod->path, AuDLNPair(mod->h_root), mod->perm);
 
835
        SiMustWriteLock(sb);
 
836
        root = sb->s_root;
 
837
        DiMustWriteLock(root);
 
838
        IiMustWriteLock(root->d_inode);
 
839
 
 
840
        bindex = au_find_dbindex(root, mod->h_root);
 
841
        if (bindex < 0) {
 
842
                if (remount)
 
843
                        return 0; /* success */
 
844
                err = -ENOENT;
 
845
                AuErr("%s no such branch\n", mod->path);
 
846
                goto out;
 
847
        }
 
848
        LKTRTrace("bindex b%d\n", bindex);
 
849
 
 
850
        hidden_dir = mod->h_root->d_inode;
 
851
        err = test_br(sb, hidden_dir, mod->perm, mod->path);
 
852
        if (unlikely(err))
 
853
                goto out;
 
854
 
 
855
        br = au_sbr(sb, bindex);
 
856
        if (br->br_perm == mod->perm)
 
857
                return 0; /* success */
 
858
 
 
859
        if (au_br_writable(br->br_perm)) {
 
860
#if 1
 
861
                /* remove whiteout base */
 
862
                //todo: mod->perm?
 
863
                err = init_br_wh(sb, bindex, br, AuBr_RO, mod->h_root,
 
864
                                 br->br_mnt);
 
865
                if (unlikely(err))
 
866
                        goto out;
 
867
#else
 
868
                dput(br->br_wh);
 
869
                dput(br->br_plink);
 
870
                br->br_plink = NULL;
 
871
                br->br_wh = NULL;
 
872
#endif
 
873
 
 
874
                if (!au_br_writable(mod->perm)) {
 
875
                        /* rw --> ro, file might be mmapped */
 
876
                        struct file *file, *hf;
 
877
 
 
878
#if 1 // test here
 
879
                        DiMustNoWaiters(root);
 
880
                        IiMustNoWaiters(root->d_inode);
 
881
                        di_write_unlock(root);
 
882
 
 
883
                        /*
 
884
                         * no need file_list_lock()
 
885
                         * since BKL (and sbinfo) is locked
 
886
                         */
 
887
                        AuDebugOn(!kernel_locked());
 
888
                        list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
 
889
                                LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry));
 
890
                                if (!au_test_aufs_file(file))
 
891
                                        continue;
 
892
 
 
893
                                fi_read_lock(file);
 
894
                                if (!S_ISREG(file->f_dentry->d_inode->i_mode)
 
895
                                    || !(file->f_mode & FMODE_WRITE)
 
896
                                    || au_fbstart(file) != bindex) {
 
897
                                        FiMustNoWaiters(file);
 
898
                                        fi_read_unlock(file);
 
899
                                        continue;
 
900
                                }
 
901
 
 
902
                                if (unlikely(au_test_mmapped(file))) {
 
903
                                        err = -EBUSY;
 
904
                                        FiMustNoWaiters(file);
 
905
                                        fi_read_unlock(file);
 
906
                                        break;
 
907
                                }
 
908
 
 
909
                                // todo: already flushed?
 
910
                                hf = au_h_fptr(file, au_fbstart(file));
 
911
                                hf->f_flags = au_file_roflags(hf->f_flags);
 
912
                                hf->f_mode &= ~FMODE_WRITE;
 
913
                                put_write_access(hf->f_dentry->d_inode);
 
914
                                FiMustNoWaiters(file);
 
915
                                fi_read_unlock(file);
 
916
                        }
 
917
 
 
918
                        /* aufs_write_lock() calls ..._child() */
 
919
                        di_write_lock_child(root);
 
920
#endif
 
921
                }
 
922
        }
 
923
 
 
924
        if (!err) {
 
925
                *do_update |= need_sigen_inc(br->br_perm, mod->perm);
 
926
                br->br_perm = mod->perm;
 
927
        }
 
928
 
 
929
 out:
 
930
        AuTraceErr(err);
 
931
        return err;
 
932
}