aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2018-03-07 16:57:32 -0600
committerEric Blake <eblake@redhat.com>2018-03-13 15:38:55 -0500
commit65529782f8fec531fd114cc0f58399e88202153c (patch)
tree09920b73b611197917f4631df20be2bf986a9af7
parent6f302e60931a1f95ea873a8bd6bd8c1edf179ec2 (diff)
nbd/server: Honor FUA request on NBD_CMD_TRIM
The NBD spec states that since trim requests can affect disk contents, then they should allow for FUA semantics just like writes for ensuring the disk has settled before returning. As bdrv_[co_]pdiscard() does not support a flags argument, we can't pass FUA down the block layer stack, and must therefore emulate it with a flush at the NBD layer. Note that in all reality, generic well-behaved clients will never send TRIM+FUA (in fact, qemu as a client never does, and we have no intention to plumb flags into bdrv_pdiscard). This is because the NBD protocol states that it is unspecified to READ a trimmed area (you might read stale data, all zeroes, or even random unrelated data) without first rewriting it, and even the experimental BLOCK_STATUS extension states that TRIM need not affect reported status. Thus, in the general case, a client cannot tell the difference between an arbitrary server that ignores TRIM, a server that had a power outage without flushing to disk, and a server that actually affected the disk before returning; so waiting for the trim actions to flush to disk makes little sense. However, for a specific client and server pair, where the client knows the server treats TRIM'd areas as guaranteed reads-zero, waiting for a flush makes sense, hence why the protocol documents that FUA is valid on trim. So, even though the NBD protocol doesn't have a way for the server to advertise what effects (if any) TRIM will actually have, and thus any client that relies on specific effects is probably in error, we can at least support a client that requests TRIM+FUA. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20180307225732.155835-1-eblake@redhat.com>
-rw-r--r--nbd/server.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/nbd/server.c b/nbd/server.c
index 83f21c5591..4776009a2d 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1638,6 +1638,9 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
case NBD_CMD_TRIM:
ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset,
request->len);
+ if (ret == 0 && request->flags & NBD_CMD_FLAG_FUA) {
+ ret = blk_co_flush(exp->blk);
+ }
return nbd_send_generic_reply(client, request->handle, ret,
"discard failed", errp);