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: ...@@ -92,6 +92,32 @@ out:
return err; 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 au_refresh_hinode_self(struct inode *inode)
{ {
int err, update; int err, update;
......
...@@ -116,6 +116,7 @@ static inline struct au_iinfo *au_ii(struct inode *inode) ...@@ -116,6 +116,7 @@ static inline struct au_iinfo *au_ii(struct inode *inode)
/* inode.c */ /* inode.c */
struct inode *au_igrab(struct inode *inode); 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_self(struct inode *inode);
int au_refresh_hinode(struct inode *inode, struct dentry *dentry); 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, 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) ...@@ -1286,7 +1286,7 @@ int au_opts_remount(struct super_block *sb, struct au_opts *opts)
err = rerr; err = rerr;
if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL)) 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)) { if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
rerr = au_xib_trunc(sb); rerr = au_xib_trunc(sb);
...@@ -1298,7 +1298,7 @@ int au_opts_remount(struct super_block *sb, struct au_opts *opts) ...@@ -1298,7 +1298,7 @@ int au_opts_remount(struct super_block *sb, struct au_opts *opts)
if (!au_ftest_opts(opts->flags, REFRESH) if (!au_ftest_opts(opts->flags, REFRESH)
&& (opts->given_udba && (opts->given_udba
|| au_opt_test(sbinfo->si_mntflags, XINO) || 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); au_fset_opts(opts->flags, REFRESH);
......
...@@ -135,7 +135,7 @@ struct au_opt { ...@@ -135,7 +135,7 @@ struct au_opt {
#define AuOpts_REFRESH (1 << 1) #define AuOpts_REFRESH (1 << 1)
#define AuOpts_TRUNC_XIB (1 << 2) #define AuOpts_TRUNC_XIB (1 << 2)
#define AuOpts_REFRESH_DYAOP (1 << 3) #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_ftest_opts(flags, name) ((flags) & AuOpts_##name)
#define au_fset_opts(flags, name) \ #define au_fset_opts(flags, name) \
do { (flags) |= AuOpts_##name; } while (0) do { (flags) |= AuOpts_##name; } while (0)
......
...@@ -460,7 +460,7 @@ static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, ...@@ -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, static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
struct au_sbinfo *sbinfo, struct au_sbinfo *sbinfo,
const unsigned int dir_flags, unsigned int do_dop) const unsigned int dir_flags, unsigned int do_idop)
{ {
int err; int err;
struct dentry *parent; struct dentry *parent;
...@@ -484,7 +484,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, ...@@ -484,7 +484,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
dput(parent); dput(parent);
if (!err) { if (!err) {
if (do_dop) if (do_idop)
au_refresh_dop(dentry, /*force_reval*/0); au_refresh_dop(dentry, /*force_reval*/0);
} else } else
au_refresh_dop(dentry, /*force_reval*/1); au_refresh_dop(dentry, /*force_reval*/1);
...@@ -493,7 +493,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, ...@@ -493,7 +493,7 @@ static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
return err; 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; int err, i, j, ndentry, e;
unsigned int sigen; unsigned int sigen;
...@@ -504,7 +504,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop) ...@@ -504,7 +504,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
struct dentry *root = sb->s_root; struct dentry *root = sb->s_root;
const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); 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); au_refresh_dop(root, /*force_reval*/0);
err = au_dpages_init(&dpages, GFP_NOFS); err = au_dpages_init(&dpages, GFP_NOFS);
...@@ -523,7 +523,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop) ...@@ -523,7 +523,7 @@ static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
for (j = 0; j < ndentry; j++) { for (j = 0; j < ndentry; j++) {
d = dentries[j]; d = dentries[j];
e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
do_dop); do_idop);
if (unlikely(e && !err)) if (unlikely(e && !err))
err = e; err = e;
/* go on even err */ /* go on even err */
...@@ -536,7 +536,7 @@ out: ...@@ -536,7 +536,7 @@ out:
return err; 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; int err, e;
unsigned int sigen; unsigned int sigen;
...@@ -554,17 +554,22 @@ static int au_refresh_i(struct super_block *sb) ...@@ -554,17 +554,22 @@ static int au_refresh_i(struct super_block *sb)
inode = array[ull]; inode = array[ull];
if (unlikely(!inode)) if (unlikely(!inode))
break; break;
if (au_iigen(inode, NULL) != sigen) {
e = 0;
ii_write_lock_child(inode); ii_write_lock_child(inode);
if (au_iigen(inode, NULL) != sigen) {
e = au_refresh_hinode_self(inode); e = au_refresh_hinode_self(inode);
ii_write_unlock(inode);
if (unlikely(e)) { if (unlikely(e)) {
au_refresh_iop(inode, /*force_getattr*/1);
pr_err("error %d, i%lu\n", e, inode->i_ino); pr_err("error %d, i%lu\n", e, inode->i_ino);
if (!err) if (!err)
err = e; err = e;
/* go on even if err */ /* 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); au_iarray_free(array, max);
...@@ -573,7 +578,7 @@ out: ...@@ -573,7 +578,7 @@ out:
return err; 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; int err, e;
unsigned int udba; unsigned int udba;
...@@ -604,20 +609,25 @@ static void au_remount_refresh(struct super_block *sb, unsigned int do_dop) ...@@ -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)); au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
if (do_dop) { if (do_idop) {
if (au_ftest_si(sbi, NO_DREVAL)) { if (au_ftest_si(sbi, NO_DREVAL)) {
AuDebugOn(sb->s_d_op == &aufs_dop_noreval); AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
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 { } else {
AuDebugOn(sb->s_d_op == &aufs_dop); AuDebugOn(sb->s_d_op == &aufs_dop);
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); di_write_unlock(root);
err = au_refresh_d(sb, do_dop); err = au_refresh_d(sb, do_idop);
e = au_refresh_i(sb); e = au_refresh_i(sb, do_idop);
if (unlikely(e && !err)) if (unlikely(e && !err))
err = e; err = e;
/* aufs_write_lock() calls ..._child() */ /* aufs_write_lock() calls ..._child() */
...@@ -693,7 +703,7 @@ static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) ...@@ -693,7 +703,7 @@ static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
au_opts_free(&opts); au_opts_free(&opts);
if (au_ftest_opts(opts.flags, REFRESH)) 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)) { if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
mntflags = au_mntflags(sb); mntflags = au_mntflags(sb);
...@@ -830,6 +840,8 @@ static int aufs_fill_super(struct super_block *sb, void *raw_data, ...@@ -830,6 +840,8 @@ static int aufs_fill_super(struct super_block *sb, void *raw_data,
sb->s_d_op = &aufs_dop_noreval; sb->s_d_op = &aufs_dop_noreval;
pr_info("%ps\n", sb->s_d_op); pr_info("%ps\n", sb->s_d_op);
au_refresh_dop(root, /*force_reval*/0); 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); aufs_write_unlock(root);
inode_unlock(inode); 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