]> sourceware.org Git - lvm2.git/commitdiff
format_text: Round size written up to multiple of 4096.
authorAlasdair G Kergon <agk@redhat.com>
Tue, 12 Dec 2017 22:52:22 +0000 (22:52 +0000)
committerAlasdair G Kergon <agk@redhat.com>
Tue, 12 Dec 2017 22:52:22 +0000 (22:52 +0000)
Zero-fill metadata up to the next 4096 boundary then write out a
multiple of 4096 bytes to avoid triggering a read-modify-write.

WHATS_NEW
lib/format_text/export.c
lib/format_text/format-text.c
lib/format_text/layout.h

index f8713777b0ed269b310d1d50b0410c1053c9792c..5fc4cd3d26a458bee7ca53cec32fa98b858ebad7 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.177 -
 ====================================
+  When writing text metadata content, use complete 4096 byte blocks.
   Change text format metadata alignment from 512 to 4096 bytes.
   When writing metadata, consistently skip mdas marked as failed.
   Refactor and adjust text format metadata alignment calculation.
index e5352376d351bb8eb8602ad88222da643842bc68..1bcaf8369e14b06649f55cdce5ae0822750627c9 100644 (file)
@@ -23,6 +23,7 @@
 #include "lvm-version.h"
 #include "toolcontext.h"
 #include "config-util.h"
+#include "layout.h"
 
 #include <stdarg.h>
 #include <time.h>
@@ -1079,7 +1080,12 @@ size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
                goto_out;
        }
 
-       r = f->data.buf.used + 1;
+       f->data.buf.used += 1;  /* Terminating NUL */
+
+       /* Zero fill up to next alignment boundary */
+       memset(f->data.buf.start + f->data.buf.used, 0, MDA_ALIGNMENT - f->data.buf.used % MDA_ALIGNMENT);
+
+       r = f->data.buf.used;
        *buf = f->data.buf.start;
 
       out:
index ea31a2f501a059b92f96844246dd964ac4097f44..1aa91c72056709093b8dd6e679a862a7fcbb461f 100644 (file)
@@ -704,11 +704,12 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
        struct mda_header *mdah;
        struct pv_list *pvl;
        int r = 0;
-       uint64_t new_wrap;      /* Number of bytes of new metadata that wrap around to start of buffer */
+       uint64_t new_wrap = 0;  /* Number of bytes of new metadata that wrap around to start of buffer */
        uint64_t alignment = MDA_ALIGNMENT;
        int found = 0;
        int noprecommit = 0;
        const char *old_vg_name = NULL;
+       uint64_t new_size_rounded;
 
        /* Ignore any mda on a PV outside the VG. vgsplit relies on this */
        dm_list_iterate_items(pvl, &vg->pvs) {
@@ -735,6 +736,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
        if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
                goto_out;
 
+       /* Following space is zero-filled up to the next MDA_ALIGNMENT boundary */
        if (!fidtc->raw_metadata_buf &&
            !(fidtc->raw_metadata_buf_size =
                        text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
@@ -775,19 +777,33 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
                                  vg->name, dev_name(mdac->area.dev), mdac->rlocn.size, mdah->size - MDA_HEADER_SIZE, rlocn ? rlocn->size : 0);
                        goto out;
                }
+
+               new_size_rounded = mdac->rlocn.size;
+       } else {
+               /* Round up to a multiple of the new alignment */
+               if (mdac->rlocn.offset + new_size_rounded < mdah->size)
+                       new_size_rounded = (mdac->rlocn.size | (alignment - 1)) + 1;
+               else
+                       new_size_rounded = mdac->rlocn.size;
        }
 
-       log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64 " aligned to " FMTu64,
+       log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " (rounded to " FMTu64 ") of " FMTu64 " aligned to " FMTu64,
                            vg->name, dev_name(mdac->area.dev), mdac->area.start +
-                           mdac->rlocn.offset, mdac->rlocn.size - new_wrap, mdac->rlocn.size, alignment);
+                           mdac->rlocn.offset, mdac->rlocn.size - new_wrap, new_size_rounded, mdac->rlocn.size, alignment);
 
-       /* Write text out, circularly */
-       if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
-                      (size_t) (mdac->rlocn.size - new_wrap), MDA_CONTENT_REASON(mda_is_primary(mda)),
-                      fidtc->raw_metadata_buf))
-               goto_out;
+       if (!new_wrap) {
+               /* Write text out, in alignment-sized blocks */
+               if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
+                              (size_t) new_size_rounded, MDA_CONTENT_REASON(mda_is_primary(mda)),
+                              fidtc->raw_metadata_buf))
+                       goto_out;
+       } else {
+               /* Write text out, circularly */
+               if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
+                              (size_t) (mdac->rlocn.size - new_wrap), MDA_CONTENT_REASON(mda_is_primary(mda)),
+                              fidtc->raw_metadata_buf))
+                       goto_out;
 
-       if (new_wrap) {
                log_debug_metadata("Writing wrapped metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64,
                                  dev_name(mdac->area.dev), mdac->area.start +
                                  MDA_HEADER_SIZE, new_wrap, mdac->rlocn.size);
index 1eed664da80316932297920a44a18306d2fe99b1..bc25597553bf2ba26609da6ebfa3039073fc2f28 100644 (file)
@@ -17,6 +17,7 @@
 #define _LVM_TEXT_LAYOUT_H
 
 #include "config.h"
+#include "format-text.h"
 #include "metadata.h"
 #include "lvmcache.h"
 #include "uuid.h"
This page took 0.05297 seconds and 5 git commands to generate.