]> sourceware.org Git - lvm2.git/commitdiff
Change pv_write code to work with the changes in metadata handling interface
authorPeter Rajnoha <prajnoha@redhat.com>
Mon, 21 Feb 2011 12:26:27 +0000 (12:26 +0000)
committerPeter Rajnoha <prajnoha@redhat.com>
Mon, 21 Feb 2011 12:26:27 +0000 (12:26 +0000)
and changes in format_instance.

lib/format1/format1.c
lib/format_text/format-text.c
lib/metadata/metadata-exported.h
lib/metadata/metadata.c
lib/metadata/metadata.h
tools/pvchange.c
tools/pvresize.c
tools/vgconvert.c
tools/vgreduce.c

index b9d4e17b7ce5c1d4b6fa0b82d5a4691b38a240a8..c49226f80aed644aa8681803ca64e90dd9efeadd 100644 (file)
@@ -426,8 +426,7 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volume
        return 1;
 }
 
-static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
-                    struct dm_list *mdas __attribute__((unused)), int64_t sector __attribute__((unused)))
+static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv)
 {
        struct dm_pool *mem;
        struct disk_list *dl;
index a59d11f40b24ee9af5f88697b9474b53d0053366..e72a9363117266847d49f9cc931dc4e4e55b26fb 100644 (file)
@@ -1256,60 +1256,81 @@ static int _text_scan(const struct format_type *fmt, const char *vgname)
 }
 
 /* Only for orphans */
-/* Set label_sector to -1 if rewriting existing label into same sector */
-/* If mdas is supplied it overwrites existing mdas e.g. used with pvcreate */
-static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv,
-                    struct dm_list *mdas, int64_t label_sector)
+static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv)
 {
+       struct text_fid_pv_context *fid_pv_tc;
+       struct format_instance *fid = pv->fid;
        struct label *label;
+       int64_t label_sector;
        struct lvmcache_info *info;
        struct mda_context *mdac;
        struct metadata_area *mda;
+       unsigned mda_index;
        char buf[MDA_HEADER_SIZE] __attribute__((aligned(8)));
        struct mda_header *mdah = (struct mda_header *) buf;
-       uint64_t adjustment;
        struct data_area_list *da;
 
-       /* FIXME Test mode don't update cache? */
-
-       if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
-                                 FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
+       /* Add a new cache entry with PV info or update existing one. */
+       if (!(info = lvmcache_add(fmt->labeller, (const char *) &pv->id,
+                       pv->dev, FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
                return_0;
+
        label = info->label;
 
-       if (label_sector != -1)
+       /*
+        * We can change the label sector for a
+        * plain PV that is not part of a VG only!
+        */
+       if (fid && (!fid->type & FMT_INSTANCE_VG) &&
+           (fid_pv_tc = (struct text_fid_pv_context *) pv->fid->private) &&
+           ((label_sector = fid_pv_tc->label_sector) != -1))
                label->sector = label_sector;
 
        info->device_size = pv->size << SECTOR_SHIFT;
        info->fmt = fmt;
 
-       /* If mdas supplied, use them regardless of existing ones, */
-       /* otherwise retain existing ones */
-       if (mdas) {
-               if (info->mdas.n)
-                       del_mdas(&info->mdas);
-               else
-                       dm_list_init(&info->mdas);
-               dm_list_iterate_items(mda, mdas) {
-                       mdac = mda->metadata_locn;
-                       log_debug("Creating metadata area on %s at sector %"
-                                 PRIu64 " size %" PRIu64 " sectors",
-                                 dev_name(mdac->area.dev),
-                                 mdac->area.start >> SECTOR_SHIFT,
-                                 mdac->area.size >> SECTOR_SHIFT);
-                       add_mda(fmt, NULL, &info->mdas, mdac->area.dev,
-                               mdac->area.start, mdac->area.size, mda_is_ignored(mda));
-               }
-               /* FIXME Temporary until mda creation supported by tools */
-       } else if (!info->mdas.n) {
+       /* Flush all cached metadata areas, we will reenter new/modified ones. */
+       if (info->mdas.n)
+               del_mdas(&info->mdas);
+       else
                dm_list_init(&info->mdas);
+
+       /*
+        * Add all new or modified metadata areas for this PV stored in
+        * its format instance. If this PV is not part of a VG yet,
+        * pv->fid will be used. Otherwise pv->vg->fid will be used.
+        * The fid_get_mda_indexed fn can handle that transparently,
+        * just pass the right format_instance in.
+        */
+       for (mda_index = 0; mda_index < FMT_TEXT_MAX_MDAS_PER_PV; mda_index++) {
+               if (!(mda = fid_get_mda_indexed(fid, (const char *) &pv->id,
+                                                       ID_LEN, mda_index)))
+                       continue;
+
+               mdac = (struct mda_context *) mda->metadata_locn;
+               log_debug("Creating metadata area on %s at sector %"
+                         PRIu64 " size %" PRIu64 " sectors",
+                         dev_name(mdac->area.dev),
+                         mdac->area.start >> SECTOR_SHIFT,
+                         mdac->area.size >> SECTOR_SHIFT);
+               add_mda(fmt, NULL, &info->mdas, mdac->area.dev,
+                       mdac->area.start, mdac->area.size, mda_is_ignored(mda));
        }
 
        /*
-        * If no pe_start supplied but PV already exists,
-        * get existing value; use-cases include:
-        * - pvcreate on PV without prior pvremove
-        * - vgremove on VG with PV(s) that have pe_start=0 (hacked cfg)
+        * FIXME: Allow writing zero offset/size data area to disk.
+        *        This requires defining a special value since we can't
+        *        write offset/size that is 0/0 - this is already reserved
+        *        as a delimiter in data/metadata area area list in PV header
+        *        (needs exploring compatibility with older lvm2).
+        */
+
+       /*
+        * We can't actually write pe_start = 0 (a data area offset)
+        * in PV header now. We need to replace this value here. This can
+        * happen with vgcfgrestore with redefined pe_start or
+        * pvcreate --restorefile. However, we can can have this value in
+        * metadata which will override the value in the PV header.
         */
        if (info->das.n) {
                if (!pv->pe_start)
@@ -1319,66 +1340,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
        } else
                dm_list_init(&info->das);
 
-#if 0
-       /*
-        * FIXME: ideally a pre-existing pe_start seen in .pv_write
-        * would always be preserved BUT 'pvcreate on PV without prior pvremove'
-        * could easily cause the pe_start to overlap with the first mda!
-        */
-       if (pv->pe_start) {
-               log_very_verbose("%s: preserving pe_start=%lu",
-                                pv_dev_name(pv), pv->pe_start);
-               goto preserve_pe_start;
-       }
-#endif
-
-       /*
-        * If pe_start is still unset, set it to first aligned
-        * sector after any metadata areas that begin before pe_start.
-        */
-       if (!pv->pe_start) {
-               pv->pe_start = pv->pe_align;
-               if (pv->pe_align_offset)
-                       pv->pe_start += pv->pe_align_offset;
-       }
-       dm_list_iterate_items(mda, &info->mdas) {
-               mdac = (struct mda_context *) mda->metadata_locn;
-               if (pv->dev == mdac->area.dev &&
-                   ((mdac->area.start <= (pv->pe_start << SECTOR_SHIFT)) ||
-                   (mdac->area.start <= lvm_getpagesize() &&
-                    pv->pe_start < (lvm_getpagesize() >> SECTOR_SHIFT))) &&
-                   (mdac->area.start + mdac->area.size >
-                    (pv->pe_start << SECTOR_SHIFT))) {
-                       pv->pe_start = (mdac->area.start + mdac->area.size)
-                           >> SECTOR_SHIFT;
-                       /* Adjust pe_start to: (N * pe_align) + pe_align_offset */
-                       if (pv->pe_align) {
-                               adjustment =
-                               (pv->pe_start - pv->pe_align_offset) % pv->pe_align;
-                               if (adjustment)
-                                       pv->pe_start += (pv->pe_align - adjustment);
-
-                               log_very_verbose("%s: setting pe_start=%" PRIu64
-                                        " (orig_pe_start=%" PRIu64 ", "
-                                        "pe_align=%lu, pe_align_offset=%lu, "
-                                        "adjustment=%" PRIu64 ")",
-                                        pv_dev_name(pv), pv->pe_start,
-                                        (adjustment ?
-                                         pv->pe_start - (pv->pe_align - adjustment) :
-                                         pv->pe_start),
-                                        pv->pe_align, pv->pe_align_offset, adjustment);
-                       }
-               }
-       }
-       if (pv->pe_start >= pv->size) {
-               log_error("Data area is beyond end of device %s!",
-                         pv_dev_name(pv));
-               return 0;
-       }
-
-       /* FIXME: preserve_pe_start: */
-       if (!add_da
-           (NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
+       if (!add_da(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
                return_0;
 
        if (!dev_open(pv->dev))
@@ -1397,11 +1359,17 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
                }
        }
 
-       if (!label_write(pv->dev, label)) {
+       if (!label_write(pv->dev, info->label)) {
                dev_close(pv->dev);
                return_0;
        }
 
+       /*
+        *  FIXME: We should probably use the format instance's metadata
+        *        areas for label_write and only if it's successful,
+        *        update the cache afterwards?
+        */
+
        if (!dev_close(pv->dev))
                return_0;
 
index b57f6ff4b675bf54cfca24ac88003036df394a43..6cc02bd5985c54fc70e7063eeb79bb582985d5cd 100644 (file)
@@ -384,8 +384,7 @@ struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
 struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
 int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings);
 
-int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
-            struct dm_list *mdas, int64_t label_sector);
+int pv_write(struct cmd_context *cmd, struct physical_volume *pv);
 int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
            const char *pv_name);
 int move_pvs_used_by_lv(struct volume_group *vg_from,
index e1cf0e50c8ca337226ccde4338c4f9cc513bbcd7..68e4b07008a1e5e0dd8dbaedb70d32b84341da44 100644 (file)
@@ -586,7 +586,7 @@ int vg_remove(struct volume_group *vg)
                }
 
                /* FIXME Write to same sector label was read from */
-               if (!pv_write(vg->cmd, pv, NULL, INT64_C(-1))) {
+               if (!pv_write(vg->cmd, pv)) {
                        log_error("Failed to remove physical volume \"%s\""
                                  " from volume group \"%s\"",
                                  pv_dev_name(pv), vg->name);
@@ -1511,7 +1511,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,
        log_very_verbose("Writing physical volume data to disk \"%s\"",
                         pv_name);
 
-       if (!(pv_write(cmd, pv, &mdas, pp->labelsector))) {
+       if (!(pv_write(cmd, pv))) {
                log_error("Failed to write physical volume \"%s\"", pv_name);
                goto error;
        }
@@ -3536,8 +3536,7 @@ int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings)
 }
 
 int pv_write(struct cmd_context *cmd __attribute__((unused)),
-            struct physical_volume *pv,
-            struct dm_list *mdas, int64_t label_sector)
+            struct physical_volume *pv)
 {
        if (!pv->fmt->ops->pv_write) {
                log_error("Format does not support writing physical volumes");
@@ -3550,7 +3549,7 @@ int pv_write(struct cmd_context *cmd __attribute__((unused)),
                return 0;
        }
 
-       if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector))
+       if (!pv->fmt->ops->pv_write(pv->fmt, pv))
                return_0;
 
        return 1;
@@ -3569,7 +3568,7 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
                return 0;
        }
 
-       if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
+       if (!pv_write(cmd, pv)) {
                log_error("Failed to clear metadata from physical "
                          "volume \"%s\" after removal from \"%s\"",
                          pv_dev_name(pv), old_vg_name);
index 18b53542d30d8faaa0df82cffea40929dcf069e3..6acb30b8aaecc57eabf10beb446faba613bd039f 100644 (file)
@@ -297,8 +297,7 @@ struct format_handler {
         * pv->vg_name must be a valid orphan VG name
         */
        int (*pv_write) (const struct format_type * fmt,
-                        struct physical_volume * pv, struct dm_list * mdas,
-                        int64_t label_sector);
+                        struct physical_volume * pv);
 
        /*
         * Tweak an already filled out a lv eg, check there
index 6e0fc2d384b9514372a6227aaa34c402353b81bd..0ffe7df4397757d75cf1572100f92f8451b57799 100644 (file)
@@ -139,7 +139,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 
                        pv->vg_name = pv->fmt->orphan_vg_name;
                        pv->pe_alloc_count = 0;
-                       if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+                       if (!(pv_write(cmd, pv))) {
                                log_error("pv_write with new uuid failed "
                                          "for %s.", pv_name);
                                return 0;
@@ -161,7 +161,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
                        return 0;
                }
                backup(vg);
-       } else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+       } else if (!(pv_write(cmd, pv))) {
                log_error("Failed to store physical volume \"%s\"",
                          pv_name);
                return 0;
index f347d9d377c6eaaf0c314b861f29b0e96f807bc8..f1870c6c6e7d897548dd5ab133a04677c61c6e9f 100644 (file)
@@ -150,7 +150,7 @@ static int _pv_resize_single(struct cmd_context *cmd,
                        goto out;
                }
                backup(vg);
-       } else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+       } else if (!(pv_write(cmd, pv))) {
                log_error("Failed to store physical volume \"%s\"",
                          pv_name);
                goto out;
index e19fa480061e7607c070e47c0281770775b5644a..3c9ff6535c8e3b60d0c7b25d8de2589f4fb2677d 100644 (file)
@@ -154,9 +154,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
 
                log_very_verbose("Writing physical volume data to disk \"%s\"",
                                 pv_dev_name(pv));
-               if (!(pv_write(cmd, pv, &mdas,
-                              arg_int64_value(cmd, labelsector_ARG,
-                                              DEFAULT_LABELSECTOR)))) {
+               if (!(pv_write(cmd, pv))) {
                        log_error("Failed to write physical volume \"%s\"",
                                  pv_dev_name(pv));
                        log_error("Use pvcreate and vgcfgrestore to repair "
index 5e61cf832544d46ca72c6f9f541e094b65f0325b..8d3cb1cd0f4b05435a70934973aef1b4fb52566b 100644 (file)
@@ -438,7 +438,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
                goto bad;
        }
 
-       if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
+       if (!pv_write(cmd, pv)) {
                log_error("Failed to clear metadata from physical "
                          "volume \"%s\" "
                          "after removal from \"%s\"", name, vg->name);
This page took 0.048324 seconds and 5 git commands to generate.