aboutsummaryrefslogtreecommitdiff
path: root/src/gdbmsync.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-06-27 12:38:10 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-07-17 22:56:25 +0300
commita563f9c8e5269195f217e4c50694a67dd44d3e75 (patch)
tree870cc28c9d6272c2abc057baa2094641b0fef186 /src/gdbmsync.c
parent4ae4541e80a6e6b43c3b6b58fa582a382722205d (diff)
downloadgdbm-a563f9c8e5269195f217e4c50694a67dd44d3e75.tar.gz
gdbm-a563f9c8e5269195f217e4c50694a67dd44d3e75.tar.bz2
Improve fsync_to_root. Other minor fixes.
* src/gdbm.h.in (gdbm_latest_status): Rename to gdbm_latest_snapshot_status. * src/gdbmsync.c (fsync_to_root): Start synching from the snapshot itself. Take care to open it write-only. (gdbm_latest_snapshot): Reorganize to improve readability. [!GDBM_FAILURE_ATOMIC] gdbm_latest_snapshot: Fix signature.
Diffstat (limited to 'src/gdbmsync.c')
-rw-r--r--src/gdbmsync.c82
1 files changed, 44 insertions, 38 deletions
diff --git a/src/gdbmsync.c b/src/gdbmsync.c
index 266f249..80fdbf1 100644
--- a/src/gdbmsync.c
+++ b/src/gdbmsync.c
@@ -38,31 +38,34 @@
static int
fsync_to_root (const char *f)
{
+ int flags = O_WRONLY;
char path[PATH_MAX], *end;
+
if (realpath (f, path) == NULL)
return GDBM_ERR_REALPATH;
end = path + strlen(path);
while (path < end)
{
- if (end[-1] == '/')
+ int fd;
+
+ *end = 0;
+ fd = open (path, flags);
+ flags = O_RDONLY;
+ if (fd == -1)
+ return GDBM_FILE_OPEN_ERROR;
+ if (fsync (fd))
{
- int fd;
-
- *end = 0;
- fd = open (path, O_RDONLY);
- if (fd == -1)
- return GDBM_FILE_OPEN_ERROR;
- if (fsync (fd))
- {
- int ec = errno;
- close (fd);
- errno = ec;
- return GDBM_FILE_SYNC_ERROR;
- }
- if (close (fd))
- return GDBM_FILE_CLOSE_ERROR;
+ int ec = errno;
+ close (fd);
+ errno = ec;
+ return GDBM_FILE_SYNC_ERROR;
}
- end--;
+ if (close (fd))
+ return GDBM_FILE_CLOSE_ERROR;
+
+ do
+ --end;
+ while (path < end && end[-1] != '/');
}
return GDBM_NO_ERROR;
}
@@ -258,7 +261,26 @@ gdbm_latest_snapshot (const char *even, const char *odd, const char **ret)
*ret = even;
return GDBM_SNAPSHOT_OK;
}
- /* Both readable: check mtime */
+
+ /*
+ * Both readable: check mtime.
+ * Select the newer snapshot, i.e. the one whose mtime
+ * is greater than the other's
+ */
+ switch (timespec_cmp (&st_even.st_mtim, &st_odd.st_mtim))
+ {
+ case -1:
+ *ret = odd;
+ break;
+
+ case 1:
+ *ret = even;
+ break;
+
+ case 0:
+ /* Shouldn't happen */
+ return GDBM_SNAPSHOT_SAME;
+ }
}
else if (st_odd.st_mode & S_IRUSR)
{
@@ -266,28 +288,12 @@ gdbm_latest_snapshot (const char *even, const char *odd, const char **ret)
return GDBM_SNAPSHOT_OK;
}
else
- {
- /* neither readable: error */
+ {
+ /* neither readable: this means the crash occurred during
+ gdbm_failure_atomic() */
return GDBM_SNAPSHOT_BAD;
}
- /* Compare mtimes, select the newer snapshot, i.e. the one whose mtime
- is greater than the other's */
- switch (timespec_cmp (&st_even.st_mtim, &st_odd.st_mtim))
- {
- case -1:
- *ret = odd;
- break;
-
- case 1:
- *ret = even;
- break;
-
- case 0:
- /* Shouldn't happen */
- return GDBM_SNAPSHOT_SAME;
- }
-
return GDBM_SNAPSHOT_OK;
}
#else
@@ -300,7 +306,7 @@ gdbm_failure_atomic (GDBM_FILE dbf, const char *even, const char *odd)
}
int
-gdbm_latest_snapshot (const char *even, const char *odd, const char *ret)
+gdbm_latest_snapshot (const char *even, const char *odd, const char **ret)
{
errno = ENOSYS;
return GDBM_SNAPSHOT_ERR;

Return to:

Send suggestions and report system problems to the System administrator.