summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-07-29 16:31:33 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-07-29 16:35:54 +0300
commiteaf06eae1c948859b3f5e2d81bee515747644572 (patch)
treeb75b4ad76f054987402f035fa62aceab05aa11ce
parentd3ffd42ac2dae174b8872485c486f09c856720e2 (diff)
downloadgdbm-eaf06eae1c948859b3f5e2d81bee515747644572.tar.gz
Improve _gdbm_snapshot
* src/gdbmsync.c (_gdbm_snapshot): Before returning, chmod previous snapshot write-only. Change proposed by Terence Kelly on July 23, 2021.
-rw-r--r--src/gdbmsync.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/gdbmsync.c b/src/gdbmsync.c
index f8562e7..533f8de 100644
--- a/src/gdbmsync.c
+++ b/src/gdbmsync.c
@@ -77,6 +77,7 @@ int
_gdbm_snapshot (GDBM_FILE dbf)
{
int s; /* snapshot file descriptor */
+ int oldsnap; /* previous snapshot file descriptor */
if (dbf->snapfd[0] < 0)
/* crash consistency hasn't been requested on this database */
@@ -93,7 +94,8 @@ _gdbm_snapshot (GDBM_FILE dbf)
s = dbf->snapfd[dbf->eo];
dbf->eo = !dbf->eo;
-
+ oldsnap = dbf->snapfd[dbf->eo];
+
/* says "DON'T recover from this snapshot, writing in progress " */
if (fchmod (s, S_IWUSR))
{
@@ -141,6 +143,26 @@ _gdbm_snapshot (GDBM_FILE dbf)
GDBM_SET_ERRNO (dbf, GDBM_FILE_SYNC_ERROR, FALSE);
return -1;
}
+
+ /*
+ * Mark the previous snapshot file write-only, indicating thereby
+ * that it contains obsolete data. The point of this additional
+ * operation is to reduce the time window during which a crash would
+ * leave two readable snapshot files.
+ */
+ if (fchmod (oldsnap, S_IWUSR))
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_ERR_FILE_MODE, FALSE);
+ return -1;
+ }
+
+ /* commit permission bits */
+ if (fsync (oldsnap))
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_SYNC_ERROR, FALSE);
+ return -1;
+ }
+
return 0;
}