summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/nvmutil/nvmutil.c76
1 files changed, 50 insertions, 26 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index e9046dc6..35ea6757 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -355,8 +355,8 @@ static int try_err(int loop_err, int errval);
/*
* Error handling and cleanup
*/
+static int close_files(void);
static void err(int nvm_errval, const char *msg, ...);
-static void close_files(void);
static const char *getnvmprogname(void);
static void usage(int usage_exit);
@@ -705,7 +705,8 @@ main(int argc, char *argv[])
err(EIO, "%s: bad write", fname);
}
- close_files();
+ if (close_files() == -1)
+ err(EIO, "%s: close", fname);
return EXIT_SUCCESS;
}
@@ -1568,6 +1569,8 @@ check_written_part(size_t p)
mem_offset = gbe_mem_offset(p, "pwrite");
file_offset = (off_t)gbe_file_offset(p, "pwrite");
+ memset(pad, 0xff, sizeof(pad));
+
r = rw_gbe_file_exact(gbe_fd, pad,
gbe_rw_size, file_offset, IO_PREAD);
@@ -1578,6 +1581,10 @@ check_written_part(size_t p)
else if (memcmp(mem_offset, pad, gbe_rw_size) != 0)
rw_check_bad_part[p] = io_err_gbe = 1;
+ if (rw_check_err_read[p] ||
+ rw_check_partial_read[p])
+ return;
+
/*
* We only load one part on-file, into memory but
* always at offset zero, for post-write checks.
@@ -1614,10 +1621,15 @@ report_io_err_rw(void)
"%s: pwrite: corrupt write on p%lu\n",
fname, (ulong)p);
- /*
- * so that we can re-use main checksumming features
- * correct part to read always part 0
- */
+ if (rw_check_err_read[p] ||
+ rw_check_partial_read[p]) {
+ fprintf(stderr,
+ "%s: p%lu: skipped checksum verification "
+ "(because read failed)\n",
+ fname, (ulong)p);
+
+ continue;
+ }
fprintf(stderr, "%s: ", fname);
@@ -1990,17 +2002,45 @@ try_err(int loop_err, int errval)
return -1;
}
+static int
+close_files(void)
+{
+ int close_err_gbe = 0;
+ int close_err_rand = 0;
+ int saved_errno = errno;
+
+ if (gbe_fd > -1) {
+ if (close(gbe_fd) == -1)
+ close_err_gbe = errno;
+ gbe_fd = -1;
+ }
+
+ if (urandom_fd > -1) {
+ if (close(urandom_fd) == -1)
+ close_err_rand = errno;
+ urandom_fd = -1;
+ }
+
+ if (saved_errno)
+ errno = saved_errno;
+
+ if (close_err_gbe || close_err_rand)
+ return -1;
+
+ return 0;
+}
+
static void
err(int nvm_errval, const char *msg, ...)
{
va_list args;
- if (nvm_errval >= 0) {
- close_files();
- errno = nvm_errval;
- }
if (errno <= 0)
errno = ECANCELED;
+ if (!errno)
+ errno = nvm_errval;
+
+ (void)close_files();
fprintf(stderr, "%s: ", getnvmprogname());
@@ -2014,22 +2054,6 @@ err(int nvm_errval, const char *msg, ...)
exit(EXIT_FAILURE);
}
-static void
-close_files(void)
-{
- if (gbe_fd > -1) {
- if (close(gbe_fd) == -1)
- err(-1, "%s: close failed", fname);
- gbe_fd = -1;
- }
-
- if (urandom_fd > -1) {
- if (close(urandom_fd) == -1)
- err(-1, "%s: close failed", rname);
- urandom_fd = -1;
- }
-}
-
static const char *
getnvmprogname(void)
{