Skip to content

Commit 1655ce5

Browse files
ryaotonyhutter
authored andcommitted
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 <[email protected]> Reviewed-by: Allan Jude <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Signed-off-by: Richard Yao <[email protected]> Closes openzfs#8507
1 parent 5de6e4e commit 1655ce5

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

include/os/linux/zfs/sys/zfs_znode_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@
3636
#include <sys/list.h>
3737
#include <sys/dmu.h>
3838
#include <sys/sa.h>
39+
#include <sys/time.h>
3940
#include <sys/zfs_vfsops.h>
4041
#include <sys/rrwlock.h>
4142
#include <sys/zfs_sa.h>
4243
#include <sys/zfs_stat.h>
4344
#include <sys/zfs_rlock.h>
4445

45-
4646
#ifdef __cplusplus
4747
extern "C" {
4848
#endif
4949

5050
#define ZNODE_OS_FIELDS \
51+
inode_timespec_t z_btime; /* creation/birth time (cached) */ \
5152
struct inode z_inode;
5253

53-
5454
/*
5555
* Convert between znode pointers and inode pointers
5656
*/

module/os/linux/zfs/zfs_znode.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
525525
uint64_t tmp_gen;
526526
uint64_t links;
527527
uint64_t z_uid, z_gid;
528-
uint64_t atime[2], mtime[2], ctime[2];
528+
uint64_t atime[2], mtime[2], ctime[2], btime[2];
529529
uint64_t projid = ZFS_DEFAULT_PROJID;
530-
sa_bulk_attr_t bulk[11];
530+
sa_bulk_attr_t bulk[12];
531531
int count = 0;
532532

533533
ASSERT(zfsvfs != NULL);
@@ -569,6 +569,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
569569
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, &atime, 16);
570570
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16);
571571
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16);
572+
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &btime, 16);
572573

573574
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || tmp_gen == 0 ||
574575
(dmu_objset_projectquota_enabled(zfsvfs->z_os) &&
@@ -596,6 +597,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
596597
ZFS_TIME_DECODE(&ip->i_atime, atime);
597598
ZFS_TIME_DECODE(&ip->i_mtime, mtime);
598599
ZFS_TIME_DECODE(&ip->i_ctime, ctime);
600+
ZFS_TIME_DECODE(&zp->z_btime, btime);
599601

600602
ip->i_ino = zp->z_id;
601603
zfs_znode_update_vfs(zp);
@@ -1169,12 +1171,12 @@ zfs_rezget(znode_t *zp)
11691171
uint64_t obj_num = zp->z_id;
11701172
uint64_t mode;
11711173
uint64_t links;
1172-
sa_bulk_attr_t bulk[10];
1174+
sa_bulk_attr_t bulk[11];
11731175
int err;
11741176
int count = 0;
11751177
uint64_t gen;
11761178
uint64_t z_uid, z_gid;
1177-
uint64_t atime[2], mtime[2], ctime[2];
1179+
uint64_t atime[2], mtime[2], ctime[2], btime[2];
11781180
uint64_t projid = ZFS_DEFAULT_PROJID;
11791181
znode_hold_t *zh;
11801182

@@ -1244,6 +1246,7 @@ zfs_rezget(znode_t *zp)
12441246
&mtime, 16);
12451247
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
12461248
&ctime, 16);
1249+
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &btime, 16);
12471250

12481251
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) {
12491252
zfs_znode_dmu_fini(zp);
@@ -1269,6 +1272,7 @@ zfs_rezget(znode_t *zp)
12691272
ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime);
12701273
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
12711274
ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime);
1275+
ZFS_TIME_DECODE(&zp->z_btime, btime);
12721276

12731277
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
12741278
zfs_znode_dmu_fini(zp);

module/os/linux/zfs/zpl_inode.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,18 +378,46 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
378378
{
379379
int error;
380380
fstrans_cookie_t cookie;
381+
struct inode *ip = path->dentry->d_inode;
382+
znode_t *zp __maybe_unused = ITOZ(ip);
381383

382384
cookie = spl_fstrans_mark();
383385

384386
/*
385-
* XXX request_mask and query_flags currently ignored.
387+
* XXX query_flags currently ignored.
386388
*/
387389

388390
#ifdef HAVE_USERNS_IOPS_GETATTR
389-
error = -zfs_getattr_fast(user_ns, path->dentry->d_inode, stat);
391+
error = -zfs_getattr_fast(user_ns, ip, stat);
390392
#else
391-
error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
393+
error = -zfs_getattr_fast(kcred->user_ns, ip, stat);
392394
#endif
395+
396+
#ifdef STATX_BTIME
397+
if (request_mask & STATX_BTIME) {
398+
stat->btime = zp->z_btime;
399+
stat->result_mask |= STATX_BTIME;
400+
}
401+
#endif
402+
403+
#ifdef STATX_ATTR_IMMUTABLE
404+
if (zp->z_pflags & ZFS_IMMUTABLE)
405+
stat->attributes |= STATX_ATTR_IMMUTABLE;
406+
stat->attributes_mask |= STATX_ATTR_IMMUTABLE;
407+
#endif
408+
409+
#ifdef STATX_ATTR_APPEND
410+
if (zp->z_pflags & ZFS_APPENDONLY)
411+
stat->attributes |= STATX_ATTR_APPEND;
412+
stat->attributes_mask |= STATX_ATTR_APPEND;
413+
#endif
414+
415+
#ifdef STATX_ATTR_NODUMP
416+
if (zp->z_pflags & ZFS_NODUMP)
417+
stat->attributes |= STATX_ATTR_NODUMP;
418+
stat->attributes_mask |= STATX_ATTR_NODUMP;
419+
#endif
420+
393421
spl_fstrans_unmark(cookie);
394422
ASSERT3S(error, <=, 0);
395423

0 commit comments

Comments
 (0)