summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2018-05-30 11:04:48 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2018-05-30 11:04:48 (GMT)
commit4e819c987988432ef936c6c3e003db6b26463154 (patch) (side-by-side diff)
treefeefee7688cec0df1a66401b9da2204272d8d83f
parentb8d5da4c426b21ca0e56fc1cd6f75b49c0668e95 (diff)
downloadgdbm-4e819c987988432ef936c6c3e003db6b26463154.tar.gz
gdbm-4e819c987988432ef936c6c3e003db6b26463154.tar.bz2
Fix the legacy operation (--disable-mmapped-io)
* src/mmap.c (_gdbm_file_extend): Move to ... * src/fullio.c: ... here * src/proto.h (_gdbm_file_extend): New proto. * src/gdbmopen.c (gdbm_fd_open): Make sure the file size equals header->next_block. * src/gdbmsetopt.c [!HAVE_MMAP]: Don't disable GDBM_GETFLAGS. * src/update.c (_gdbm_end_update): Make sure disk file ends on header->next_block.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/fullio.c46
-rw-r--r--src/gdbmopen.c15
-rw-r--r--src/gdbmsetopt.c4
-rw-r--r--src/mmap.c42
-rw-r--r--src/proto.h1
-rw-r--r--src/update.c2
6 files changed, 64 insertions, 46 deletions
diff --git a/src/fullio.c b/src/fullio.c
index 84eea60..0efa96d 100644
--- a/src/fullio.c
+++ b/src/fullio.c
@@ -75,3 +75,49 @@ _gdbm_full_write (GDBM_FILE dbf, void *buffer, size_t size)
}
return 0;
}
+
+/* Grow the disk file of DBF to SIZE bytes in length. Fill the
+ newly allocated space with zeros. */
+int
+_gdbm_file_extend (GDBM_FILE dbf, off_t size)
+{
+ size_t page_size = sysconf (_SC_PAGESIZE);
+ char *buf;
+ off_t file_end;
+
+ file_end = lseek (dbf->desc, 0, SEEK_END);
+ if (!file_end)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, FALSE);
+ return -1;
+ }
+ size -= file_end;
+ if (size > 0)
+ {
+ if (size < page_size)
+ page_size = size;
+ buf = calloc (1, page_size);
+ if (!buf)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_MALLOC_ERROR, FALSE);
+ return -1;
+ }
+
+ while (size)
+ {
+ ssize_t n = write (dbf->desc, buf,
+ size < page_size ? size : page_size);
+ if (n <= 0)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_WRITE_ERROR, TRUE);
+ break;
+ }
+ size -= n;
+ }
+ free (buf);
+ if (size)
+ return -1;
+ }
+ return 0;
+}
+
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 53d62a4..31d8fea 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -139,7 +139,7 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st)
if (hdr->next_block != st->st_size)
/* FIXME: Should return GDBM_NEED_RECOVERY instead? */
return GDBM_BAD_HEADER;
-
+
/* Make sure dir and dir + dir_size fall within the file boundary */
if (!(hdr->dir > 0
&& hdr->dir < st->st_size
@@ -427,7 +427,18 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
SAVE_ERRNO (gdbm_close (dbf));
return NULL;
}
-
+
+ if (_gdbm_file_extend (dbf, dbf->header->next_block))
+ {
+ GDBM_DEBUG (GDBM_DEBUG_OPEN|GDBM_DEBUG_ERR,
+ "%s: error extending file: %s",
+ dbf->name, gdbm_db_strerror (dbf));
+ if (!(flags & GDBM_CLOERROR))
+ dbf->desc = -1;
+ SAVE_ERRNO (gdbm_close (dbf));
+ return NULL;
+ }
+
/* Wait for initial configuration to be written to disk. */
gdbm_file_sync (dbf);
diff --git a/src/gdbmsetopt.c b/src/gdbmsetopt.c
index 69e244c..f9face0 100644
--- a/src/gdbmsetopt.c
+++ b/src/gdbmsetopt.c
@@ -248,6 +248,7 @@ setopt_gdbm_getmaxmapsize (GDBM_FILE dbf, void *optval, int optlen)
*(size_t*) optval = dbf->mapped_size_max;
return 0;
}
+#endif
static int
setopt_gdbm_getflags (GDBM_FILE dbf, void *optval, int optlen)
@@ -270,7 +271,6 @@ setopt_gdbm_getflags (GDBM_FILE dbf, void *optval, int optlen)
}
return 0;
}
-#endif
static int
setopt_gdbm_getdbname (GDBM_FILE dbf, void *optval, int optlen)
@@ -323,8 +323,8 @@ static setopt_handler setopt_handler_tab[] = {
[GDBM_GETMMAP] = setopt_gdbm_getmmap,
[GDBM_SETMAXMAPSIZE] = setopt_gdbm_setmaxmapsize,
[GDBM_GETMAXMAPSIZE] = setopt_gdbm_getmaxmapsize,
- [GDBM_GETFLAGS] = setopt_gdbm_getflags,
#endif
+ [GDBM_GETFLAGS] = setopt_gdbm_getflags,
[GDBM_GETDBNAME] = setopt_gdbm_getdbname,
[GDBM_GETBLOCKSIZE] = setopt_gdbm_getblocksize,
};
diff --git a/src/mmap.c b/src/mmap.c
index ba05bd7..008a0f8 100644
--- a/src/mmap.c
+++ b/src/mmap.c
@@ -122,48 +122,6 @@ _gdbm_internal_remap (GDBM_FILE dbf, size_t size)
return 0;
}
-/* Grow the disk file of DBF to the SIZE bytes in length. Fill the
- newly allocated space with zeros. */
-static int
-_gdbm_file_extend (GDBM_FILE dbf, off_t size)
-{
- size_t page_size = sysconf (_SC_PAGESIZE);
- char *buf;
- off_t file_end;
-
- file_end = lseek (dbf->desc, 0, SEEK_END);
- if (!file_end)
- {
- GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, FALSE);
- return -1;
- }
- size -= file_end;
-
- if (size < page_size)
- page_size = size;
- buf = calloc (1, page_size);
- if (!buf)
- {
- GDBM_SET_ERRNO (dbf, GDBM_MALLOC_ERROR, FALSE);
- return -1;
- }
-
- while (size)
- {
- ssize_t n = write (dbf->desc, buf, size < page_size ? size : page_size);
- if (n <= 0)
- {
- GDBM_SET_ERRNO (dbf, GDBM_FILE_WRITE_ERROR, FALSE);
- break;
- }
- size -= n;
- }
- free (buf);
- if (size)
- return -1;
- return 0;
-}
-
# define _REMAP_DEFAULT 0
# define _REMAP_EXTEND 1
# define _REMAP_END 2
diff --git a/src/proto.h b/src/proto.h
index 563505f..3fb990c 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -68,6 +68,7 @@ int _gdbm_lock_file (GDBM_FILE);
/* From fullio.c */
int _gdbm_full_read (GDBM_FILE, void *, size_t);
int _gdbm_full_write (GDBM_FILE, void *, size_t);
+int _gdbm_file_extend (GDBM_FILE dbf, off_t size);
/* From base64.c */
int _gdbm_base64_encode (const unsigned char *input, size_t input_len,
diff --git a/src/update.c b/src/update.c
index e3ee717..d10d31f 100644
--- a/src/update.c
+++ b/src/update.c
@@ -122,6 +122,8 @@ _gdbm_end_update (GDBM_FILE dbf)
{
if (write_header (dbf))
return -1;
+ if (_gdbm_file_extend (dbf, dbf->header->next_block))
+ return -1;
dbf->header_changed = FALSE;
}

Return to:

Send suggestions and report system problems to the System administrator.