]> granicus.if.org Git - zfs/commitdiff
Linux 4.11 compat: vfs_getattr() takes 4 args
authorOlaf Faaland <faaland1@llnl.gov>
Tue, 7 Mar 2017 21:18:53 +0000 (13:18 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 21 Mar 2017 00:43:39 +0000 (17:43 -0700)
There are changes to vfs_getattr() in torvalds/linux@a528d35.  The new
interface is:

int vfs_getattr(const struct path *path, struct kstat *stat,
               u32 request_mask, unsigned int query_flags)

The request_mask argument indicates which field(s) the caller intends to
use.  Fields the caller does not specify via request_mask may be set in
the returned struct anyway, but their values may be approximate.

The query_flags argument indicates whether the filesystem must update
the attributes from the backing store.

This patch uses the query_flags which result in vfs_getattr behaving the same
as it did with the 2-argument version which the kernel provided before
Linux 4.11.

Members blksize and blocks are now always the same size regardless of
arch.  They match the size of the equivalent members in vnode_t.

The configure checks are modified to ensure that the appropriate
vfs_getattr() interface is used.

A more complete fix, removing the ZFS dependency on vfs_getattr()
entirely, is deferred as it is a much larger project.

Reviewed-by: Chunwei Chen <david.chen@osnexus.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Closes #608

config/spl-build.m4
module/spl/spl-vnode.c

index 8d0e8aba3ccd2b85c726a61da9f985081068d5cf..fc0efcf39cbdf1132d3cb28d699989603f697543 100644 (file)
@@ -43,6 +43,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
        SPL_AC_RWSEM_ACTIVITY
        SPL_AC_RWSEM_ATOMIC_LONG_COUNT
        SPL_AC_SCHED_RT_HEADER
+       SPL_AC_4ARGS_VFS_GETATTR
+       SPL_AC_3ARGS_VFS_GETATTR
        SPL_AC_2ARGS_VFS_GETATTR
        SPL_AC_USLEEP_RANGE
        SPL_AC_KMEM_CACHE_ALLOCFLAGS
@@ -1409,34 +1411,67 @@ AC_DEFUN([SPL_AC_SCHED_RT_HEADER],
        ])
 ])
 
+
 dnl #
-dnl # 3.9 API change,
-dnl # vfs_getattr() uses 2 args
-dnl # It takes struct path * instead of struct vfsmount * and struct dentry *
+dnl # 4.11 API, a528d35e@torvalds/linux
+dnl # vfs_getattr(const struct path *p, struct kstat *s, u32 m, unsigned int f)
+dnl #
+AC_DEFUN([SPL_AC_4ARGS_VFS_GETATTR], [
+       AC_MSG_CHECKING([whether vfs_getattr() wants 4 args])
+       SPL_LINUX_TRY_COMPILE([
+               #include <linux/fs.h>
+       ],[
+               vfs_getattr((const struct path *)NULL,
+                       (struct kstat *)NULL,
+                       (u32)0,
+                       (unsigned int)0);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_4ARGS_VFS_GETATTR, 1,
+                 [vfs_getattr wants 4 args])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+])
+
+dnl #
+dnl # 3.9 API 
+dnl # vfs_getattr(struct path *p, struct kstat *s)
 dnl #
 AC_DEFUN([SPL_AC_2ARGS_VFS_GETATTR], [
-       AC_MSG_CHECKING([whether vfs_getattr() wants])
+       AC_MSG_CHECKING([whether vfs_getattr() wants 2 args])
        SPL_LINUX_TRY_COMPILE([
                #include <linux/fs.h>
        ],[
                vfs_getattr((struct path *) NULL,
                        (struct kstat *)NULL);
        ],[
-               AC_MSG_RESULT(2 args)
+               AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1,
-                         [vfs_getattr wants 2 args])
+                         [vfs_getattr wants 2 args])
        ],[
-               SPL_LINUX_TRY_COMPILE([
-                       #include <linux/fs.h>
-               ],[
-                       vfs_getattr((struct vfsmount *)NULL,
-                               (struct dentry *)NULL,
-                               (struct kstat *)NULL);
-               ],[
-                       AC_MSG_RESULT(3 args)
-               ],[
-                       AC_MSG_ERROR(unknown)
-               ])
+               AC_MSG_RESULT(no)
+       ])
+])
+
+dnl #
+dnl # <3.9 API 
+dnl # vfs_getattr(struct vfsmount *v, struct dentry *d, struct kstat *k)
+dnl #
+AC_DEFUN([SPL_AC_3ARGS_VFS_GETATTR], [
+       AC_MSG_CHECKING([whether vfs_getattr() wants 3 args])
+       SPL_LINUX_TRY_COMPILE([
+               #include <linux/fs.h>
+       ],[
+               vfs_getattr((struct vfsmount *)NULL,
+                       (struct dentry *)NULL,
+                       (struct kstat *)NULL);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_3ARGS_VFS_GETATTR, 1,
+                 [vfs_getattr wants 3 args])
+       ],[
+               AC_MSG_RESULT(no)
        ])
 ])
 
index cd276b5c847d6e9622eb9c222c230d6ccf323d48..0902e11618cae09247c8e57b089f85809adfd1c3 100644 (file)
@@ -153,7 +153,9 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
        if (IS_ERR(fp))
                return (-PTR_ERR(fp));
 
-#ifdef HAVE_2ARGS_VFS_GETATTR
+#if defined(HAVE_4ARGS_VFS_GETATTR)
+       rc = vfs_getattr(&fp->f_path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
+#elif defined(HAVE_2ARGS_VFS_GETATTR)
        rc = vfs_getattr(&fp->f_path, &stat);
 #else
        rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
@@ -510,7 +512,10 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
 
        fp = vp->v_file;
 
-#ifdef HAVE_2ARGS_VFS_GETATTR
+#if defined(HAVE_4ARGS_VFS_GETATTR)
+       rc = vfs_getattr(&fp->f_path, &stat, STATX_BASIC_STATS,
+           AT_STATX_SYNC_AS_STAT);
+#elif defined(HAVE_2ARGS_VFS_GETATTR)
        rc = vfs_getattr(&fp->f_path, &stat);
 #else
        rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
@@ -708,7 +713,9 @@ vn_getf(int fd)
        if (vp == NULL)
                goto out_fget;
 
-#ifdef HAVE_2ARGS_VFS_GETATTR
+#if defined(HAVE_4ARGS_VFS_GETATTR)
+       rc = vfs_getattr(&lfp->f_path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
+#elif defined(HAVE_2ARGS_VFS_GETATTR)
        rc = vfs_getattr(&lfp->f_path, &stat);
 #else
        rc = vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat);