Linux 4.11 compat: iops.getattr and friends
In torvalds/linux@a528d35, there are changes to the getattr family of functions, struct kstat, and the interface of inode_operations .getattr. The inode_operations .getattr and simple_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 has not specified 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. Currently both fields are ignored. It is possible that getattr-related functions within zfs could be optimized based on the request_mask. 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 */ Fields attribute and btime are cleared; the result_mask reflects this. These appear to be optional based on simple_getattr() and vfs_getattr() within the kernel, which take the same approach. Reviewed-by: Chunwei Chen <david.chen@osnexus.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Olaf Faaland <faaland1@llnl.gov> Closes #5875
This commit is contained in:
parent
626ba3142b
commit
b4c181dc76
|
@ -0,0 +1,67 @@
|
|||
dnl #
|
||||
dnl # Linux 4.11 API
|
||||
dnl # See torvalds/linux@a528d35
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
|
||||
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
int test_getattr(
|
||||
const struct path *p, 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_PATH_IOPS_GETATTR, 1,
|
||||
[iops->getattr() takes a path])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
|
||||
dnl #
|
||||
dnl # Linux 3.9 - 4.10 API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
|
||||
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
||||
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_VFSMOUNT_IOPS_GETATTR, 1,
|
||||
[iops->getattr() takes a vfsmount])
|
||||
],[
|
||||
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_PATH_KERNEL_IOPS_GETATTR
|
||||
ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR
|
||||
])
|
|
@ -58,6 +58,7 @@ 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_GET_ACL_HANDLE_CACHE
|
||||
ZFS_AC_KERNEL_SHOW_OPTIONS
|
||||
ZFS_AC_KERNEL_FILE_INODE
|
||||
|
|
|
@ -368,4 +368,47 @@ setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.11 API change
|
||||
* These macros are defined by kernel 4.11. We define them so that the same
|
||||
* code builds under kernels < 4.11 and >= 4.11. The macros are set to 0 so
|
||||
* that it will create obvious failures if they are accidentally used when built
|
||||
* against a kernel >= 4.11.
|
||||
*/
|
||||
|
||||
#ifndef STATX_BASIC_STATS
|
||||
#define STATX_BASIC_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef AT_STATX_SYNC_AS_STAT
|
||||
#define AT_STATX_SYNC_AS_STAT 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.11 API change
|
||||
* 4.11 takes struct path *, < 4.11 takes vfsmount *
|
||||
*/
|
||||
|
||||
#ifdef HAVE_VFSMOUNT_IOPS_GETATTR
|
||||
#define ZPL_GETATTR_WRAPPER(func) \
|
||||
static int \
|
||||
func(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) \
|
||||
{ \
|
||||
struct path path = { .mnt = mnt, .dentry = dentry }; \
|
||||
return func##_impl(&path, stat, STATX_BASIC_STATS, \
|
||||
AT_STATX_SYNC_AS_STAT); \
|
||||
}
|
||||
#elif defined(HAVE_PATH_IOPS_GETATTR)
|
||||
#define ZPL_GETATTR_WRAPPER(func) \
|
||||
static int \
|
||||
func(const struct path *path, struct kstat *stat, u32 request_mask, \
|
||||
unsigned int query_flags) \
|
||||
{ \
|
||||
return (func##_impl(path, stat, request_mask, query_flags)); \
|
||||
}
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ZFS_VFS_H */
|
||||
|
|
|
@ -100,16 +100,15 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zpl_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
struct kstat *stat)
|
||||
zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = simple_getattr(mnt, dentry, stat);
|
||||
generic_fillattr(path->dentry->d_inode, stat);
|
||||
stat->atime = CURRENT_TIME;
|
||||
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
ZPL_GETATTR_WRAPPER(zpl_root_getattr);
|
||||
|
||||
static struct dentry *
|
||||
#ifdef HAVE_LOOKUP_NAMEIDATA
|
||||
|
@ -375,21 +374,21 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, zpl_umode_t mode)
|
|||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zpl_snapdir_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
struct kstat *stat)
|
||||
zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{
|
||||
zfs_sb_t *zsb = ITOZSB(dentry->d_inode);
|
||||
int error;
|
||||
zfs_sb_t *zsb = ITOZSB(path->dentry->d_inode);
|
||||
|
||||
ZFS_ENTER(zsb);
|
||||
error = simple_getattr(mnt, dentry, stat);
|
||||
generic_fillattr(path->dentry->d_inode, stat);
|
||||
stat->nlink = stat->size = 2;
|
||||
stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os);
|
||||
stat->atime = CURRENT_TIME;
|
||||
ZFS_EXIT(zsb);
|
||||
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
|
||||
|
||||
/*
|
||||
* The '.zfs/snapshot' directory file operations. These mainly control
|
||||
|
@ -509,10 +508,10 @@ 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_impl(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{
|
||||
struct inode *ip = dentry->d_inode;
|
||||
struct inode *ip = path->dentry->d_inode;
|
||||
zfs_sb_t *zsb = ITOZSB(ip);
|
||||
znode_t *dzp;
|
||||
int error;
|
||||
|
@ -520,11 +519,11 @@ zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|||
ZFS_ENTER(zsb);
|
||||
|
||||
if (zsb->z_shares_dir == 0) {
|
||||
error = simple_getattr(mnt, dentry, stat);
|
||||
generic_fillattr(path->dentry->d_inode, stat);
|
||||
stat->nlink = stat->size = 2;
|
||||
stat->atime = CURRENT_TIME;
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
|
||||
|
@ -538,6 +537,7 @@ zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|||
|
||||
return (error);
|
||||
}
|
||||
ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
|
||||
|
||||
/*
|
||||
* The '.zfs/shares' directory file operations.
|
||||
|
|
|
@ -302,18 +302,25 @@ zpl_rmdir(struct inode * dir, struct dentry *dentry)
|
|||
}
|
||||
|
||||
static int
|
||||
zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||
zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
||||
unsigned int query_flags)
|
||||
{
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_getattr_fast(dentry->d_inode, stat);
|
||||
|
||||
/*
|
||||
* XXX request_mask and query_flags currently ignored.
|
||||
*/
|
||||
|
||||
error = -zfs_getattr_fast(path->dentry->d_inode, stat);
|
||||
spl_fstrans_unmark(cookie);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
return (error);
|
||||
}
|
||||
ZPL_GETATTR_WRAPPER(zpl_getattr);
|
||||
|
||||
static int
|
||||
zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||
|
|
Loading…
Reference in New Issue