diff options
Diffstat (limited to 'fs/aufs/inode.c')
-rw-r--r-- | fs/aufs/inode.c | 36 |
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: |