xfs: set up inode operation vectors later
authorChristoph Hellwig <hch@lst.de>
Tue, 5 Apr 2016 21:48:27 +0000 (07:48 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 5 Apr 2016 21:48:27 +0000 (07:48 +1000)
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>
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_iops.c

index 96f606d..4fcd6a7 100644 (file)
@@ -2855,6 +2855,7 @@ xfs_rename_alloc_whiteout(
         * and flag it as linkable.
         */
        drop_nlink(VFS_I(tmpfile));
+       xfs_setup_iops(tmpfile);
        xfs_finish_inode_setup(tmpfile);
        VFS_I(tmpfile)->i_state |= I_LINKABLE;
 
index 43e1d51..e52d7c7 100644 (file)
@@ -440,6 +440,9 @@ loff_t      __xfs_seek_hole_data(struct inode *inode, loff_t start,
 
 
 /* from xfs_iops.c */
+extern void xfs_setup_inode(struct xfs_inode *ip);
+extern void xfs_setup_iops(struct xfs_inode *ip);
+
 /*
  * When setting up a newly allocated inode, we need to call
  * xfs_finish_inode_setup() once the inode is fully instantiated at
@@ -447,7 +450,6 @@ loff_t      __xfs_seek_hole_data(struct inode *inode, loff_t start,
  * before we've completed instantiation. Otherwise we can do it
  * the moment the inode lookup is complete.
  */
-extern void xfs_setup_inode(struct xfs_inode *ip);
 static inline void xfs_finish_inode_setup(struct xfs_inode *ip)
 {
        xfs_iflags_clear(ip, XFS_INEW);
@@ -458,6 +460,7 @@ static inline void xfs_finish_inode_setup(struct xfs_inode *ip)
 static inline void xfs_setup_existing_inode(struct xfs_inode *ip)
 {
        xfs_setup_inode(ip);
+       xfs_setup_iops(ip);
        xfs_finish_inode_setup(ip);
 }
 
index fb7dc61..f08d91c 100644 (file)
@@ -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);
-       }
 }