summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/nvmutil/nvmutil.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index 59d2facd..120586a9 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -2073,25 +2073,8 @@ real_pread_pwrite:
* if the offset changed to what
* we previously got. If it did,
* then another thread may have
- * changed it.
- *
- * This is no substitute for real
- * pread/pwrite, which would be
- * fully atomic at kernel-level
- * and do not use file offsets.
- *
- * TODO: Add a toggle to make it
- * recover instead, reset
- * to known offset, and
- * carry on operations.
- *
- * Failure is the better option
- * here, since recovery would
- * mask hidden bugs in code.
- * We cannot guarantee thread
- * safety, except in the event
- * that violations cause exit;
- * you would then debug it.
+ * changed it. Enabled if
+ * off_reset is OFF_RESET.
*/
if (off != verified) {
if (!off_reset)
@@ -2112,6 +2095,24 @@ real_pread_pwrite:
return -1;
}
+ verified = lseek_loop(fd, (off_t)0, SEEK_CUR,
+ loop_eagain, loop_eintr);
+
+ /*
+ * Verify again before I/O
+ * (even with OFF_ERR)
+ *
+ * This implements the first check
+ * even with OFF_ERR, but without
+ * the recovery. On ERR_RESET, if
+ * the check fails again, then we
+ * know something else is touching
+ * the file, so it's best that we
+ * probably leave it alone and err.
+ */
+ if (verified != off)
+ goto err_prw;
+
do {
if (rw_type == IO_PREAD)
r = read(fd, mem, nrw);