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

aufs: udba=none has no ->getattr() 2/2, refresh inode_operations



An enhancement for udba=none if possible.
The condition is same to the 'no ->d_revalidate()' patch series.
Refresh i_op in all cached inodes at the remount-time.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 46b85e53
......@@ -92,6 +92,32 @@ out:
return err;
}
void au_refresh_iop(struct inode *inode, int force_getattr)
{
int type;
struct au_sbinfo *sbi = au_sbi(inode->i_sb);
const struct inode_operations *iop
= force_getattr ? aufs_iop : sbi->si_iop_array;
if (inode->i_op == iop)
return;
switch (inode->i_mode & S_IFMT) {
case S_IFDIR:
type = AuIop_DIR;
break;
case S_IFLNK:
type = AuIop_SYMLINK;
break;
default:
type = AuIop_OTHER;
break;
}
inode->i_op = iop + type;
/* unnecessary smp_wmb() */
}
int au_refresh_hinode_self(struct inode *inode)
{
int err, update;
......
......@@ -116,6 +116,7 @@ static inline struct au_iinfo *au_ii(struct inode *inode)
/* inode.c */
struct inode *au_igrab(struct inode *inode);
void au_refresh_iop(struct inode *inode, int force_getattr);
int au_refresh_hinode_self(struct inode *inode);
int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
......
......@@ -1286,7 +1286,7 @@ int au_opts_remount(struct super_block *sb, struct au_opts *opts)
err = rerr;
if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
au_fset_opts(opts->flags, REFRESH_DOP);
au_fset_opts(opts->flags, REFRESH_IDOP);
if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
rerr = au_xib_trunc(sb);
......@@ -1298,7 +1298,7 @@ int au_opts_remount(struct super_block *sb, struct au_opts *opts)
if (!au_ftest_opts(opts->flags, REFRESH)
&& (opts->given_udba
|| au_opt_test(sbinfo->si_mntflags, XINO)
|| au_ftest_opts(opts->flags, REFRESH_DOP)
|| au_ftest_opts(opts->flags, REFRESH_IDOP)
))
au_fset_opts(opts->flags, REFRESH);
......
......@@ -135,7 +135,7 @@ struct au_opt {
#define AuOpts_REFRESH (1 << 1)
#define AuOpts_TRUNC_XIB (1 << 2)
#define AuOpts_REFRESH_DYAOP (1 << 3)
#define AuOpts_REFRESH_DOP (1 << 4)
#define AuOpts_REFRESH_IDOP (1 << 4)
#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
#define au_fset_opts(flags, name) \
do { (flags) |= AuOpts_##name; } while (0)
......
......@@ -460,7 +460,7 @@ static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
struct au_sbinfo *sbinfo,
const unsigned int dir_flags, unsigned int do_dop)
const unsigned int dir_flags, unsigned int do_idop)
{
int err;
struct dentry *parent;
......@@ -484,7 +484,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
dput(parent);
if (!err) {
if (do_dop)
if (do_idop)
au_refresh_dop(dentry, /*force_reval*/0);
} else
au_refresh_dop(dentry, /*force_reval*/1);
......@@ -493,7 +493,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
return err;
}
static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
{
int err, i, j, ndentry, e;
unsigned int sigen;
......@@ -504,7 +504,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
struct dentry *root = sb->s_root;
const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
if (do_dop)
if (do_idop)
au_refresh_dop(root, /*force_reval*/0);
err = au_dpages_init(&dpages, GFP_NOFS);
......@@ -523,7 +523,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
for (j = 0; j < ndentry; j++) {
d = dentries[j];
e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
do_dop);
do_idop);
if (unlikely(e && !err))
err = e;
/* go on even err */
......@@ -536,7 +536,7 @@ out:
return err;
}
static int au_refresh_i(struct super_block *sb)
static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
{
int err, e;
unsigned int sigen;
......@@ -554,17 +554,22 @@ static int au_refresh_i(struct super_block *sb)
inode = array[ull];
if (unlikely(!inode))
break;
e = 0;
ii_write_lock_child(inode);
if (au_iigen(inode, NULL) != sigen) {
ii_write_lock_child(inode);
e = au_refresh_hinode_self(inode);
ii_write_unlock(inode);
if (unlikely(e)) {
au_refresh_iop(inode, /*force_getattr*/1);
pr_err("error %d, i%lu\n", e, inode->i_ino);
if (!err)
err = e;
/* go on even if err */
}
}
if (!e && do_idop)
au_refresh_iop(inode, /*force_getattr*/0);
ii_write_unlock(inode);
}
au_iarray_free(array, max);
......@@ -573,7 +578,7 @@ out:
return err;
}
static void au_remount_refresh(struct super_block *sb, unsigned int do_dop)
static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
{
int err, e;
unsigned int udba;
......@@ -604,20 +609,25 @@ static void au_remount_refresh(struct super_block *sb, unsigned int do_dop)
}
au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
if (do_dop) {
if (do_idop) {
if (au_ftest_si(sbi, NO_DREVAL)) {
AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
sb->s_d_op = &aufs_dop_noreval;
AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
sbi->si_iop_array = aufs_iop_nogetattr;
} else {
AuDebugOn(sb->s_d_op == &aufs_dop);
sb->s_d_op = &aufs_dop;
AuDebugOn(sbi->si_iop_array == aufs_iop);
sbi->si_iop_array = aufs_iop;
}
pr_info("reset to %ps\n", sb->s_d_op);
pr_info("reset to %ps and %ps\n",
sb->s_d_op, sbi->si_iop_array);
}
di_write_unlock(root);
err = au_refresh_d(sb, do_dop);
e = au_refresh_i(sb);
err = au_refresh_d(sb, do_idop);
e = au_refresh_i(sb, do_idop);
if (unlikely(e && !err))
err = e;
/* aufs_write_lock() calls ..._child() */
......@@ -693,7 +703,7 @@ static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
au_opts_free(&opts);
if (au_ftest_opts(opts.flags, REFRESH))
au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_DOP));
au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
mntflags = au_mntflags(sb);
......@@ -830,6 +840,8 @@ static int aufs_fill_super(struct super_block *sb, void *raw_data,
sb->s_d_op = &aufs_dop_noreval;
pr_info("%ps\n", sb->s_d_op);
au_refresh_dop(root, /*force_reval*/0);
sbinfo->si_iop_array = aufs_iop_nogetattr;
au_refresh_iop(inode, /*force_getattr*/0);
}
aufs_write_unlock(root);
inode_unlock(inode);
......
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