Commit fb70a624 authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: remount 4/5, refresh the internal branch array



Maintain the internal array including corresponding XINO file and sysfs
entries.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 97be350d
......@@ -181,7 +181,7 @@ out:
* plus: success, it is already unified, the caller should ignore it
* minus: error
*/
static int test_add(struct super_block *sb, struct au_opt_add *add)
static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
{
int err;
aufs_bindex_t bbot, bindex;
......@@ -192,8 +192,11 @@ static int test_add(struct super_block *sb, struct au_opt_add *add)
bbot = au_sbbot(sb);
if (unlikely(bbot >= 0
&& au_find_dbindex(root, add->path.dentry) >= 0)) {
err = -EINVAL;
pr_err("%s duplicated\n", add->pathname);
err = 1;
if (!remount) {
err = -EINVAL;
pr_err("%s duplicated\n", add->pathname);
}
goto out;
}
......@@ -452,7 +455,7 @@ static void au_br_do_add(struct super_block *sb, struct au_branch *br,
au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
}
int au_br_add(struct super_block *sb, struct au_opt_add *add)
int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
{
int err;
aufs_bindex_t bbot, add_bindex;
......@@ -464,7 +467,7 @@ int au_br_add(struct super_block *sb, struct au_opt_add *add)
root_inode = d_inode(root);
IMustLock(root_inode);
IiMustWriteLock(root_inode);
err = test_add(sb, add);
err = test_add(sb, add, remount);
if (unlikely(err < 0))
goto out;
if (err) {
......@@ -485,7 +488,9 @@ int au_br_add(struct super_block *sb, struct au_opt_add *add)
}
add_bindex = add->bindex;
sysaufs_brs_del(sb, add_bindex); /* remove successors */
au_br_do_add(sb, add_branch, add_bindex);
sysaufs_brs_add(sb, add_bindex); /* append successors */
h_dentry = add->path.dentry;
if (!add_bindex) {
......
......@@ -177,7 +177,7 @@ struct au_sbinfo;
void au_br_free(struct au_sbinfo *sinfo);
int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
struct au_opt_add;
int au_br_add(struct super_block *sb, struct au_opt_add *add);
int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
/* xino.c */
static const loff_t au_loff_max = LLONG_MAX;
......@@ -212,7 +212,7 @@ struct file *au_xino_file1(struct au_xino *xi);
struct au_opt_xino;
void au_xino_clr(struct super_block *sb);
int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt);
int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount);
struct file *au_xino_def(struct super_block *sb);
int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino,
struct path *base);
......
......@@ -40,6 +40,12 @@ int au_test_subdir(struct dentry *d1, struct dentry *d2);
/* ---------------------------------------------------------------------- */
static inline int au_qstreq(struct qstr *a, struct qstr *b)
{
return a->len == b->len
&& !memcmp(a->name, b->name, a->len);
}
/*
* by the commit
* 360f547 2015-01-25 dcache: let the dentry count go down to zero without
......
......@@ -1020,10 +1020,11 @@ static int au_opt_br(struct super_block *sb, struct au_opt *opt,
err = 0;
switch (opt->type) {
case Opt_add:
err = au_br_add(sb, &opt->add);
err = au_br_add(sb, &opt->add,
au_ftest_opts(opts->flags, REMOUNT));
if (!err) {
err = 1;
/* au_fset_opts(opts->flags, REFRESH); re-commit later */
au_fset_opts(opts->flags, REFRESH);
}
break;
}
......@@ -1039,7 +1040,8 @@ static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
err = 0;
switch (opt->type) {
case Opt_xino:
err = au_xino_set(sb, &opt->xino);
err = au_xino_set(sb, &opt->xino,
!!au_ftest_opts(opts->flags, REMOUNT));
if (unlikely(err))
break;
......@@ -1205,7 +1207,7 @@ int au_opts_mount(struct super_block *sb, struct au_opts *opts)
if (IS_ERR(xino.file))
goto out;
err = au_xino_set(sb, &xino);
err = au_xino_set(sb, &xino, /*remount*/0);
fput(xino.file);
if (unlikely(err))
goto out;
......@@ -1233,6 +1235,54 @@ out:
return err;
}
int au_opts_remount(struct super_block *sb, struct au_opts *opts)
{
int err, rerr;
struct inode *dir;
struct au_opt_xino *opt_xino;
struct au_opt *opt;
struct au_sbinfo *sbinfo;
SiMustWriteLock(sb);
err = 0;
dir = d_inode(sb->s_root);
sbinfo = au_sbi(sb);
opt_xino = NULL;
opt = opts->opt;
while (err >= 0 && opt->type != Opt_tail) {
err = au_opt_simple(sb, opt, opts);
if (!err)
err = au_opt_br(sb, opt, opts);
if (!err)
err = au_opt_xino(sb, opt, &opt_xino, opts);
opt++;
}
if (err > 0)
err = 0;
AuTraceErr(err);
/* go on even err */
rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
if (unlikely(rerr && !err))
err = rerr;
if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
rerr = au_xib_trunc(sb);
if (unlikely(rerr && !err))
err = rerr;
}
/* will be handled by the caller */
if (!au_ftest_opts(opts->flags, REFRESH)
&& (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
au_fset_opts(opts->flags, REFRESH);
AuDbg("status 0x%x\n", opts->flags);
return err;
}
/* ---------------------------------------------------------------------- */
unsigned int au_opt_udba(struct super_block *sb)
......
......@@ -131,6 +131,8 @@ struct au_opt {
};
/* opts flags */
#define AuOpts_REMOUNT 1
#define AuOpts_REFRESH (1 << 1)
#define AuOpts_TRUNC_XIB (1 << 2)
#define AuOpts_REFRESH_DYAOP (1 << 3)
#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
......@@ -162,6 +164,7 @@ int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
unsigned int pending);
int au_opts_mount(struct super_block *sb, struct au_opts *opts);
int au_opts_remount(struct super_block *sb, struct au_opts *opts);
unsigned int au_opt_udba(struct super_block *sb);
......
......@@ -60,6 +60,7 @@ ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
void sysaufs_br_init(struct au_branch *br);
void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
#define sysaufs_brs_init() do {} while (0)
......@@ -71,6 +72,7 @@ AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
struct attribute *attr, char *buf)
AuStubVoid(sysaufs_br_init, struct au_branch *br)
AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
static inline void sysaufs_brs_init(void)
{
......
......@@ -198,6 +198,29 @@ void sysaufs_br_init(struct au_branch *br)
}
}
void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
{
struct au_branch *br;
struct kobject *kobj;
struct au_brsysfs *br_sysfs;
int i;
aufs_bindex_t bbot;
if (!sysaufs_brs)
return;
kobj = &au_sbi(sb)->si_kobj;
bbot = au_sbbot(sb);
for (; bindex <= bbot; bindex++) {
br = au_sbr(sb, bindex);
br_sysfs = br->br_sysfs;
for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
sysfs_remove_file(kobj, &br_sysfs->attr);
br_sysfs++;
}
}
}
void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
{
int err, i;
......
......@@ -1564,12 +1564,14 @@ void au_xino_clr(struct super_block *sb)
au_opt_clr(sbinfo->si_mntflags, XINO);
}
int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt)
int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount)
{
int err;
struct dentry *dentry, *parent;
int err, skip;
struct dentry *dentry, *parent, *cur_dentry, *cur_parent;
struct qstr *dname, *cur_name;
struct file *cur_xino;
struct au_sbinfo *sbinfo;
struct path *path;
struct path *path, *cur_path;
SiMustWriteLock(sb);
......@@ -1578,6 +1580,23 @@ int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt)
path = &xiopt->file->f_path;
dentry = path->dentry;
parent = dget_parent(dentry);
if (remount) {
skip = 0;
cur_xino = sbinfo->si_xib;
if (cur_xino) {
cur_path = &cur_xino->f_path;
cur_dentry = cur_path->dentry;
cur_parent = dget_parent(cur_dentry);
cur_name = &cur_dentry->d_name;
dname = &dentry->d_name;
skip = (cur_parent == parent
&& au_qstreq(dname, cur_name));
dput(cur_parent);
}
if (skip)
goto out;
}
au_opt_set(sbinfo->si_mntflags, XINO);
err = au_xino_set_xib(sb, path);
/* si_x{read,write} are set */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment