diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-30 14:04:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-30 14:04:48 +0300 |
commit | 4e819c987988432ef936c6c3e003db6b26463154 (patch) | |
tree | feefee7688cec0df1a66401b9da2204272d8d83f | |
parent | b8d5da4c426b21ca0e56fc1cd6f75b49c0668e95 (diff) | |
download | gdbm-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.
-rw-r--r-- | src/fullio.c | 46 | ||||
-rw-r--r-- | src/gdbmopen.c | 11 | ||||
-rw-r--r-- | src/gdbmsetopt.c | 4 | ||||
-rw-r--r-- | src/mmap.c | 42 | ||||
-rw-r--r-- | src/proto.h | 1 | ||||
-rw-r--r-- | src/update.c | 2 |
6 files changed, 62 insertions, 44 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 @@ -428,6 +428,17 @@ gdbm_fd_open (int fd, const char *file_name, int block_size, 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, }; @@ -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; } |