Reduce confusion in zfs_write

Is this block when abuf != NULL ever reached? Yes, it is.

Add asserts and comments to prove that when we get here, we have a full
block write at an aligned offset extending past EOF.

Simplify by removing the check that tx_bytes == max_blksz, since we can
assert that it is always true.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11191
This commit is contained in:
Ryan Moeller 2020-11-18 18:06:59 -05:00 committed by Brian Behlendorf
parent af5626ac27
commit 783be694f1

View File

@ -431,7 +431,8 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
* XXX - should we really limit each write to z_max_blksz? * XXX - should we really limit each write to z_max_blksz?
* Perhaps we should use SPA_MAXBLOCKSIZE chunks? * Perhaps we should use SPA_MAXBLOCKSIZE chunks?
*/ */
ssize_t nbytes = MIN(n, max_blksz - P2PHASE(woff, max_blksz)); const ssize_t nbytes =
MIN(n, max_blksz - P2PHASE(woff, max_blksz));
ssize_t tx_bytes; ssize_t tx_bytes;
if (abuf == NULL) { if (abuf == NULL) {
@ -464,28 +465,33 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
} }
tx_bytes -= uio->uio_resid; tx_bytes -= uio->uio_resid;
} else { } else {
/* Implied by abuf != NULL: */
ASSERT3S(n, >=, max_blksz);
ASSERT3S(woff, >=, zp->z_size);
ASSERT0(P2PHASE(woff, max_blksz));
/* /*
* Is this block ever reached? * We can simplify nbytes to MIN(n, max_blksz) since
* P2PHASE(woff, max_blksz) is 0, and knowing
* n >= max_blksz lets us simplify further:
*/ */
tx_bytes = nbytes; ASSERT3S(nbytes, ==, max_blksz);
/* /*
* If this is not a full block write, but we are * Thus, we're writing a full block at a block-aligned
* extending the file past EOF and this data starts * offset and extending the file past EOF.
* block-aligned, use assign_arcbuf(). Otherwise, *
* write via dmu_write(). * dmu_assign_arcbuf_by_dbuf() will directly assign the
* arc buffer to a dbuf.
*/ */
error = dmu_assign_arcbuf_by_dbuf(
if (tx_bytes == max_blksz) { sa_get_db(zp->z_sa_hdl), woff, abuf, tx);
error = dmu_assign_arcbuf_by_dbuf( if (error != 0) {
sa_get_db(zp->z_sa_hdl), woff, abuf, tx); dmu_return_arcbuf(abuf);
if (error != 0) { dmu_tx_commit(tx);
dmu_return_arcbuf(abuf); break;
dmu_tx_commit(tx);
break;
}
} }
ASSERT(tx_bytes <= uio->uio_resid); ASSERT3S(nbytes, <=, uio->uio_resid);
uioskip(uio, tx_bytes); uioskip(uio, nbytes);
tx_bytes = nbytes;
} }
if (tx_bytes && zn_has_cached_data(zp) && if (tx_bytes && zn_has_cached_data(zp) &&
!(ioflag & O_DIRECT)) { !(ioflag & O_DIRECT)) {