summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2009-06-22 20:19:04 +0200
committerAlexander Larsson <alexl@redhat.com>2009-06-23 15:10:28 +0200
commitc8551bb6755c19c9ab254d9c647e393561ec4aef (patch)
tree0604a98f38132f8aef89d8cb02a234506fb20fb3
parent589ad8dc3f3bb6b13402170fdf765fba6e2c73d0 (diff)
downloadgvfs-c8551bb6755c19c9ab254d9c647e393561ec4aef.tar.gz
Fix metadata file rotation
Ensure we open in read/write mode Use mmap to set the rotated flag to avoid any confusion with mixing write and mmap updates.
-rw-r--r--metadata/metabuilder.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/metadata/metabuilder.c b/metadata/metabuilder.c
index f8810524..76ab6fb4 100644
--- a/metadata/metabuilder.c
+++ b/metadata/metabuilder.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
+#include <sys/mman.h>
#include <glib/gstdio.h>
#define MAJOR_VERSION 1
@@ -1024,7 +1025,7 @@ meta_builder_write (MetaBuilder *builder,
goto out;
/* Open old file so we can set it rotated */
- fd2 = open (filename, O_RDONLY);
+ fd2 = open (filename, O_RDWR);
if (g_rename (tmp_name, filename) == -1)
{
if (fd2 != -1)
@@ -1035,25 +1036,19 @@ meta_builder_write (MetaBuilder *builder,
/* Mark old file (if any) as rotated) */
if (fd2 != -1)
{
- gboolean have_old_tag;
guint32 old_tag;
char *old_log;
- guint32 c = 0xffffffff;
+ char *data;
+ data = mmap (NULL, RANDOM_TAG_OFFSET + 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
- if (lseek(fd2, RANDOM_TAG_OFFSET, SEEK_SET) == RANDOM_TAG_OFFSET &&
- read (fd2, &old_tag, 4) == 4)
+ if (data)
{
- have_old_tag = TRUE;
- old_tag = GUINT32_FROM_BE (old_tag);
- }
-
- if (lseek(fd2, ROTATED_OFFSET, SEEK_SET) == ROTATED_OFFSET)
- write (fd2, &c, 4);
- close (fd2);
+ old_tag = GUINT32_FROM_BE (*(guint32 *)(data + RANDOM_TAG_OFFSET));
+ *(guint32 *)(data + ROTATED_OFFSET) = 0xffffffff;
+ munmap (data, RANDOM_TAG_OFFSET + 4);
+ close (fd2);
- if (have_old_tag)
- {
old_log = get_journal_filename (filename, old_tag);
g_unlink (old_log);
g_free (old_log);