Skip to content

Commit

Permalink
Linux 4.11 compat: iops.getattr and friends
Browse files Browse the repository at this point in the history
In torvalds/linux@a528d35, there are several changes to the getattr
family of functions, struct kstat, and the interface of inode_operations
.getattr.

The inode_operations .getattr interface changed to:

int (*getattr) (const struct path *, struct dentry *, struct kstat *,
    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
he 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.

Currently both fields are ignored.

struct kstat includes new fields:
u32               result_mask;  /* What fields the user got */
u64               attributes;   /* See STATX_ATTR_* flags */
struct timespec   btime;        /* File creation time */

XXX Currently none of these fields are populated.

The interface to simple_getattr() has changed to:

int simple_getattr(const struct path *, struct kstat *, u32,
    unsigned int);

Requires-spl: refs/pull/608/head
Requires-builders: distro

Signed-off-by: Olaf Faaland <[email protected]>
  • Loading branch information
ofaaland committed Mar 9, 2017
1 parent 9b77d1c commit d8ef1d3
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 5 deletions.
67 changes: 67 additions & 0 deletions config/kernel-inode-getattr.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
dnl #
dnl # Linux 4.11 API
dnl # See torvalds/linux@a528d35
dnl #
AC_DEFUN([ZFS_AC_5ARGS_KERNEL_IOPS_GETATTR], [
AC_MSG_CHECKING([whether iops->getattr() takes 5 arguments])
ZFS_LINUX_TRY_COMPILE([
#include <linux/fs.h>
int test_getattr(
const struct path *p, struct dentry *d, struct kstat *k,
u32 request_mask, unsigned int query_flags)
{ return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.getattr = test_getattr,
};
],[
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_5ARGS_IOPS_GETATTR, 1,
[iops->getattr() takes 5 arguments])
],[
AC_MSG_RESULT(no)
])
])



dnl #
dnl # Linux 3.9 - 4.10 API
dnl #
AC_DEFUN([ZFS_AC_3ARGS_KERNEL_IOPS_GETATTR], [
AC_MSG_CHECKING([whether iops->getattr() takes 3 arguments])
ZFS_LINUX_TRY_COMPILE([
#include <linux/fs.h>
int test_getattr(
struct vfsmount *mnt, struct dentry *d,
struct kstat *k)
{ return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.getattr = test_getattr,
};
],[
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_3ARGS_IOPS_GETATTR, 1,
[iops->getattr() takes 3 arguments])
],[
AC_MSG_RESULT(no)
])
])


dnl #
dnl # The interface of the getattr callback from the inode_operations
dnl # structure changed. Also, the interface of the simple_getattr()
dnl # function provided by the kernel changed.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR], [
ZFS_AC_5ARGS_KERNEL_IOPS_GETATTR
ZFS_AC_3ARGS_KERNEL_IOPS_GETATTR
])
55 changes: 55 additions & 0 deletions config/kernel-simple-getattr-args.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
dnl #
dnl # Linux 4.11 API
dnl #
AC_DEFUN([ZFS_AC_KERNEL_PATH_SIMPLE_GETATTR], [
AC_MSG_CHECKING([whether simple_getattr() takes a path])
ZFS_LINUX_TRY_COMPILE([
#include <linux/fs.h>
],[
int rc;
struct path *p = NULL;
struct dentry *d = NULL;
struct kstat *k = NULL;
u32 u = 0;
unsigned int i;
rc = simple_getattr(p, d, k, u, i);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PATH_SIMPLE_GETATTR, 1,
[simple_getattr() takes a path])
],[
AC_MSG_RESULT(no)
])
])



dnl #
dnl # Linux ?.? - 4.10 API
dnl #
AC_DEFUN([ZFS_AC_KERNEL_VFSMOUNT_SIMPLE_GETATTR], [
AC_MSG_CHECKING([whether simple_getattr() takes a vfsmount])
ZFS_LINUX_TRY_COMPILE([
#include <linux/fs.h>
],[
int rc;
struct vfsmount *v = NULL;
struct dentry *d = NULL;
struct kstat *k = NULL;
rc = simple_getattr(
v, d, k);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_VFSMOUNT_SIMPLE_GETATTR, 1,
[simple_getattr() takes a vfsmount])
],[
AC_MSG_RESULT(no)
])
])



AC_DEFUN([ZFS_AC_KERNEL_SIMPLE_GETATTR], [
ZFS_AC_KERNEL_VFSMOUNT_SIMPLE_GETATTR
ZFS_AC_KERNEL_PATH_SIMPLE_GETATTR
])
2 changes: 2 additions & 0 deletions config/kernel.m4
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR
ZFS_AC_KERNEL_SIMPLE_GETATTR
ZFS_AC_KERNEL_INODE_SET_FLAGS
ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
ZFS_AC_KERNEL_SHOW_OPTIONS
Expand Down
54 changes: 50 additions & 4 deletions module/zfs/zpl_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,35 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
* Get root directory attributes.
*/
/* ARGSUSED */

static int
zpl_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
zpl_root_getattr(
#if defined(HAVE_3ARGS_IOPS_GETATTR)
struct vfsmount *mnt,
struct dentry *dentry,
struct kstat *stat
#elif defined(HAVE_5ARGS_IOPS_GETATTR)
const struct path *path,
struct dentry *dentry,
struct kstat *stat,
uint32_t request_mask,
unsigned int query_flags
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
)
{
int error;

#if defined(HAVE_VFSMOUNT_SIMPLE_GETATTR) && defined(HAVE_3ARGS_IOPS_GETATTR)
error = simple_getattr(mnt, dentry, stat);
#elif defined(HAVE_PATH_SIMPLE_GETATTR) && defined(HAVE_5ARGS_IOPS_GETATTR)
error = simple_getattr(path, dentry, stat, request_mask, query_flags);
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
stat->atime = CURRENT_TIME;

return (error);
}


static struct dentry *
#ifdef HAVE_LOOKUP_NAMEIDATA
zpl_root_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd)
Expand Down Expand Up @@ -374,15 +391,28 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, zpl_umode_t mode)
* Get snapshot directory attributes.
*/
/* ARGSUSED */
#if defined(HAVE_3ARGS_IOPS_GETATTR)
static int
zpl_snapdir_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
#elif defined(HAVE_5ARGS_IOPS_GETATTR)
static int
zpl_snapdir_getattr(struct path *path, struct dentry *dentry,
struct kstat *stat, uint32_t request_mask,
unsigned int query_flags)
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
{
zfs_sb_t *zsb = ITOZSB(dentry->d_inode);
int error;

ZFS_ENTER(zsb);

#if defined(HAVE_VFSMOUNT_SIMPLE_GETATTR) && defined(HAVE_3ARGS_IOPS_GETATTR)
error = simple_getattr(mnt, dentry, stat);
#elif defined(HAVE_PATH_SIMPLE_GETATTR) && defined(HAVE_5ARGS_IOPS_GETATTR)
error = simple_getattr(path, dentry, stat, request_mask, query_flags);
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */

stat->nlink = stat->size = 2;
stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os);
stat->atime = CURRENT_TIME;
Expand Down Expand Up @@ -509,8 +539,19 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)

/* ARGSUSED */
static int
zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
zpl_shares_getattr(
#if defined(HAVE_3ARGS_IOPS_GETATTR)
struct vfsmount *mnt,
struct dentry *dentry,
struct kstat *stat
#elif defined(HAVE_5ARGS_IOPS_GETATTR)
struct path *path,
struct dentry *dentry,
struct kstat *stat,
uint32_t request_mask,
unsigned int query_flags
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
)
{
struct inode *ip = dentry->d_inode;
zfs_sb_t *zsb = ITOZSB(ip);
Expand All @@ -520,7 +561,12 @@ zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
ZFS_ENTER(zsb);

if (zsb->z_shares_dir == 0) {
#if defined(HAVE_VFSMOUNT_SIMPLE_GETATTR) && defined(HAVE_3ARGS_IOPS_GETATTR)
error = simple_getattr(mnt, dentry, stat);
#elif defined(HAVE_PATH_SIMPLE_GETATTR) && defined(HAVE_5ARGS_IOPS_GETATTR)
error = simple_getattr(path, dentry, stat, request_mask,
query_flags);
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
stat->nlink = stat->size = 2;
stat->atime = CURRENT_TIME;
ZFS_EXIT(zsb);
Expand Down
14 changes: 13 additions & 1 deletion module/zfs/zpl_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,19 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
}

static int
zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
zpl_getattr(
#if defined(HAVE_3ARGS_IOPS_GETATTR)
struct vfsmount *mnt,
struct dentry *dentry,
struct kstat *stat
#elif defined(HAVE_5ARGS_IOPS_GETATTR)
struct path *path,
struct dentry *dentry,
struct kstat *stat,
uint32_t request_mask,
unsigned int query_flags
#endif /* defined(HAVE_PATH_SIMPLE_GETATTR) */
)
{
int error;
fstrans_cookie_t cookie;
Expand Down

0 comments on commit d8ef1d3

Please sign in to comment.