Skip to content

Commit

Permalink
Linux 4.11 compat: vfs_getattr() takes 4 args
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Olaf Faaland <[email protected]>
Closes openzfs#608
  • Loading branch information
ofaaland authored and behlendorf committed Mar 21, 2017
1 parent e0aacd9 commit 94b1ab2
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 20 deletions.
69 changes: 52 additions & 17 deletions config/spl-build.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
])
])

Expand Down
13 changes: 10 additions & 3 deletions module/spl/spl-vnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 94b1ab2

Please sign in to comment.