Merge tag 'libnvdimm-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdim...
[linux-2.6-block.git] / fs / xfs / xfs_iops.c
index ce0c1f9466a8ca88fd95877ba51beef86c897451..3b4be06fdaa57112150770c84d62f048261a00c8 100644 (file)
@@ -259,6 +259,7 @@ xfs_vn_lookup(
        struct dentry   *dentry,
        unsigned int flags)
 {
+       struct inode *inode;
        struct xfs_inode *cip;
        struct xfs_name name;
        int             error;
@@ -268,14 +269,13 @@ xfs_vn_lookup(
 
        xfs_dentry_to_name(&name, dentry);
        error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
-       if (unlikely(error)) {
-               if (unlikely(error != -ENOENT))
-                       return ERR_PTR(error);
-               d_add(dentry, NULL);
-               return NULL;
-       }
-
-       return d_splice_alias(VFS_I(cip), dentry);
+       if (likely(!error))
+               inode = VFS_I(cip);
+       else if (likely(error == -ENOENT))
+               inode = NULL;
+       else
+               inode = ERR_PTR(error);
+       return d_splice_alias(inode, dentry);
 }
 
 STATIC struct dentry *
@@ -854,7 +854,7 @@ xfs_setattr_size(
        /*
         * Make sure that the dquots are attached to the inode.
         */
-       error = xfs_qm_dqattach(ip, 0);
+       error = xfs_qm_dqattach(ip);
        if (error)
                return error;
 
@@ -1199,6 +1199,30 @@ static const struct inode_operations xfs_inline_symlink_inode_operations = {
        .update_time            = xfs_vn_update_time,
 };
 
+/* Figure out if this file actually supports DAX. */
+static bool
+xfs_inode_supports_dax(
+       struct xfs_inode        *ip)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+
+       /* Only supported on non-reflinked files. */
+       if (!S_ISREG(VFS_I(ip)->i_mode) || xfs_is_reflink_inode(ip))
+               return false;
+
+       /* DAX mount option or DAX iflag must be set. */
+       if (!(mp->m_flags & XFS_MOUNT_DAX) &&
+           !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+               return false;
+
+       /* Block size must match page size */
+       if (mp->m_sb.sb_blocksize != PAGE_SIZE)
+               return false;
+
+       /* Device has to support DAX too. */
+       return xfs_find_daxdev_for_inode(VFS_I(ip)) != NULL;
+}
+
 STATIC void
 xfs_diflags_to_iflags(
        struct inode            *inode,
@@ -1217,11 +1241,7 @@ xfs_diflags_to_iflags(
                inode->i_flags |= S_SYNC;
        if (flags & XFS_DIFLAG_NOATIME)
                inode->i_flags |= S_NOATIME;
-       if (S_ISREG(inode->i_mode) &&
-           ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
-           !xfs_is_reflink_inode(ip) &&
-           (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
-            ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+       if (xfs_inode_supports_dax(ip))
                inode->i_flags |= S_DAX;
 }