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

Nir Soffer nirsof at gmail.com
Sat Jul 28 11:42:56 UTC 2018


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;
     }
-- 
2.17.1




More information about the Libguestfs mailing list