Blame SOURCES/0006-copy-Pass-in-dummy-variable-rather-than-errno-to-cal.patch

a81d13
From 22572f8ac13e2e8daf91d227eac2f384303fb5b4 Mon Sep 17 00:00:00 2001
a81d13
From: Eric Blake <eblake@redhat.com>
a81d13
Date: Thu, 3 Feb 2022 14:25:57 -0600
a81d13
Subject: [PATCH] copy: Pass in dummy variable rather than &errno to callback
a81d13
a81d13
In several places where asynch handlers manually call the provided
a81d13
nbd_completion_callback, the value of errno is indeterminate (for
a81d13
example, in file-ops.c:file_asynch_read(), the previous call to
a81d13
file_synch_read() already triggered exit() on error, but does not
a81d13
guarantee what is left in errno on success).  As the callback should
a81d13
be paying attention to the value of *error (to be fixed in the next
a81d13
patch), we are better off ensuring that we pass in a pointer to a
a81d13
known-zero value.  Besides, passing in &errno carries a risk that if
a81d13
the callback uses any other library function that alters errno prior
a81d13
to dereferncing *error, it will no longer see the value we passed in.
a81d13
Thus, it is easier to use a dummy variable on the stack than to mess
a81d13
around with errno and it's magic macro expansion into a thread-local
a81d13
storage location.
a81d13
a81d13
Note that several callsites then check if the callback returned -1,
a81d13
and if so assume that the callback has caused errno to now have a sane
a81d13
value to pass on to perror.  In theory, the fact that we are no longer
a81d13
passing in &errno means that if the callback assigns into *error but
a81d13
did not otherwise affect errno (a tenuous assumption, given our
a81d13
argument above that we could not even guarantee that the callback does
a81d13
not accidentally alter errno prior to reading *error), our perror call
a81d13
would no longer reflect the intended error value from the callback.
a81d13
But in practice, since the callback never actually returned -1, nor
a81d13
even assigned into *error, the call to perror is dead code; although I
a81d13
have chosen to defer that additional cleanup to the next patch.
a81d13
a81d13
Message-Id: <20220203202558.203013-5-eblake@redhat.com>
a81d13
Acked-by: Richard W.M. Jones <rjones@redhat.com>
a81d13
Acked-by: Nir Soffer <nsoffer@redhat.com>
a81d13
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
a81d13
(cherry picked from commit 794c8ce06e995ebd282e8f2b9465a06140572112)
a81d13
Conflicts:
a81d13
	copy/file-ops.c - no backport of d5f65e56 ("copy: Do not use trim
a81d13
 for zeroing"), so asynch_trim needed same treatment
a81d13
	copy/multi-thread-copying.c - context due to missing refactoring
a81d13
	copy/null-ops.c - no backport of 0b16205e "copy: Implement "null:"
a81d13
  destination."
a81d13
(cherry picked from commit 26e3dcf80815fe2db320d3046aabc2580c2f7a0d)
a81d13
---
a81d13
 copy/file-ops.c             | 22 +++++++++++++---------
a81d13
 copy/multi-thread-copying.c |  8 +++++---
a81d13
 2 files changed, 18 insertions(+), 12 deletions(-)
a81d13
a81d13
diff --git a/copy/file-ops.c b/copy/file-ops.c
a81d13
index 086348a..cc312b4 100644
a81d13
--- a/copy/file-ops.c
a81d13
+++ b/copy/file-ops.c
a81d13
@@ -1,5 +1,5 @@
a81d13
 /* NBD client library in userspace.
a81d13
- * Copyright (C) 2020 Red Hat Inc.
a81d13
+ * Copyright (C) 2020-2022 Red Hat Inc.
a81d13
  *
a81d13
  * This library is free software; you can redistribute it and/or
a81d13
  * modify it under the terms of the GNU Lesser General Public
a81d13
@@ -158,10 +158,11 @@ file_asynch_read (struct rw *rw,
a81d13
                   struct command *command,
a81d13
                   nbd_completion_callback cb)
a81d13
 {
a81d13
+  int dummy = 0;
a81d13
+
a81d13
   file_synch_read (rw, slice_ptr (command->slice),
a81d13
                    command->slice.len, command->offset);
a81d13
-  errno = 0;
a81d13
-  if (cb.callback (cb.user_data, &errno) == -1) {
a81d13
+  if (cb.callback (cb.user_data, &dummy) == -1) {
a81d13
     perror (rw->name);
a81d13
     exit (EXIT_FAILURE);
a81d13
   }
a81d13
@@ -172,10 +173,11 @@ file_asynch_write (struct rw *rw,
a81d13
                    struct command *command,
a81d13
                    nbd_completion_callback cb)
a81d13
 {
a81d13
+  int dummy = 0;
a81d13
+
a81d13
   file_synch_write (rw, slice_ptr (command->slice),
a81d13
                     command->slice.len, command->offset);
a81d13
-  errno = 0;
a81d13
-  if (cb.callback (cb.user_data, &errno) == -1) {
a81d13
+  if (cb.callback (cb.user_data, &dummy) == -1) {
a81d13
     perror (rw->name);
a81d13
     exit (EXIT_FAILURE);
a81d13
   }
a81d13
@@ -185,10 +187,11 @@ static bool
a81d13
 file_asynch_trim (struct rw *rw, struct command *command,
a81d13
                   nbd_completion_callback cb)
a81d13
 {
a81d13
+  int dummy = 0;
a81d13
+
a81d13
   if (!file_synch_trim (rw, command->offset, command->slice.len))
a81d13
     return false;
a81d13
-  errno = 0;
a81d13
-  if (cb.callback (cb.user_data, &errno) == -1) {
a81d13
+  if (cb.callback (cb.user_data, &dummy) == -1) {
a81d13
     perror (rw->name);
a81d13
     exit (EXIT_FAILURE);
a81d13
   }
a81d13
@@ -199,10 +202,11 @@ static bool
a81d13
 file_asynch_zero (struct rw *rw, struct command *command,
a81d13
                   nbd_completion_callback cb)
a81d13
 {
a81d13
+  int dummy = 0;
a81d13
+
a81d13
   if (!file_synch_zero (rw, command->offset, command->slice.len))
a81d13
     return false;
a81d13
-  errno = 0;
a81d13
-  if (cb.callback (cb.user_data, &errno) == -1) {
a81d13
+  if (cb.callback (cb.user_data, &dummy) == -1) {
a81d13
     perror (rw->name);
a81d13
     exit (EXIT_FAILURE);
a81d13
   }
a81d13
diff --git a/copy/multi-thread-copying.c b/copy/multi-thread-copying.c
a81d13
index a7aaa7d..2593ff7 100644
a81d13
--- a/copy/multi-thread-copying.c
a81d13
+++ b/copy/multi-thread-copying.c
a81d13
@@ -1,5 +1,5 @@
a81d13
 /* NBD client library in userspace.
a81d13
- * Copyright (C) 2020 Red Hat Inc.
a81d13
+ * Copyright (C) 2020-2022 Red Hat Inc.
a81d13
  *
a81d13
  * This library is free software; you can redistribute it and/or
a81d13
  * modify it under the terms of the GNU Lesser General Public
a81d13
@@ -391,6 +391,7 @@ finished_read (void *vp, int *error)
a81d13
     bool last_is_hole = false;
a81d13
     uint64_t i;
a81d13
     struct command *newcommand;
a81d13
+    int dummy = 0;
a81d13
 
a81d13
     /* Iterate over whole blocks in the command, starting on a block
a81d13
      * boundary.
a81d13
@@ -473,7 +474,7 @@ finished_read (void *vp, int *error)
a81d13
     /* Free the original command since it has been split into
a81d13
      * subcommands and the original is no longer needed.
a81d13
      */
a81d13
-    free_command (command, &errno);
a81d13
+    free_command (command, &dummy);
a81d13
   }
a81d13
 
a81d13
   return 1; /* auto-retires the command */
a81d13
@@ -498,6 +499,7 @@ static void
a81d13
 fill_dst_range_with_zeroes (struct command *command)
a81d13
 {
a81d13
   char *data;
a81d13
+  int dummy = 0;
a81d13
 
a81d13
   if (destination_is_zero)
a81d13
     goto free_and_return;
a81d13
@@ -541,7 +543,7 @@ fill_dst_range_with_zeroes (struct command *command)
a81d13
   free (data);
a81d13
 
a81d13
  free_and_return:
a81d13
-  free_command (command, &errno);
a81d13
+  free_command (command, &dummy);
a81d13
 }
a81d13
 
a81d13
 static int
a81d13
-- 
a81d13
2.31.1
a81d13