git: 87525ef94007 - main - FFS: truncate write if it would exceed the fs max file size or RLIMIT_FSIZE

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 24 Sep 2022 16:42:38 UTC
The branch main has been updated by kib:

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

commit 87525ef94007c792c6745db7938251a663ca5706
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-09-18 11:48:40 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-09-24 16:41:57 +0000

    FFS: truncate write if it would exceed the fs max file size or RLIMIT_FSIZE
    
    PR:     164793
    Reviewed by:    asomers, jah, markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D36625
---
 sys/ufs/ffs/ffs_vnops.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 833177aa4a2b..f28a6e54143d 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -839,7 +839,7 @@ ffs_write(
 	struct buf *bp;
 	ufs_lbn_t lbn;
 	off_t osize;
-	ssize_t resid;
+	ssize_t resid, r;
 	int seqcount;
 	int blkoffset, error, flags, ioflag, size, xfersize;
 
@@ -888,15 +888,17 @@ ffs_write(
 	KASSERT(uio->uio_resid >= 0, ("ffs_write: uio->uio_resid < 0"));
 	KASSERT(uio->uio_offset >= 0, ("ffs_write: uio->uio_offset < 0"));
 	fs = ITOFS(ip);
-	if ((uoff_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize)
-		return (EFBIG);
+
 	/*
 	 * Maybe this should be above the vnode op call, but so long as
 	 * file servers have no limits, I don't think it matters.
 	 */
-	error = vn_rlimit_fsize(vp, uio, uio->uio_td);
-	if (error != 0)
+	error = vn_rlimit_fsizex(vp, uio, fs->fs_maxfilesize, &r,
+	    uio->uio_td);
+	if (error != 0) {
+		vn_rlimit_fsizex_res(uio, r);
 		return (error);
+	}
 
 	resid = uio->uio_resid;
 	osize = ip->i_size;
@@ -1037,6 +1039,7 @@ ffs_write(
 		if (ffs_fsfail_cleanup(VFSTOUFS(vp->v_mount), error))
 			error = ENXIO;
 	}
+	vn_rlimit_fsizex_res(uio, r);
 	return (error);
 }