[Libguestfs] [nbdkit PATCH] file: Add trim support
Richard W.M. Jones
rjones at redhat.com
Wed Jan 31 16:23:44 UTC 2018
On Tue, Jan 30, 2018 at 08:14:05PM -0600, Eric Blake wrote:
> We already have support in the file driver for punching holes
> during .zero with the may_trim flag (via FALLOC_FL_PUNCH_HOLE),
> so we should use the same mechanism to support .trim. Note that
> the NBD spec says that trim is advisory (we can return success
> even if we did nothing); but at the same time, it's nicer to
> avoid advertising the feature if we know for sure we can't do
> it, so we also need .can_trim. Note that there's still an
> element of runtime behavior, as FALLOC_FL_PUNCH_HOLE doesn't
> work on all filesystems; there we fall back on the NBD
> protocol allowing us to be advisory for all but a handful of
> errno values that we can directly report back over NBD.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
>
> I couldn't test --filter=log results on trim commands without
> at least one plugin that supports trim ;)
>
> plugins/file/file.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 44 insertions(+), 3 deletions(-)
>
> diff --git a/plugins/file/file.c b/plugins/file/file.c
> index 1fe4191..081848b 100644
> --- a/plugins/file/file.c
> +++ b/plugins/file/file.c
> @@ -1,5 +1,5 @@
> /* nbdkit
> - * Copyright (C) 2013 Red Hat Inc.
> + * Copyright (C) 2013-2018 Red Hat Inc.
> * All rights reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> @@ -175,6 +175,18 @@ file_get_size (void *handle)
> return statbuf.st_size;
> }
>
> +static int
> +file_can_trim (void *handle)
> +{
> + /* Trim is advisory, but we prefer to advertise it only when we can
> + * actually (attempt to) punch holes. */
> +#ifdef FALLOC_FL_PUNCH_HOLE
> + return 1;
> +#else
> + return 0;
> +#endif
> +}
> +
> /* Read data from the file. */
> static int
> file_pread (void *handle, void *buf, uint32_t count, uint64_t offset)
> @@ -219,7 +231,7 @@ file_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset)
> return 0;
> }
>
> -/* Write data to the file. */
> +/* Write zeroes to the file. */
> static int
> file_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
> {
> @@ -268,6 +280,33 @@ file_flush (void *handle)
> return 0;
> }
>
> +/* Punch a hole in the file. */
> +static int
> +file_trim (void *handle, uint32_t count, uint64_t offset)
> +{
> + int r = -1;
> +#ifdef FALLOC_FL_PUNCH_HOLE
> + struct handle *h = handle;
> +
> + /* Trim is advisory; we don't care if it fails for anything other
> + * than EIO or EPERM. */
> + r = fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> + offset, count);
> + if (r < 0) {
> + if (errno != EPERM && errno != EIO) {
> + nbdkit_debug ("ignoring failed fallocate during trim: %m");
> + r = 0;
> + }
> + else
> + nbdkit_error ("fallocate: %m");
> + }
> +#else
> + /* Based on .can_trim, this should not be reached. */
> + errno = EOPNOTSUPP;
> +#endif
> + return r;
> +}
> +
> static struct nbdkit_plugin plugin = {
> .name = "file",
> .longname = "nbdkit file plugin",
> @@ -279,10 +318,12 @@ static struct nbdkit_plugin plugin = {
> .open = file_open,
> .close = file_close,
> .get_size = file_get_size,
> + .can_trim = file_can_trim,
> .pread = file_pread,
> .pwrite = file_pwrite,
> - .zero = file_zero,
> .flush = file_flush,
> + .trim = file_trim,
> + .zero = file_zero,
> .errno_is_preserved = 1,
> };
ACK
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
More information about the Libguestfs
mailing list