On 29 May 2025, at 6:45, Benjamin Coddington wrote: > From: Anne Marie Merritt <annemarie.merritt@xxxxxxxxxxxxxxx> > > Add tracking of the create time (a.k.a. btime) along with corresponding > bitfields, request, and decode xdr routines. > > Signed-off-by: Anne Marie Merritt <annemarie.merritt@xxxxxxxxxxxxxxx> > Signed-off-by: Lance Shelton <lance.shelton@xxxxxxxxxxxxxxx> > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> > --- > fs/nfs/inode.c | 17 +++++++++++++++-- > fs/nfs/nfs4proc.c | 14 +++++++++++++- > fs/nfs/nfs4xdr.c | 24 ++++++++++++++++++++++++ > fs/nfs/nfstrace.h | 3 ++- > include/linux/nfs_fs.h | 8 ++++++++ > include/linux/nfs_xdr.h | 3 +++ > 6 files changed, 65 insertions(+), 4 deletions(-) > > diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c > index 160f3478a835..2e36188a855b 100644 > --- a/fs/nfs/inode.c > +++ b/fs/nfs/inode.c > @@ -197,6 +197,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) > if (!(flags & NFS_INO_REVAL_FORCED)) > flags &= ~(NFS_INO_INVALID_MODE | > NFS_INO_INVALID_OTHER | > + NFS_INO_INVALID_BTIME | > NFS_INO_INVALID_XATTR); > flags &= ~(NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE); > } > @@ -522,6 +523,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) > inode_set_atime(inode, 0, 0); > inode_set_mtime(inode, 0, 0); > inode_set_ctime(inode, 0, 0); > + memset(&nfsi->btime, 0, sizeof(nfsi->btime)); > inode_set_iversion_raw(inode, 0); > inode->i_size = 0; > clear_nlink(inode); > @@ -545,6 +547,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) > inode_set_ctime_to_ts(inode, fattr->ctime); > else if (fattr_supported & NFS_ATTR_FATTR_CTIME) > nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME); > + if (fattr->valid & NFS_ATTR_FATTR_BTIME) > + nfsi->btime = fattr->btime; > + else if (fattr_supported & NFS_ATTR_FATTR_BTIME) > + nfs_set_cache_invalid(inode, NFS_INO_INVALID_BTIME); > if (fattr->valid & NFS_ATTR_FATTR_CHANGE) > inode_set_iversion_raw(inode, fattr->change_attr); > else > @@ -1900,7 +1906,7 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr, > NFS_INO_INVALID_ATIME | NFS_INO_INVALID_CTIME | > NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE | > NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER | > - NFS_INO_INVALID_NLINK; > + NFS_INO_INVALID_NLINK | NFS_INO_INVALID_BTIME; > unsigned long cache_validity = NFS_I(inode)->cache_validity; > enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type; > > @@ -2261,7 +2267,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) > | NFS_INO_INVALID_BLOCKS > | NFS_INO_INVALID_NLINK > | NFS_INO_INVALID_MODE > - | NFS_INO_INVALID_OTHER; > + | NFS_INO_INVALID_OTHER > + | NFS_INO_INVALID_BTIME; > if (S_ISDIR(inode->i_mode)) > nfs_force_lookup_revalidate(inode); > attr_changed = true; > @@ -2295,6 +2302,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) > nfsi->cache_validity |= > save_cache_validity & NFS_INO_INVALID_CTIME; > > + if (fattr->valid & NFS_ATTR_FATTR_BTIME) > + nfsi->btime = fattr->btime; > + else if (fattr_supported & NFS_ATTR_FATTR_BTIME) > + nfsi->cache_validity |= > + save_cache_validity & NFS_INO_INVALID_BTIME; > + > /* Check if our cached file size is stale */ > if (fattr->valid & NFS_ATTR_FATTR_SIZE) { > new_isize = nfs_size_to_loff_t(fattr->size); > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index b1d2122bd5a7..f7fb61f805a3 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -222,6 +222,7 @@ const u32 nfs4_fattr_bitmap[3] = { > | FATTR4_WORD1_RAWDEV > | FATTR4_WORD1_SPACE_USED > | FATTR4_WORD1_TIME_ACCESS > + | FATTR4_WORD1_TIME_CREATE > | FATTR4_WORD1_TIME_METADATA > | FATTR4_WORD1_TIME_MODIFY > | FATTR4_WORD1_MOUNTED_ON_FILEID, > @@ -243,6 +244,7 @@ static const u32 nfs4_pnfs_open_bitmap[3] = { > | FATTR4_WORD1_RAWDEV > | FATTR4_WORD1_SPACE_USED > | FATTR4_WORD1_TIME_ACCESS > + | FATTR4_WORD1_TIME_CREATE > | FATTR4_WORD1_TIME_METADATA > | FATTR4_WORD1_TIME_MODIFY, > FATTR4_WORD2_MDSTHRESHOLD > @@ -323,6 +325,9 @@ static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src, > if (!(cache_validity & NFS_INO_INVALID_OTHER)) > dst[1] &= ~(FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP); > > + if (!(cache_validity & NFS_INO_INVALID_BTIME)) > + dst[1] &= ~FATTR4_WORD1_TIME_CREATE; > + > if (nfs_have_delegated_mtime(inode)) { > if (!(cache_validity & NFS_INO_INVALID_ATIME)) > dst[1] &= ~FATTR4_WORD1_TIME_ACCESS; > @@ -1307,7 +1312,8 @@ nfs4_update_changeattr_locked(struct inode *inode, > NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | > NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER | > NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK | > - NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR; > + NFS_INO_INVALID_MODE | NFS_INO_INVALID_BTIME | > + NFS_INO_INVALID_XATTR; > nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); > } > nfsi->attrtimeo_timestamp = jiffies; > @@ -4047,6 +4053,10 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > server->fattr_valid &= ~NFS_ATTR_FATTR_CTIME; > if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)) > server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME; > + if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)) > + server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME; ^^ I just noticed this duplicates the two lines right above -- not harmful, but probably needs a cleanup.. let me know if I should repost or if this can be fixed up in a maintainers tree. Ben