diff options
Diffstat (limited to 'sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c')
| -rw-r--r-- | sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c index f97662d052c7..e4e15c824f4b 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c @@ -506,6 +506,32 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask, } #endif +#ifdef STATX_CHANGE_COOKIE + if (request_mask & STATX_CHANGE_COOKIE) { + /* + * knfsd uses the STATX_CHANGE_COOKIE to surface to clients + * change_info4 data, which is used to implement NFS client + * name caching (see RFC 8881 Section 10.8). This number + * should always increase with changes and should not be + * reused. We cannot simply present ctime here because + * ZFS uses a coarse timer to set them, which may cause + * clients to fail to detect changes and invalidate cache. + * + * ZFS always increments znode z_seq number, but this is + * uint_t and so we mask in ctime to upper bits. + * + * STATX_ATTR_CHANGE_MONOTONIC is advertised + * to prevent knfsd from generating the change cookie + * based on ctime. C.f. nfsd4_change_attribute in + * fs/nfsd/nfsfh.c. + */ + stat->change_cookie = + ((u64)stat->ctime.tv_sec << 32) | zp->z_seq; + stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC; + stat->result_mask |= STATX_CHANGE_COOKIE; + } +#endif + #ifdef STATX_DIOALIGN if (request_mask & STATX_DIOALIGN) { uint64_t align; |
