]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/xfs/xfs_iops.c
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / fs / xfs / xfs_iops.c
index fe285d123d69f1eb8c749ad145a02ea36c96904a..8afe69ca188bb8ae2132d7318201001d85ed445f 100644 (file)
@@ -20,6 +20,7 @@
 #include "xfs_symlink.h"
 #include "xfs_dir2.h"
 #include "xfs_iomap.h"
+#include "xfs_error.h"
 
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
@@ -470,20 +471,57 @@ xfs_vn_get_link_inline(
        struct inode            *inode,
        struct delayed_call     *done)
 {
+       struct xfs_inode        *ip = XFS_I(inode);
        char                    *link;
 
-       ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE);
+       ASSERT(ip->i_df.if_flags & XFS_IFINLINE);
 
        /*
         * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if
         * if_data is junk.
         */
-       link = XFS_I(inode)->i_df.if_u1.if_data;
-       if (!link)
+       link = ip->i_df.if_u1.if_data;
+       if (XFS_IS_CORRUPT(ip->i_mount, !link))
                return ERR_PTR(-EFSCORRUPTED);
        return link;
 }
 
+static uint32_t
+xfs_stat_blksize(
+       struct xfs_inode        *ip)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+
+       /*
+        * If the file blocks are being allocated from a realtime volume, then
+        * always return the realtime extent size.
+        */
+       if (XFS_IS_REALTIME_INODE(ip))
+               return xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog;
+
+       /*
+        * Allow large block sizes to be reported to userspace programs if the
+        * "largeio" mount option is used.
+        *
+        * If compatibility mode is specified, simply return the basic unit of
+        * caching so that we don't get inefficient read/modify/write I/O from
+        * user apps. Otherwise....
+        *
+        * If the underlying volume is a stripe, then return the stripe width in
+        * bytes as the recommended I/O size. It is not a stripe and we've set a
+        * default buffered I/O size, return that, otherwise return the compat
+        * default.
+        */
+       if (mp->m_flags & XFS_MOUNT_LARGEIO) {
+               if (mp->m_swidth)
+                       return mp->m_swidth << mp->m_sb.sb_blocklog;
+               if (mp->m_flags & XFS_MOUNT_ALLOCSIZE)
+                       return 1U << mp->m_allocsize_log;
+       }
+
+       return PAGE_SIZE;
+}
+
 STATIC int
 xfs_vn_getattr(
        const struct path       *path,
@@ -516,8 +554,7 @@ xfs_vn_getattr(
        if (ip->i_d.di_version == 3) {
                if (request_mask & STATX_BTIME) {
                        stat->result_mask |= STATX_BTIME;
-                       stat->btime.tv_sec = ip->i_d.di_crtime.t_sec;
-                       stat->btime.tv_nsec = ip->i_d.di_crtime.t_nsec;
+                       stat->btime = ip->i_d.di_crtime;
                }
        }
 
@@ -543,16 +580,7 @@ xfs_vn_getattr(
                stat->rdev = inode->i_rdev;
                break;
        default:
-               if (XFS_IS_REALTIME_INODE(ip)) {
-                       /*
-                        * If the file blocks are being allocated from a
-                        * realtime volume, then return the inode's realtime
-                        * extent size or the realtime volume's extent size.
-                        */
-                       stat->blksize =
-                               xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog;
-               } else
-                       stat->blksize = xfs_preferred_iosize(mp);
+               stat->blksize = xfs_stat_blksize(ip);
                stat->rdev = 0;
                break;
        }
@@ -664,7 +692,7 @@ xfs_setattr_nonsize(
                ASSERT(gdqp == NULL);
                error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid),
                                           xfs_kgid_to_gid(gid),
-                                          xfs_get_projid(ip),
+                                          ip->i_d.di_projid,
                                           qflags, &udqp, &gdqp, NULL);
                if (error)
                        return error;
@@ -883,10 +911,10 @@ xfs_setattr_size(
        if (newsize > oldsize) {
                trace_xfs_zero_eof(ip, oldsize, newsize - oldsize);
                error = iomap_zero_range(inode, oldsize, newsize - oldsize,
-                               &did_zeroing, &xfs_iomap_ops);
+                               &did_zeroing, &xfs_buffered_write_iomap_ops);
        } else {
                error = iomap_truncate_page(inode, newsize, &did_zeroing,
-                               &xfs_iomap_ops);
+                               &xfs_buffered_write_iomap_ops);
        }
 
        if (error)
@@ -1114,7 +1142,7 @@ xfs_vn_fiemap(
                                &xfs_xattr_iomap_ops);
        } else {
                error = iomap_fiemap(inode, fieinfo, start, length,
-                               &xfs_iomap_ops);
+                               &xfs_read_iomap_ops);
        }
        xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED);
 
@@ -1227,7 +1255,7 @@ xfs_inode_supports_dax(
                return false;
 
        /* Device has to support DAX too. */
-       return xfs_find_daxdev_for_inode(VFS_I(ip)) != NULL;
+       return xfs_inode_buftarg(ip)->bt_daxdev != NULL;
 }
 
 STATIC void
@@ -1290,9 +1318,7 @@ xfs_setup_inode(
                lockdep_set_class(&inode->i_rwsem,
                                  &inode->i_sb->s_type->i_mutex_dir_key);
                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);
        }