If the target server supports FUA, then we should pass the client flag through rather than emulating things with a less-efficient flush.
Signed-off-by: Eric Blake <[email protected]> --- plugins/nbd/nbd.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c index c9727f7..09cefe5 100644 --- a/plugins/nbd/nbd.c +++ b/plugins/nbd/nbd.c @@ -616,6 +616,14 @@ nbd_can_trim (void *handle) return h->flags & NBD_FLAG_SEND_TRIM; } +static int +nbd_can_fua (void *handle) +{ + struct handle *h = handle; + + return h->flags & NBD_FLAG_SEND_FUA; +} + /* Read data from the file. */ static int nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset) @@ -631,23 +639,26 @@ nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset) /* Write data to the file. */ static int -nbd_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset) +nbd_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, + int fua) { struct handle *h = handle; int c; /* TODO Auto-fragment this if the client has a larger max transfer limit than the server */ - c = nbd_request_full (h, 0, NBD_CMD_WRITE, offset, count, buf, NULL); + c = nbd_request_full (h, fua ? NBD_CMD_FLAG_FUA : 0, + NBD_CMD_WRITE, offset, count, buf, NULL); return c < 0 ? c : nbd_reply (h, c); } /* Write zeroes to the file. */ static int -nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim) +nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim, int fua) { struct handle *h = handle; int c; + int flags = 0; if (!(h->flags & NBD_FLAG_SEND_WRITE_ZEROES)) { /* Trigger a fall back to regular writing */ @@ -655,19 +666,22 @@ nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim) return -1; } - c = nbd_request (h, may_trim ? 0 : NBD_CMD_FLAG_NO_HOLE, - NBD_CMD_WRITE_ZEROES, offset, count); + if (!may_trim) + flags |= NBD_CMD_FLAG_NO_HOLE; + if (fua) + flags |= NBD_CMD_FLAG_FUA; + c = nbd_request (h, flags, NBD_CMD_WRITE_ZEROES, offset, count); return c < 0 ? c : nbd_reply (h, c); } /* Trim a portion of the file. */ static int -nbd_trim (void *handle, uint32_t count, uint64_t offset) +nbd_trim (void *handle, uint32_t count, uint64_t offset, int fua) { struct handle *h = handle; int c; - c = nbd_request (h, 0, NBD_CMD_TRIM, offset, count); + c = nbd_request (h, fua ? NBD_CMD_FLAG_FUA : 0, NBD_CMD_TRIM, offset, count); return c < 0 ? c : nbd_reply (h, c); } @@ -697,11 +711,12 @@ static struct nbdkit_plugin plugin = { .can_flush = nbd_can_flush, .is_rotational = nbd_is_rotational, .can_trim = nbd_can_trim, + .can_fua = nbd_can_fua, .pread = nbd_pread, - .pwrite = nbd_pwrite, - .zero = nbd_zero, + .pwrite_fua = nbd_pwrite, + .zero_fua = nbd_zero, .flush = nbd_flush, - .trim = nbd_trim, + .trim_fua = nbd_trim, .errno_is_preserved = 1, }; -- 2.14.3 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
