Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jun 2019 20:18:57 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r348700 - projects/fuse2/sys/fs/fuse
Message-ID:  <201906052018.x55KIvm3040384@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Wed Jun  5 20:18:56 2019
New Revision: 348700
URL: https://svnweb.freebsd.org/changeset/base/348700

Log:
  fusefs: simplify fuse_write_biobackend.  No functional change.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_io.c

Modified: projects/fuse2/sys/fs/fuse/fuse_io.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_io.c	Wed Jun  5 20:18:08 2019	(r348699)
+++ projects/fuse2/sys/fs/fuse/fuse_io.c	Wed Jun  5 20:18:56 2019	(r348700)
@@ -594,6 +594,8 @@ fuse_write_biobackend(struct vnode *vp, struct uio *ui
          * no point optimizing for something that really won't ever happen.
          */
 	do {
+		bool direct_append, extending;
+
 		if (fuse_isdeadfs(vp)) {
 			err = ENXIO;
 			break;
@@ -603,68 +605,54 @@ fuse_write_biobackend(struct vnode *vp, struct uio *ui
 		n = MIN((unsigned)(biosize - on), uio->uio_resid);
 
 again:
-		/*
-	         * Handle direct append and file extension cases, calculate
-	         * unaligned buffer size.
-	         */
-		if (uio->uio_offset == filesize && n) {
-			/*
-	                 * Get the buffer (in its pre-append state to maintain
-	                 * B_CACHE if it was previously set).  Resize the
-	                 * nfsnode after we have locked the buffer to prevent
-	                 * readers from reading garbage.
-	                 */
-			bcount = on;
-			SDT_PROBE6(fusefs, , io, write_biobackend_start,
-				lbn, on, n, uio, bcount, true);
-			bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
-
+		/* Get or create a buffer for the write */
+		direct_append = uio->uio_offset == filesize && n;
+		if ((off_t)lbn * biosize + on + n < filesize) {
+			extending = false;
+			if ((off_t)(lbn + 1) * biosize < filesize) {
+				/* Not the file's last block */
+				bcount = biosize;
+			} else {
+				/* The file's last block */
+				bcount = filesize - (off_t)lbn *biosize;
+			}
+		} else {
+			extending = true;
+			bcount = on + n;
+		}
+		if (direct_append) {
+			/* 
+			 * Take care to preserve the buffer's B_CACHE state so
+			 * as not to cause an unnecessary read.
+			 */
+			bp = getblk(vp, lbn, on, PCATCH, 0, 0);
 			if (bp != NULL) {
-				long save;
-
-				err = fuse_vnode_setsize(vp, cred, 
-							 uio->uio_offset + n);
-				fvdat->flag |= FN_SIZECHANGE;
-
-				if (err) {
-					brelse(bp);
-					break;
-				}
-				save = bp->b_flags & B_CACHE;
-				bcount += n;
+				uint32_t save = bp->b_flags & B_CACHE;
 				allocbuf(bp, bcount);
 				bp->b_flags |= save;
 			}
 		} else {
-			/*
-	                 * Obtain the locked cache block first, and then
-	                 * adjust the file's size as appropriate.
-	                 */
-			bcount = on + n;
-			if ((off_t)lbn * biosize + bcount < filesize) {
-				if ((off_t)(lbn + 1) * biosize < filesize)
-					bcount = biosize;
-				else
-					bcount = filesize - (off_t)lbn *biosize;
-			}
-			SDT_PROBE6(fusefs, , io, write_biobackend_start,
-				lbn, on, n, uio, bcount, false);
 			bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
-			if (bp && uio->uio_offset + n > filesize) {
-				err = fuse_vnode_setsize(vp, cred, 
-							 uio->uio_offset + n);
-				fvdat->flag |= FN_SIZECHANGE;
-				if (err) {
-					brelse(bp);
-					break;
-				} 
-			}
 		}
-
 		if (!bp) {
 			err = EINTR;
 			break;
 		}
+		if (extending) {
+			/* 
+			 * Extend file _after_ locking buffer so we won't race
+			 * with other readers
+			 */
+			err = fuse_vnode_setsize(vp, cred, uio->uio_offset + n);
+			fvdat->flag |= FN_SIZECHANGE;
+			if (err) {
+				brelse(bp);
+				break;
+			} 
+		}
+
+		SDT_PROBE6(fusefs, , io, write_biobackend_start,
+			lbn, on, n, uio, bcount, direct_append);
 		/*
 	         * Issue a READ if B_CACHE is not set.  In special-append
 	         * mode, B_CACHE is based on the buffer prior to the write



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906052018.x55KIvm3040384>