diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-04-24 18:47:19 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-04-24 18:47:19 +0000 |
commit | c9edc8891dac165b8446cdd11db4304f9faf01d8 (patch) | |
tree | 261ff4a90cd7ed147cab0766fab92d2a3db7b710 /locale/programs/locarchive.c | |
parent | c2d5bd5b00cfbb0ef192821f2d724fb6448d59e3 (diff) | |
download | glibc-c9edc8891dac165b8446cdd11db4304f9faf01d8.zip glibc-c9edc8891dac165b8446cdd11db4304f9faf01d8.tar.gz glibc-c9edc8891dac165b8446cdd11db4304f9faf01d8.tar.bz2 |
* locale/programs/locarchive.c (enlarge_archive): Conserve address
space when temporarily mapping the whole content of the old file.
Diffstat (limited to 'locale/programs/locarchive.c')
-rw-r--r-- | locale/programs/locarchive.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c index 66c5d39..e1e0423 100644 --- a/locale/programs/locarchive.c +++ b/locale/programs/locarchive.c @@ -133,14 +133,14 @@ create_archive (const char *archivefname, struct locarhandle *ah) address space. */ size_t reserved = RESERVE_MMAP_SIZE; int xflags = 0; - if (total < RESERVE_MMAP_SIZE + if (total < reserved && ((p = mmap64 (NULL, reserved, PROT_NONE, MAP_ANON, -1, 0)) != MAP_FAILED)) xflags = MAP_FIXED; else { p = NULL; - reserved = 0; + reserved = total; } /* Map the header and all the administration data structures. */ @@ -307,11 +307,22 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) /* Not all of the old file has to be mapped. Change this now this we will have to access the whole content. */ - if (fstat64 (ah->fd, &st) != 0 - || (st.st_size > ah->mmaped - && (ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE, - MAP_SHARED, ah->fd, 0)) == MAP_FAILED)) + if (fstat64 (ah->fd, &st) != 0) + enomap: error (EXIT_FAILURE, errno, _("cannot map locale archive file")); + + if (st.st_size < ah->reserved) + ah->addr = mremap (ah->addr, ah->mmaped, st.st_size, + MREMAP_MAYMOVE | MREMAP_FIXED, ah->addr); + else + { + munmap (ah->addr, ah->reserved); + ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, ah->fd, 0); + ah->reserved = st.st_size; + } + if (ah->addr == MAP_FAILED) + goto enomap; ah->mmaped = st.st_size; /* Create a temporary file in the correct directory. */ @@ -581,14 +592,14 @@ open_archive (struct locarhandle *ah, bool readonly) size_t reserved = RESERVE_MMAP_SIZE; int xflags = 0; void *p; - if (st.st_size < RESERVE_MMAP_SIZE + if (st.st_size < reserved && ((p = mmap64 (NULL, RESERVE_MMAP_SIZE, PROT_NONE, MAP_ANON, -1, 0)) != MAP_FAILED)) xflags = MAP_FIXED; else { p = NULL; - reserved = 0; + reserved = st.st_size; } /* Map the entire file. We might need to compare the category data @@ -609,7 +620,7 @@ close_archive (struct locarhandle *ah) { if (ah->fd != -1) { - munmap (ah->addr, MAX (ah->reserved, ah->mmaped)); + munmap (ah->addr, ah->reserved); close (ah->fd); } } |