2
* Copyright (C) 2007-2008 Junjiro Okajima
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.
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.
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
20
* policies for selecting one among multiple writable branches
22
* $Id: wbr_policy.c,v 1.3 2008/04/28 03:04:12 sfjro Exp $
25
#include <linux/statfs.h>
28
static int au_cpdown_attr(struct dentry *h_dst, struct dentry *h_src, int dlgt)
32
struct inode *h_idst, *h_isrc;
33
struct vfsub_args vargs;
35
LKTRTrace("%.*s\n", AuDLNPair(h_dst));
36
h_idst = h_dst->d_inode;
38
h_isrc = h_src->d_inode;
41
ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
42
ia.ia_mode = h_isrc->i_mode;
43
ia.ia_uid = h_isrc->i_uid;
44
ia.ia_gid = h_isrc->i_gid;
45
sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
47
vfsub_args_init(&vargs, NULL, dlgt, /*force_unlink*/0);
48
err = vfsub_notify_change(h_dst, &ia, &vargs);
50
/* is this nfs only? */
51
if (!err && sbits && au_test_nfs(h_dst->d_sb)) {
52
ia.ia_valid = ATTR_FORCE | ATTR_MODE;
53
ia.ia_mode = h_isrc->i_mode;
54
err = vfsub_notify_change(h_dst, &ia, &vargs);
58
h_idst->i_flags = h_isrc->i_flags; //??
64
struct au_cpdown_dir_args {
65
struct dentry *parent;
66
unsigned int parent_opq; // bit-flags
69
static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
70
struct dentry *h_parent, void *arg)
72
int err, parent_opq, whed, dlgt, do_opq, made_dir, diropq, rerr;
73
struct au_cpdown_dir_args *args = arg;
74
aufs_bindex_t bend, bopq, bstart;
75
struct dentry *h_dentry, *opq_dentry, *wh_dentry;
76
struct inode *h_dir, *h_inode, *inode;
78
LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst);
79
bstart = au_dbstart(dentry);
80
AuDebugOn(bstart <= bdst
81
&& bdst <= au_dbend(dentry)
82
&& au_h_dptr(dentry, bdst));
84
h_dir = h_parent->d_inode;
88
err = au_lkup_neg(dentry, bdst);
89
if (unlikely(err < 0))
91
h_dentry = au_h_dptr(dentry, bdst);
92
dlgt = !!au_opt_test_dlgt(au_mntflags(dentry->d_sb));
93
err = vfsub_sio_mkdir(h_dir, h_dentry, S_IRWXU | S_IRUGO | S_IXUGO,
99
bend = au_dbend(dentry);
100
bopq = au_dbdiropq(dentry);
101
whed = (au_dbwh(dentry) == bdst);
102
if (!args->parent_opq)
103
args->parent_opq |= (bopq <= bdst);
104
parent_opq = (args->parent_opq && args->parent == dentry);
107
h_inode = h_dentry->d_inode;
108
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
109
if (whed || (parent_opq && do_opq)) {
110
opq_dentry = au_diropq_create(dentry, bdst, dlgt);
111
err = PTR_ERR(opq_dentry);
112
if (IS_ERR(opq_dentry)) {
113
mutex_unlock(&h_inode->i_mutex);
120
err = au_cpdown_attr(h_dentry, au_h_dptr(dentry, bstart), dlgt);
121
mutex_unlock(&h_inode->i_mutex);
127
wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, /*ndx*/NULL);
128
err = PTR_ERR(wh_dentry);
129
if (IS_ERR(wh_dentry))
132
if (wh_dentry->d_inode)
133
err = au_wh_unlink_dentry(h_dir, wh_dentry, dentry,
140
inode = dentry->d_inode;
141
if (au_ibend(inode) < bdst)
142
au_set_ibend(inode, bdst);
143
au_set_h_iptr(inode, bdst, igrab(h_inode), au_hi_flags(inode, 1));
144
goto out; /* success */
149
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
150
rerr = au_diropq_remove(dentry, bdst, dlgt);
151
mutex_unlock(&h_inode->i_mutex);
152
if (unlikely(rerr)) {
153
AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
154
AuDLNPair(dentry), bdst, rerr);
161
rerr = vfsub_sio_rmdir(h_dir, h_dentry, dlgt);
162
if (unlikely(rerr)) {
163
AuIOErr("failed removing %.*s b%d (%d)\n",
164
AuDLNPair(dentry), bdst, rerr);
169
au_set_h_dptr(dentry, bdst, NULL);
170
if (au_dbend(dentry) == bdst)
171
au_update_dbend(dentry);
177
int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst,
178
struct dentry *locked)
181
struct au_cpdown_dir_args args = {
182
.parent = dget_parent(dentry),
186
LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst);
188
err = au_cp_dirs(dentry, bdst, locked, au_cpdown_dir, &args);
195
/* ---------------------------------------------------------------------- */
197
/* policies for create */
199
static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
201
for (; bindex >= 0; bindex--)
202
if (!au_br_rdonly(au_sbr(sb, bindex)))
207
/* top down parent */
208
static int au_wbr_create_tdp(struct dentry *dentry, int isdir)
211
struct super_block *sb;
212
aufs_bindex_t bstart, bindex;
213
struct dentry *parent, *h_parent;
216
LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir);
219
dirperm1 = !!au_opt_test_dirperm1(au_mntflags(sb));
220
bstart = au_dbstart(dentry);
222
if (!au_br_rdonly(au_sbr(sb, bstart)))
226
parent = dget_parent(dentry);
227
for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
228
h_parent = au_h_dptr(parent, bindex);
231
h_dir = h_parent->d_inode;
235
if (!au_br_rdonly(au_sbr(sb, bindex))
237
|| au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC,
246
if (unlikely(err < 0))
247
err = au_wbr_bu(sb, bstart - 1);
250
LKTRTrace("b%d\n", err);
254
/* ---------------------------------------------------------------------- */
256
/* an exception for the policy other than tdp */
257
static int au_wbr_create_exp(struct dentry *dentry)
260
struct dentry *parent;
261
aufs_bindex_t bwh, bdiropq;
263
LKTRTrace("%.*s\n", AuDLNPair(dentry));
266
bwh = au_dbwh(dentry);
267
parent = dget_parent(dentry);
268
bdiropq = au_dbdiropq(parent);
271
err = min(bdiropq, bwh);
274
LKTRTrace("%d\n", err);
275
} else if (bdiropq >= 0) {
277
LKTRTrace("%d\n", err);
281
if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
284
LKTRTrace("%d\n", err);
288
/* ---------------------------------------------------------------------- */
291
static int au_wbr_create_init_rr(struct super_block *sb)
295
err = au_wbr_bu(sb, au_sbend(sb));
296
atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
298
LKTRTrace("b%d\n", err);
302
static int au_wbr_create_rr(struct dentry *dentry, int isdir)
305
struct super_block *sb;
308
aufs_bindex_t bindex, bend;
311
LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir);
315
err = au_wbr_create_exp(dentry);
319
next = &au_sbi(sb)->si_wbr_rr_next;
322
for (bindex = 0; bindex <= bend; bindex++) {
324
err = atomic_dec_return(next) + 1;
325
/* modulo for 0 is meaningless */
327
err = atomic_dec_return(next) + 1;
329
err = atomic_read(next);
330
LKTRTrace("%d\n", err);
333
LKTRTrace("%d\n", err);
334
if (!au_br_rdonly(au_sbr(sb, err)))
340
LKTRTrace("%d\n", err);
345
/* ---------------------------------------------------------------------- */
347
/* most free space */
348
static void *au_wbr_statfs_arg(struct au_branch *br, struct super_block *sb,
349
aufs_bindex_t bindex)
351
struct super_block *h_sb;
353
h_sb = br->br_mnt->mnt_sb;
355
if (!au_test_nfs(h_sb))
358
/* sigh,,, why nfs s_root has wrong inode? */
359
return au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry;
362
static void au_mfs(struct dentry *dentry)
364
struct super_block *sb;
365
aufs_bindex_t bindex, bend;
370
struct au_branch *br;
371
struct au_wbr_mfs *mfs;
373
LKTRTrace("%.*s\n", AuDLNPair(dentry));
377
mfs = &au_sbi(sb)->si_wbr_mfs;
378
mfs->mfs_bindex = -EROFS;
379
mfs->mfsrr_bytes = 0;
380
dlgt = !!au_opt_test_dlgt(au_mntflags(sb));
382
for (bindex = 0; bindex <= bend; bindex++) {
383
br = au_sbr(sb, bindex);
384
if (au_br_rdonly(br))
386
arg = au_wbr_statfs_arg(br, sb, bindex);
390
err = vfsub_statfs(arg, &st, dlgt);
391
LKTRTrace("b%d, %d, %Lu\n",
392
bindex, err, (unsigned long long)st.f_bavail);
394
AuWarn1("failed statfs, b%d, %d\n", bindex, err);
398
/* when the available size is equal, select lower one */
399
b = st.f_bavail * st.f_bsize;
403
mfs->mfs_bindex = bindex;
404
mfs->mfs_jiffy = jiffies;
408
mfs->mfsrr_bytes = bavail;
409
LKTRTrace("b%d\n", mfs->mfs_bindex);
412
static int au_wbr_create_mfs(struct dentry *dentry, int isdir)
415
struct super_block *sb;
416
struct au_wbr_mfs *mfs;
419
LKTRTrace("%.*s\n", AuDLNPair(dentry));
422
err = au_wbr_create_exp(dentry);
426
mfs = &au_sbi(sb)->si_wbr_mfs;
427
mutex_lock(&mfs->mfs_lock);
428
if (unlikely(time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
429
|| mfs->mfs_bindex < 0
430
|| au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))))
432
mutex_unlock(&mfs->mfs_lock);
433
err = mfs->mfs_bindex;
436
LKTRTrace("b%d\n", err);
441
static int au_wbr_create_init_mfs(struct super_block *sb)
443
struct au_wbr_mfs *mfs;
445
mfs = &au_sbi(sb)->si_wbr_mfs;
446
LKTRTrace("expire %lu\n", mfs->mfs_expire);
448
mutex_init(&mfs->mfs_lock);
450
mfs->mfs_bindex = -EROFS;
455
static int au_wbr_create_fin_mfs(struct super_block *sb)
458
mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
462
/* ---------------------------------------------------------------------- */
464
/* most free space and then round robin */
465
static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
468
struct au_wbr_mfs *mfs;
471
LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir);
473
err = au_wbr_create_mfs(dentry, isdir);
475
mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
476
LKTRTrace("%Lu bytes, %Lu wmark\n",
477
mfs->mfsrr_bytes, mfs->mfsrr_watermark);
478
if (unlikely(mfs->mfsrr_bytes < mfs->mfsrr_watermark))
479
err = au_wbr_create_rr(dentry, isdir);
482
LKTRTrace("b%d\n", err);
487
static int au_wbr_create_init_mfsrr(struct super_block *sb)
491
au_wbr_create_init_mfs(sb); /* ignore */
492
err = au_wbr_create_init_rr(sb);
497
/* ---------------------------------------------------------------------- */
499
/* top down parent and most free space */
500
static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
502
int err, e2, dirperm1;
503
struct super_block *sb;
504
struct dentry *parent, *h_parent;
505
aufs_bindex_t bindex, bstart, bend;
506
struct au_branch *br;
511
LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir);
513
err = au_wbr_create_tdp(dentry, isdir);
514
if (unlikely(err < 0))
516
parent = dget_parent(dentry);
517
bstart = au_dbstart(parent);
518
bend = au_dbtaildir(parent);
520
goto out_parent; /* success */
522
e2 = au_wbr_create_mfs(dentry, isdir);
524
goto out_parent; /* success */
526
/* when the available size is equal, select upper one */
528
br = au_sbr(sb, err);
529
dirperm1 = !!au_opt_test_dirperm1(au_mntflags(sb));
531
LKTRTrace("b%d, %Lu\n", err, b);
533
if (unlikely(dirperm1)) {
534
for (bindex = bstart; bindex <= bend; bindex++) {
535
h_parent = au_h_dptr(parent, bindex);
538
h_dir = h_parent->d_inode;
542
br = au_sbr(sb, bindex);
543
if (!au_br_rdonly(br)
544
&& au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC,
546
&& br->br_bytes > b) {
549
LKTRTrace("b%d, %Lu\n", err, b);
555
for (bindex = bstart; bindex <= bend; bindex++) {
556
h_parent = au_h_dptr(parent, bindex);
557
if (!h_parent || !h_parent->d_inode)
560
br = au_sbr(sb, bindex);
561
if (!au_br_rdonly(br) && br->br_bytes > b) {
564
LKTRTrace("b%d, %Lu\n", err, b);
571
LKTRTrace("b%d\n", err);
576
/* ---------------------------------------------------------------------- */
578
/* policies for copyup */
580
/* top down parent */
581
static int au_wbr_copyup_tdp(struct dentry *dentry)
583
return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
586
/* bottom up parent */
587
static int au_wbr_copyup_bup(struct dentry *dentry)
590
struct dentry *parent, *h_parent;
591
aufs_bindex_t bindex, bstart;
592
struct super_block *sb;
595
LKTRTrace("%.*s\n", AuDLNPair(dentry));
599
dirperm1 = !!au_opt_test_dirperm1(au_mntflags(sb));
600
parent = dget_parent(dentry);
601
bstart = au_dbstart(parent);
602
for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
603
h_parent = au_h_dptr(parent, bindex);
606
h_dir = h_parent->d_inode;
610
if (!au_br_rdonly(au_sbr(sb, bindex))
612
|| au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC,
621
if (unlikely(err < 0))
622
err = au_wbr_bu(sb, bstart - 1);
624
LKTRTrace("b%d\n", err);
629
static int au_wbr_copyup_bu(struct dentry *dentry)
633
LKTRTrace("%.*s\n", AuDLNPair(dentry));
635
err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry));
637
LKTRTrace("b%d\n", err);
641
/* ---------------------------------------------------------------------- */
643
struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
644
[AuWbrCopyup_TDP] = {
645
.copyup = au_wbr_copyup_tdp
647
[AuWbrCopyup_BUP] = {
648
.copyup = au_wbr_copyup_bup
651
.copyup = au_wbr_copyup_bu
655
struct au_wbr_create_operations au_wbr_create_ops[] = {
656
[AuWbrCreate_TDP] = {
657
.create = au_wbr_create_tdp
660
.create = au_wbr_create_rr,
661
.init = au_wbr_create_init_rr
663
[AuWbrCreate_MFS] = {
664
.create = au_wbr_create_mfs,
665
.init = au_wbr_create_init_mfs,
666
.fin = au_wbr_create_fin_mfs
668
[AuWbrCreate_MFSV] = {
669
.create = au_wbr_create_mfs,
670
.init = au_wbr_create_init_mfs,
671
.fin = au_wbr_create_fin_mfs
673
[AuWbrCreate_MFSRR] = {
674
.create = au_wbr_create_mfsrr,
675
.init = au_wbr_create_init_mfsrr,
676
.fin = au_wbr_create_fin_mfs
678
[AuWbrCreate_MFSRRV] = {
679
.create = au_wbr_create_mfsrr,
680
.init = au_wbr_create_init_mfsrr,
681
.fin = au_wbr_create_fin_mfs
683
[AuWbrCreate_PMFS] = {
684
.create = au_wbr_create_pmfs,
685
.init = au_wbr_create_init_mfs,
686
.fin = au_wbr_create_fin_mfs
688
[AuWbrCreate_PMFSV] = {
689
.create = au_wbr_create_pmfs,
690
.init = au_wbr_create_init_mfs,
691
.fin = au_wbr_create_fin_mfs