git: b4663a8d1117 - main - stat(2): add st_filerev

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 16 Jan 2025 18:54:28 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=b4663a8d111767206bb3ebcfec5b95a6b88bc720

commit b4663a8d111767206bb3ebcfec5b95a6b88bc720
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-01-13 21:14:04 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-01-16 18:54:20 +0000

    stat(2): add st_filerev
    
    Reviewed by:    asomers, markj, olce, rmacklem
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D48452
---
 sys/compat/freebsd32/freebsd32.h      | 3 ++-
 sys/compat/freebsd32/freebsd32_misc.c | 1 +
 sys/fs/tmpfs/tmpfs_vnops.c            | 1 +
 sys/kern/kern_descrip.c               | 1 +
 sys/kern/vfs_default.c                | 2 ++
 sys/kern/vfs_subr.c                   | 1 +
 sys/sys/stat.h                        | 3 ++-
 sys/sys/vnode.h                       | 1 +
 sys/ufs/ufs/ufs_vnops.c               | 2 ++
 9 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index e1bfe282c4b1..3dbf1b5a876d 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -240,7 +240,8 @@ struct stat32 {
 	uint32_t st_blksize;
 	uint32_t st_flags;
 	uint64_t st_gen;
-	uint64_t st_spare[10];
+	uint64_t st_filerev;
+	uint64_t st_spare[9];
 };
 struct freebsd11_stat32 {
 	uint32_t st_dev;
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 4cd706e16155..e5b2b0feeafd 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2251,6 +2251,7 @@ copy_stat(struct stat *in, struct stat32 *out)
 	CP(*in, *out, st_blksize);
 	CP(*in, *out, st_flags);
 	CP(*in, *out, st_gen);
+	CP(*in, *out, st_filerev);
 	TS_CP(*in, *out, st_birthtim);
 	out->st_padding0 = 0;
 	out->st_padding1 = 0;
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 83e43ec7ba13..c99d0732be50 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -476,6 +476,7 @@ tmpfs_stat(struct vop_stat_args *v)
 	sb->st_blksize = PAGE_SIZE;
 	sb->st_flags = node->tn_flags;
 	sb->st_gen = node->tn_gen;
+	sb->st_filerev = 0;
 	if (vp->v_type == VREG) {
 #ifdef __ILP32__
 		vm_object_t obj = node->tn_reg.tn_aobj;
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 10e0b4b142f8..f87ad1f45143 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1620,6 +1620,7 @@ kern_fstat(struct thread *td, int fd, struct stat *sbp)
 
 	AUDIT_ARG_FILE(td->td_proc, fp);
 
+	sbp->st_filerev = 0;
 	error = fo_stat(fp, sbp, td->td_ucred);
 	fdrop(fp, td);
 #ifdef __STAT_TIME_T_EXT
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 4067ab4ba446..5e6516921002 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1511,6 +1511,7 @@ vop_stdstat(struct vop_stat_args *a)
 	vap->va_fsid = VNOVAL;
 	vap->va_gen = 0;
 	vap->va_rdev = NODEV;
+	vap->va_filerev = 0;
 
 	error = VOP_GETATTR(vp, vap, a->a_active_cred);
 	if (error)
@@ -1587,6 +1588,7 @@ vop_stdstat(struct vop_stat_args *a)
 	sb->st_flags = vap->va_flags;
 	sb->st_blocks = vap->va_bytes / S_BLKSIZE;
 	sb->st_gen = vap->va_gen;
+	sb->st_filerev = vap->va_filerev;
 out:
 	return (vop_stat_helper_post(a, error));
 }
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index feb808c0d4c7..ef51fdba8e7c 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1200,6 +1200,7 @@ vattr_null(struct vattr *vap)
 	vap->va_flags = VNOVAL;
 	vap->va_gen = VNOVAL;
 	vap->va_vaflags = 0;
+	vap->va_filerev = VNOVAL;
 }
 
 /*
diff --git a/sys/sys/stat.h b/sys/sys/stat.h
index dabf121f45fe..15b7ec99bdd9 100644
--- a/sys/sys/stat.h
+++ b/sys/sys/stat.h
@@ -185,7 +185,8 @@ struct stat {
 	blksize_t st_blksize;		/* optimal blocksize for I/O */
 	fflags_t  st_flags;		/* user defined flags for file */
 	__uint64_t st_gen;		/* file generation number */
-	__uint64_t st_spare[10];
+	__uint64_t st_filerev;		/* file revision, incr on changes */
+	__uint64_t st_spare[9];
 };
 
 #ifdef _KERNEL
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 42973adac287..00f8a1eabc4e 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -989,6 +989,7 @@ void	vop_rename_fail(struct vop_rename_args *ap);
 		ap->a_sb->st_padding0 = 0;					\
 		ap->a_sb->st_padding1 = 0;					\
 		bzero(_ap->a_sb->st_spare, sizeof(_ap->a_sb->st_spare));	\
+		ap->a_sb->st_filerev = 0;					\
 	}									\
 	_error;									\
 })
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 0bca40199071..9aea01e70951 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -549,6 +549,7 @@ ufs_stat(struct vop_stat_args *ap)
 		sb->st_birthtim.tv_sec = -1;
 		sb->st_birthtim.tv_nsec = 0;
 		sb->st_blocks = dbtob((uint64_t)ip->i_din1->di_blocks) / S_BLKSIZE;
+		sb->st_filerev = ip->i_din1->di_modrev;
 	} else {
 		sb->st_rdev = ip->i_din2->di_rdev;
 		sb->st_size = ip->i_din2->di_size;
@@ -559,6 +560,7 @@ ufs_stat(struct vop_stat_args *ap)
 		sb->st_birthtim.tv_sec = ip->i_din2->di_birthtime;
 		sb->st_birthtim.tv_nsec = ip->i_din2->di_birthnsec;
 		sb->st_blocks = dbtob((uint64_t)ip->i_din2->di_blocks) / S_BLKSIZE;
+		sb->st_filerev = ip->i_din2->di_modrev;
 	}
 
 	sb->st_blksize = max(PAGE_SIZE, vp->v_mount->mnt_stat.f_iosize);