summaryrefslogtreecommitdiff
path: root/fs/aufs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/inode.c')
-rw-r--r--fs/aufs/inode.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c
index 559da3358..6db3d6f62 100644
--- a/fs/aufs/inode.c
+++ b/fs/aufs/inode.c
@@ -87,6 +87,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;
@@ -168,11 +194,13 @@ static int set_inode(struct inode *inode, struct dentry *dentry)
struct dentry *h_dentry;
struct inode *h_inode;
struct au_iinfo *iinfo;
+ struct inode_operations *iop;
IiMustWriteLock(inode);
err = 0;
isdir = 0;
+ iop = au_sbi(inode->i_sb)->si_iop_array;
bstart = au_dbstart(dentry);
h_dentry = au_h_dptr(dentry, bstart);
h_inode = d_inode(h_dentry);
@@ -180,7 +208,7 @@ static int set_inode(struct inode *inode, struct dentry *dentry)
switch (mode & S_IFMT) {
case S_IFREG:
btail = au_dbtail(dentry);
- inode->i_op = &aufs_iop;
+ inode->i_op = iop + AuIop_OTHER;
inode->i_fop = &aufs_file_fop;
err = au_dy_iaop(inode, bstart, h_inode);
if (unlikely(err))
@@ -189,19 +217,19 @@ static int set_inode(struct inode *inode, struct dentry *dentry)
case S_IFDIR:
isdir = 1;
btail = au_dbtaildir(dentry);
- inode->i_op = &aufs_dir_iop;
+ inode->i_op = iop + AuIop_DIR;
inode->i_fop = &aufs_dir_fop;
break;
case S_IFLNK:
btail = au_dbtail(dentry);
- inode->i_op = &aufs_symlink_iop;
+ inode->i_op = iop + AuIop_SYMLINK;
break;
case S_IFBLK:
case S_IFCHR:
case S_IFIFO:
case S_IFSOCK:
btail = au_dbtail(dentry);
- inode->i_op = &aufs_iop;
+ inode->i_op = iop + AuIop_OTHER;
init_special_inode(inode, mode, h_inode->i_rdev);
break;
default: