Blame SOURCES/0006-copy-Store-the-preferred-block-size-in-the-operation.patch

5893ea
From 8dce43a3ea7a529bc37cbe5607a8d52186cc8169 Mon Sep 17 00:00:00 2001
5893ea
From: "Richard W.M. Jones" <rjones@redhat.com>
5893ea
Date: Tue, 28 Jun 2022 18:27:58 +0100
5893ea
Subject: [PATCH] copy: Store the preferred block size in the operations struct
5893ea
5893ea
This will be used in a subsequent commit.  At the moment the preferred
5893ea
block size for all sources / destinations is simply calculated and
5893ea
stored.
5893ea
5893ea
(cherry picked from commit e6c42f8b2d447bbcc659d6dd33be67335834b2e5)
5893ea
---
5893ea
 copy/file-ops.c |  4 +++-
5893ea
 copy/main.c     | 29 +++++++++++++++++++++++------
5893ea
 copy/nbd-ops.c  | 10 ++++++++++
5893ea
 copy/nbdcopy.h  |  4 +++-
5893ea
 copy/null-ops.c |  1 +
5893ea
 copy/pipe-ops.c |  1 +
5893ea
 6 files changed, 41 insertions(+), 8 deletions(-)
5893ea
5893ea
diff --git a/copy/file-ops.c b/copy/file-ops.c
5893ea
index ab37875..34f08e5 100644
5893ea
--- a/copy/file-ops.c
5893ea
+++ b/copy/file-ops.c
5893ea
@@ -241,13 +241,15 @@ seek_hole_supported (int fd)
5893ea
 
5893ea
 struct rw *
5893ea
 file_create (const char *name, int fd,
5893ea
-             off_t st_size, bool is_block, direction d)
5893ea
+             off_t st_size, uint64_t preferred,
5893ea
+             bool is_block, direction d)
5893ea
 {
5893ea
   struct rw_file *rwf = calloc (1, sizeof *rwf);
5893ea
   if (rwf == NULL) { perror ("calloc"); exit (EXIT_FAILURE); }
5893ea
 
5893ea
   rwf->rw.ops = &file_ops;
5893ea
   rwf->rw.name = name;
5893ea
+  rwf->rw.preferred = preferred;
5893ea
   rwf->fd = fd;
5893ea
   rwf->is_block = is_block;
5893ea
 
5893ea
diff --git a/copy/main.c b/copy/main.c
5893ea
index cc379e9..19ec384 100644
5893ea
--- a/copy/main.c
5893ea
+++ b/copy/main.c
5893ea
@@ -512,10 +512,26 @@ open_local (const char *filename, direction d)
5893ea
     fprintf (stderr, "%s: %s: %m\n", prog, filename);
5893ea
     exit (EXIT_FAILURE);
5893ea
   }
5893ea
-  if (S_ISBLK (stat.st_mode) || S_ISREG (stat.st_mode))
5893ea
-    return file_create (filename, fd, stat.st_size, S_ISBLK (stat.st_mode), d);
5893ea
-  else {
5893ea
-    /* Probably stdin/stdout, a pipe or a socket. */
5893ea
+  if (S_ISREG (stat.st_mode))   /* Regular file. */
5893ea
+    return file_create (filename, fd,
5893ea
+                        stat.st_size, (uint64_t) stat.st_blksize, false, d);
5893ea
+  else if (S_ISBLK (stat.st_mode)) { /* Block device. */
5893ea
+    unsigned int blkioopt;
5893ea
+
5893ea
+#ifdef BLKIOOPT
5893ea
+    if (ioctl (fd, BLKIOOPT, &blkioopt) == -1) {
5893ea
+      fprintf (stderr, "warning: cannot get optimal I/O size: %s: %m",
5893ea
+               filename);
5893ea
+      blkioopt = 4096;
5893ea
+    }
5893ea
+#else
5893ea
+    blkioopt = 4096;
5893ea
+#endif
5893ea
+
5893ea
+    return file_create (filename, fd,
5893ea
+                        stat.st_size, (uint64_t) blkioopt, true, d);
5893ea
+  }
5893ea
+  else {              /* Probably stdin/stdout, a pipe or a socket. */
5893ea
     synchronous = true;        /* Force synchronous mode for pipes. */
5893ea
     return pipe_create (filename, fd);
5893ea
   }
5893ea
@@ -528,8 +544,9 @@ print_rw (struct rw *rw, const char *prefix, FILE *fp)
5893ea
   char buf[HUMAN_SIZE_LONGEST];
5893ea
 
5893ea
   fprintf (fp, "%s: %s \"%s\"\n", prefix, rw->ops->ops_name, rw->name);
5893ea
-  fprintf (fp, "%s: size=%" PRIi64 " (%s)\n",
5893ea
-           prefix, rw->size, human_size (buf, rw->size, NULL));
5893ea
+  fprintf (fp, "%s: size=%" PRIi64 " (%s), preferred block size=%" PRIu64 "\n",
5893ea
+           prefix, rw->size, human_size (buf, rw->size, NULL),
5893ea
+           rw->preferred);
5893ea
 }
5893ea
 
5893ea
 /* Default implementation of rw->ops->get_extents for backends which
5893ea
diff --git a/copy/nbd-ops.c b/copy/nbd-ops.c
5893ea
index 3bc26ba..0988634 100644
5893ea
--- a/copy/nbd-ops.c
5893ea
+++ b/copy/nbd-ops.c
5893ea
@@ -112,12 +112,22 @@ open_one_nbd_handle (struct rw_nbd *rwn)
5893ea
    * the same way.
5893ea
    */
5893ea
   if (rwn->handles.len == 0) {
5893ea
+    int64_t block_size;
5893ea
+
5893ea
     rwn->can_zero = nbd_can_zero (nbd) > 0;
5893ea
+
5893ea
     rwn->rw.size = nbd_get_size (nbd);
5893ea
     if (rwn->rw.size == -1) {
5893ea
       fprintf (stderr, "%s: %s: %s\n", prog, rwn->rw.name, nbd_get_error ());
5893ea
       exit (EXIT_FAILURE);
5893ea
     }
5893ea
+
5893ea
+    block_size = nbd_get_block_size (nbd, LIBNBD_SIZE_PREFERRED);
5893ea
+    if (block_size == -1) {
5893ea
+      fprintf (stderr, "%s: %s: %s\n", prog, rwn->rw.name, nbd_get_error ());
5893ea
+      exit (EXIT_FAILURE);
5893ea
+    }
5893ea
+    rwn->rw.preferred = block_size == 0 ? 4096 : block_size;
5893ea
   }
5893ea
 
5893ea
   if (handles_append (&rwn->handles, nbd) == -1) {
5893ea
diff --git a/copy/nbdcopy.h b/copy/nbdcopy.h
5893ea
index 19797df..9438cce 100644
5893ea
--- a/copy/nbdcopy.h
5893ea
+++ b/copy/nbdcopy.h
5893ea
@@ -43,6 +43,7 @@ struct rw {
5893ea
   struct rw_ops *ops;           /* Operations. */
5893ea
   const char *name;             /* Printable name, for error messages etc. */
5893ea
   int64_t size;                 /* May be -1 for streams. */
5893ea
+  uint64_t preferred;           /* Preferred block size. */
5893ea
   /* Followed by private data for the particular subtype. */
5893ea
 };
5893ea
 
5893ea
@@ -53,7 +54,8 @@ typedef enum { READING, WRITING } direction;
5893ea
 
5893ea
 /* Create subtypes. */
5893ea
 extern struct rw *file_create (const char *name, int fd,
5893ea
-                               off_t st_size, bool is_block, direction d);
5893ea
+                               off_t st_size, uint64_t preferred,
5893ea
+                               bool is_block, direction d);
5893ea
 extern struct rw *nbd_rw_create_uri (const char *name,
5893ea
                                      const char *uri, direction d);
5893ea
 extern struct rw *nbd_rw_create_subprocess (const char **argv, size_t argc,
5893ea
diff --git a/copy/null-ops.c b/copy/null-ops.c
5893ea
index 1218a62..99cc9a7 100644
5893ea
--- a/copy/null-ops.c
5893ea
+++ b/copy/null-ops.c
5893ea
@@ -45,6 +45,7 @@ null_create (const char *name)
5893ea
   rw->rw.ops = &null_ops;
5893ea
   rw->rw.name = name;
5893ea
   rw->rw.size = INT64_MAX;
5893ea
+  rw->rw.preferred = 4096;
5893ea
   return &rw->rw;
5893ea
 }
5893ea
 
5893ea
diff --git a/copy/pipe-ops.c b/copy/pipe-ops.c
5893ea
index 3c8b6c2..3815f82 100644
5893ea
--- a/copy/pipe-ops.c
5893ea
+++ b/copy/pipe-ops.c
5893ea
@@ -43,6 +43,7 @@ pipe_create (const char *name, int fd)
5893ea
   rwp->rw.ops = &pipe_ops;
5893ea
   rwp->rw.name = name;
5893ea
   rwp->rw.size = -1;
5893ea
+  rwp->rw.preferred = 4096;
5893ea
   rwp->fd = fd;
5893ea
   return &rwp->rw;
5893ea
 }
5893ea
-- 
5893ea
2.31.1
5893ea