From 414fc02ea294d35233c48910e7c6573f29ef8f9e Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sat, 16 Mar 2019 20:43:13 -0400 Subject: [PATCH] Linux 4.11 compat: statx support Linux 4.11 added a new statx system call that allows us to expose crtime as btime. We do this by caching crtime in the znode to match how atime, ctime and mtime are cached in the inode. statx also introduced a new way of reporting whether the immutable, append and nodump bits have been set. It adds support for reporting compression and encryption, but the semantics on other filesystems is not just to report compression/encryption, but to allow it to be turned on/off at the file level. We do not support that. We could implement semantics where we refuse to allow user modification of the bit, but we would need to do a dnode_hold() in zfs_znode_alloc() to find out encryption/compression information. That would introduce locking that will have a minor (although unmeasured) performance cost. It also would be inferior to zdb, which reports far more detailed information. We therefore omit reporting of encryption/compression through statx in favor of recommending that users interested in such information use zdb. Signed-off-by: Richard Yao Closes #8507 --- include/sys/zfs_znode.h | 1 + module/zfs/zfs_znode.c | 2 ++ module/zfs/zpl_inode.c | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 2dfcf453a531..d4008b575c81 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -216,6 +216,7 @@ typedef struct znode { boolean_t z_is_mapped; /* are we mmap'ed */ boolean_t z_is_ctldir; /* are we .zfs entry */ boolean_t z_is_stale; /* are we stale due to rollback? */ + uint64_t z_crtime[2]; /* creation/birth time (cached) */ struct inode z_inode; /* generic vfs inode */ } znode_t; diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 761fbcb33764..f92917409f7a 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -582,6 +582,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, &atime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, + &zp->z_crtime[0], 16); if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || tmp_gen == 0 || (dmu_objset_projectquota_enabled(zfsvfs->z_os) && diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 41b91cabcb96..3573ba485fd5 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -353,6 +353,27 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask, */ error = -zfs_getattr_fast(path->dentry->d_inode, stat); + +#ifdef STATX_BTIME + ZFS_TIME_DECODE(zp->z_crtime, btime); + stat->result_mask |= STATX_BTIME; +#endif + +#ifdef STATX_ATTR_IMMUTABLE + if (zfs_flags & ZFS_IMMUTABLE) + stat->attributes |= STATX_ATTR_IMMUTABLE; +#endif + +#ifdef STATX_ATTR_APPEND + if (zfs_flags & ZFS_APPENDONLY) + stat->attributes |= STATX_ATTR_APPEND; +#endif + +#ifdef STATX_ATTR_NODUMP + if (zfs_flags & ZFS_NODUMP) + stat->attributes |= STATX_ATTR_NODUMP; +#ifdef + spl_fstrans_unmark(cookie); ASSERT3S(error, <=, 0);