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..cd720bf8ba4f 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -582,6 +582,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_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, 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);