summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-04-06 07:48:27 +1000
committerDave Chinner <david@fromorbit.com>2016-04-06 07:48:27 +1000
commit2b3d1d41b4d96c3b074096ae57b27cd191969643 (patch)
tree5b05d844bddc7215b809eebc88c27c5636761a83 /fs/xfs/xfs_iops.c
parent143f4aede7fb25b9198b15660d6f9830936394a8 (diff)
xfs: set up inode operation vectors later
In the next patch we'll set up different inode operations for inline vs out of line symlinks, for that we need to make sure the flags are already set up properly. [dchinner: added xfs_setup_iops() call to xfs_rename_alloc_whiteout()] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index fb7dc61f4a29..f08d91c51b7f 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -181,6 +181,8 @@ xfs_generic_create(
}
#endif
+ xfs_setup_iops(ip);
+
if (tmpfile)
d_tmpfile(dentry, inode);
else
@@ -368,6 +370,8 @@ xfs_vn_symlink(
if (unlikely(error))
goto out_cleanup_inode;
+ xfs_setup_iops(cip);
+
d_instantiate(dentry, inode);
xfs_finish_inode_setup(cip);
return 0;
@@ -1193,7 +1197,7 @@ xfs_diflags_to_iflags(
}
/*
- * Initialize the Linux inode and set up the operation vectors.
+ * Initialize the Linux inode.
*
* When reading existing inodes from disk this is called directly from xfs_iget,
* when creating a new inode it is called from xfs_ialloc after setting up the
@@ -1232,8 +1236,38 @@ xfs_setup_inode(
i_size_write(inode, ip->i_d.di_size);
xfs_diflags_to_iflags(inode, ip);
- ip->d_ops = ip->i_mount->m_nondir_inode_ops;
- lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
+ if (S_ISDIR(inode->i_mode)) {
+ lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
+ ip->d_ops = ip->i_mount->m_dir_inode_ops;
+ } else {
+ ip->d_ops = ip->i_mount->m_nondir_inode_ops;
+ lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
+ }
+
+ /*
+ * Ensure all page cache allocations are done from GFP_NOFS context to
+ * prevent direct reclaim recursion back into the filesystem and blowing
+ * stacks or deadlocking.
+ */
+ gfp_mask = mapping_gfp_mask(inode->i_mapping);
+ mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
+
+ /*
+ * If there is no attribute fork no ACL can exist on this inode,
+ * and it can't have any file capabilities attached to it either.
+ */
+ if (!XFS_IFORK_Q(ip)) {
+ inode_has_no_xattr(inode);
+ cache_no_acl(inode);
+ }
+}
+
+void
+xfs_setup_iops(
+ struct xfs_inode *ip)
+{
+ struct inode *inode = &ip->i_vnode;
+
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_op = &xfs_inode_operations;
@@ -1241,13 +1275,11 @@ xfs_setup_inode(
inode->i_mapping->a_ops = &xfs_address_space_operations;
break;
case S_IFDIR:
- lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
inode->i_op = &xfs_dir_ci_inode_operations;
else
inode->i_op = &xfs_dir_inode_operations;
inode->i_fop = &xfs_dir_file_operations;
- ip->d_ops = ip->i_mount->m_dir_inode_ops;
break;
case S_IFLNK:
inode->i_op = &xfs_symlink_inode_operations;
@@ -1259,21 +1291,4 @@ xfs_setup_inode(
init_special_inode(inode, inode->i_mode, inode->i_rdev);
break;
}
-
- /*
- * Ensure all page cache allocations are done from GFP_NOFS context to
- * prevent direct reclaim recursion back into the filesystem and blowing
- * stacks or deadlocking.
- */
- gfp_mask = mapping_gfp_mask(inode->i_mapping);
- mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
-
- /*
- * If there is no attribute fork no ACL can exist on this inode,
- * and it can't have any file capabilities attached to it either.
- */
- if (!XFS_IFORK_Q(ip)) {
- inode_has_no_xattr(inode);
- cache_no_acl(inode);
- }
}