mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
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. Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com> Reviewed-by: Allan Jude <allan@klarasystems.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Richard Yao <ryao@gentoo.org> Closes #8507
This commit is contained in:
parent
0f402668f9
commit
abbf0bd4eb
@ -36,21 +36,21 @@
|
|||||||
#include <sys/list.h>
|
#include <sys/list.h>
|
||||||
#include <sys/dmu.h>
|
#include <sys/dmu.h>
|
||||||
#include <sys/sa.h>
|
#include <sys/sa.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <sys/zfs_vfsops.h>
|
#include <sys/zfs_vfsops.h>
|
||||||
#include <sys/rrwlock.h>
|
#include <sys/rrwlock.h>
|
||||||
#include <sys/zfs_sa.h>
|
#include <sys/zfs_sa.h>
|
||||||
#include <sys/zfs_stat.h>
|
#include <sys/zfs_stat.h>
|
||||||
#include <sys/zfs_rlock.h>
|
#include <sys/zfs_rlock.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZNODE_OS_FIELDS \
|
#define ZNODE_OS_FIELDS \
|
||||||
|
inode_timespec_t z_btime; /* creation/birth time (cached) */ \
|
||||||
struct inode z_inode;
|
struct inode z_inode;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert between znode pointers and inode pointers
|
* Convert between znode pointers and inode pointers
|
||||||
*/
|
*/
|
||||||
|
@ -525,9 +525,9 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
|||||||
uint64_t tmp_gen;
|
uint64_t tmp_gen;
|
||||||
uint64_t links;
|
uint64_t links;
|
||||||
uint64_t z_uid, z_gid;
|
uint64_t z_uid, z_gid;
|
||||||
uint64_t atime[2], mtime[2], ctime[2];
|
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||||
sa_bulk_attr_t bulk[11];
|
sa_bulk_attr_t bulk[12];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
ASSERT(zfsvfs != NULL);
|
ASSERT(zfsvfs != NULL);
|
||||||
@ -569,6 +569,7 @@ 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_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_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_CTIME(zfsvfs), NULL, &ctime, 16);
|
||||||
|
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &btime, 16);
|
||||||
|
|
||||||
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || tmp_gen == 0 ||
|
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || tmp_gen == 0 ||
|
||||||
(dmu_objset_projectquota_enabled(zfsvfs->z_os) &&
|
(dmu_objset_projectquota_enabled(zfsvfs->z_os) &&
|
||||||
@ -596,6 +597,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
|||||||
ZFS_TIME_DECODE(&ip->i_atime, atime);
|
ZFS_TIME_DECODE(&ip->i_atime, atime);
|
||||||
ZFS_TIME_DECODE(&ip->i_mtime, mtime);
|
ZFS_TIME_DECODE(&ip->i_mtime, mtime);
|
||||||
ZFS_TIME_DECODE(&ip->i_ctime, ctime);
|
ZFS_TIME_DECODE(&ip->i_ctime, ctime);
|
||||||
|
ZFS_TIME_DECODE(&zp->z_btime, btime);
|
||||||
|
|
||||||
ip->i_ino = zp->z_id;
|
ip->i_ino = zp->z_id;
|
||||||
zfs_znode_update_vfs(zp);
|
zfs_znode_update_vfs(zp);
|
||||||
@ -1169,12 +1171,12 @@ zfs_rezget(znode_t *zp)
|
|||||||
uint64_t obj_num = zp->z_id;
|
uint64_t obj_num = zp->z_id;
|
||||||
uint64_t mode;
|
uint64_t mode;
|
||||||
uint64_t links;
|
uint64_t links;
|
||||||
sa_bulk_attr_t bulk[10];
|
sa_bulk_attr_t bulk[11];
|
||||||
int err;
|
int err;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
uint64_t gen;
|
uint64_t gen;
|
||||||
uint64_t z_uid, z_gid;
|
uint64_t z_uid, z_gid;
|
||||||
uint64_t atime[2], mtime[2], ctime[2];
|
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||||
znode_hold_t *zh;
|
znode_hold_t *zh;
|
||||||
|
|
||||||
@ -1244,6 +1246,7 @@ zfs_rezget(znode_t *zp)
|
|||||||
&mtime, 16);
|
&mtime, 16);
|
||||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||||
&ctime, 16);
|
&ctime, 16);
|
||||||
|
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &btime, 16);
|
||||||
|
|
||||||
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) {
|
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) {
|
||||||
zfs_znode_dmu_fini(zp);
|
zfs_znode_dmu_fini(zp);
|
||||||
@ -1269,6 +1272,7 @@ zfs_rezget(znode_t *zp)
|
|||||||
ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime);
|
ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime);
|
||||||
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
|
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
|
||||||
ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime);
|
ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime);
|
||||||
|
ZFS_TIME_DECODE(&zp->z_btime, btime);
|
||||||
|
|
||||||
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
|
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
|
||||||
zfs_znode_dmu_fini(zp);
|
zfs_znode_dmu_fini(zp);
|
||||||
|
@ -378,18 +378,46 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
fstrans_cookie_t cookie;
|
fstrans_cookie_t cookie;
|
||||||
|
struct inode *ip = path->dentry->d_inode;
|
||||||
|
znode_t *zp __maybe_unused = ITOZ(ip);
|
||||||
|
|
||||||
cookie = spl_fstrans_mark();
|
cookie = spl_fstrans_mark();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX request_mask and query_flags currently ignored.
|
* XXX query_flags currently ignored.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_USERNS_IOPS_GETATTR
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
error = -zfs_getattr_fast(user_ns, path->dentry->d_inode, stat);
|
error = -zfs_getattr_fast(user_ns, ip, stat);
|
||||||
#else
|
#else
|
||||||
error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
|
error = -zfs_getattr_fast(kcred->user_ns, ip, stat);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STATX_BTIME
|
||||||
|
if (request_mask & STATX_BTIME) {
|
||||||
|
stat->btime = zp->z_btime;
|
||||||
|
stat->result_mask |= STATX_BTIME;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STATX_ATTR_IMMUTABLE
|
||||||
|
if (zp->z_pflags & ZFS_IMMUTABLE)
|
||||||
|
stat->attributes |= STATX_ATTR_IMMUTABLE;
|
||||||
|
stat->attributes_mask |= STATX_ATTR_IMMUTABLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STATX_ATTR_APPEND
|
||||||
|
if (zp->z_pflags & ZFS_APPENDONLY)
|
||||||
|
stat->attributes |= STATX_ATTR_APPEND;
|
||||||
|
stat->attributes_mask |= STATX_ATTR_APPEND;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STATX_ATTR_NODUMP
|
||||||
|
if (zp->z_pflags & ZFS_NODUMP)
|
||||||
|
stat->attributes |= STATX_ATTR_NODUMP;
|
||||||
|
stat->attributes_mask |= STATX_ATTR_NODUMP;
|
||||||
|
#endif
|
||||||
|
|
||||||
spl_fstrans_unmark(cookie);
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user