[Libguestfs] [PATCH] file: Normalize errno value for ENODEV

Richard W.M. Jones rjones at redhat.com
Sat Jul 28 19:14:00 UTC 2018


On Sat, Jul 28, 2018 at 02:42:56PM +0300, Nir Soffer wrote:
> Fix issues Eric found in the original patch:
> https://www.redhat.com/archives/libguestfs/2018-July/msg00072.html
> 
> - When handling ENODEV, the caller is expecting ENOTSUPP to trigger
>   fallback.
> - ENODEV should be ignored in file_trim.
> 
> Tested only on Fedora 28.
> ---
>  plugins/file/file.c | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/plugins/file/file.c b/plugins/file/file.c
> index a7c07fb..4210adb 100644
> --- a/plugins/file/file.c
> +++ b/plugins/file/file.c
> @@ -50,6 +50,21 @@
>  
>  static char *filename = NULL;
>  
> +#if defined(FALLOC_FL_PUNCH_HOLE) || defined(FALLOC_FL_ZERO_RANGE)
> +static int
> +do_fallocate(int fd, int mode, off_t offset, off_t len)
> +{
> +  int r = -1;
> +  r = fallocate (fd, mode, offset, len);
> +  /* kernel 3.10 fails with ENODEV for block device. Kernel >= 4.9 fails
> +     with EOPNOTSUPP in this case. Normlize errno to simplify callers. */
> +  if (r == -1 && errno == ENODEV) {
> +    errno = EOPNOTSUPP;
> +  }
> +  return r;
> +}
> +#endif
> +
>  static void
>  file_unload (void)
>  {
> @@ -241,9 +256,9 @@ file_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
>  
>  #ifdef FALLOC_FL_PUNCH_HOLE
>    if (may_trim) {
> -    r = fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> -		   offset, count);
> -    if (r == -1 && errno != EOPNOTSUPP && errno != ENODEV) {
> +    r = do_fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> +                      offset, count);
> +    if (r == -1 && errno != EOPNOTSUPP) {
>        nbdkit_error ("zero: %m");
>      }
>      /* PUNCH_HOLE is older; if it is not supported, it is likely that
> @@ -253,8 +268,8 @@ file_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
>  #endif
>  
>  #ifdef FALLOC_FL_ZERO_RANGE
> -  r = fallocate (h->fd, FALLOC_FL_ZERO_RANGE, offset, count);
> -  if (r == -1 && errno != EOPNOTSUPP && errno != ENODEV) {
> +  r = do_fallocate (h->fd, FALLOC_FL_ZERO_RANGE, offset, count);
> +  if (r == -1 && errno != EOPNOTSUPP) {
>      nbdkit_error ("zero: %m");
>    }
>  #else
> @@ -288,11 +303,11 @@ file_trim (void *handle, uint32_t count, uint64_t offset)
>    struct handle *h = handle;
>  
>    /* Trim is advisory; we don't care if it fails for anything other
> -   * than EIO, EPERM, or ENODEV (kernel 3.10) */
> -  r = fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> -                 offset, count);
> +   * than EIO or EPERM. */
> +  r = do_fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> +                    offset, count);
>    if (r < 0) {
> -    if (errno != EPERM && errno != EIO && errno != ENODEV) {
> +    if (errno != EPERM && errno != EIO) {
>        nbdkit_debug ("ignoring failed fallocate during trim: %m");
>        r = 0;
>      }

Seems reasonable enough to me.  Eric what do you think?

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/




More information about the Libguestfs mailing list