]> sourceware.org Git - lvm2.git/commitdiff
Improve stripe size validation.
authorAlasdair Kergon <agk@redhat.com>
Sat, 29 Apr 2006 22:08:43 +0000 (22:08 +0000)
committerAlasdair Kergon <agk@redhat.com>
Sat, 29 Apr 2006 22:08:43 +0000 (22:08 +0000)
Increase maximum stripe size limit to physical extent size for lvm2 metadata.

WHATS_NEW
lib/format_text/format-text.c
lib/metadata/metadata.h
man/lvcreate.8
tools/lvcreate.c
tools/lvresize.c

index 7bd1653e0aabe02797947332a67afddf4b04ecae..9ff0176ab7f3eb0f48dabf6f6424f837abf168b1 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
 Version 2.02.06 -
 =================================
+  Improve stripe size validation.
+  Increase maximum stripe size limit to physical extent size for lvm2 metadata.
   Fix activation code to check for pre-existing mirror logs.
   Tighten region size validation.
   Ignore empty strings in config files.
index cd579950af9cae3505af6fd413326f1b583a10e3..3ca480b80155cdec7c7399fdeacba3fe4b25dc58 100644 (file)
@@ -1754,7 +1754,8 @@ struct format_type *create_text_format(struct cmd_context *cmd)
        fmt->name = FMT_TEXT_NAME;
        fmt->alias = FMT_TEXT_ALIAS;
        fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
-                       FMT_UNLIMITED_VOLS | FMT_RESIZE_PV;
+                       FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
+                       FMT_UNLIMITED_STRIPESIZE;
 
        if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
                log_error("Failed to allocate dir_list");
index f9b732dfca410e2d078639f75f31d4e439123479..c3f2b0d21105511448ef3ea16f1de2cdecc6b710 100644 (file)
@@ -31,6 +31,7 @@
 #define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
 #define STRIPE_SIZE_MIN ( getpagesize() >> SECTOR_SHIFT)       /* PAGESIZE in sectors */
 #define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT)        /* 512 KB in sectors */
+#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
 #define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT)    /* 512 KB in sectors */
 #define PE_ALIGN (65536UL >> SECTOR_SHIFT)     /* PE alignment */
 #define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
@@ -74,6 +75,7 @@
 #define FMT_ORPHAN_ALLOCATABLE 0x00000020      /* Orphan PV allocatable? */
 #define FMT_PRECOMMIT          0x00000040      /* Supports pre-commit? */
 #define FMT_RESIZE_PV          0x00000080      /* Supports pvresize? */
+#define FMT_UNLIMITED_STRIPESIZE 0x00000080    /* Unlimited stripe size? */
 
 typedef enum {
        ALLOC_INVALID,
index 881cdc4c4f81bd1498d629ccbdddf8faa1701a7c..a3717ab6a2293ec37199463f664cdcb29bfd1407 100644 (file)
@@ -58,7 +58,9 @@ the logical volume.
 .I \-I, \-\-stripesize StripeSize
 Gives the number of kilobytes for the granularity of the stripes.
 .br
-StripeSize must be 2^n (n = 2 to 9)
+StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
+For metadata in LVM2 format, the stripe size may be a larger
+power of 2 but must not exceed the physical extent size.
 .TP
 .I \-l, \-\-extents LogicalExtentsNumber
 Gives the number of logical extents to allocate for the new
index f191174589f97789c40cde59558297393d454320..7464929be09763f417e1842cc02beabb7b3df0c9 100644 (file)
@@ -181,6 +181,10 @@ static int _read_size_params(struct lvcreate_params *lp,
        return 1;
 }
 
+/* The stripe size is limited by the size of a uint32_t, but since the
+ * value given by the user is doubled, and the final result must be a
+ * power of 2, we must divide UINT_MAX by four and add 1 (to round it
+ * up to the power of 2) */
 static int _read_stripe_params(struct lvcreate_params *lp,
                               struct cmd_context *cmd,
                               int *pargc, char ***pargv)
@@ -192,6 +196,12 @@ static int _read_stripe_params(struct lvcreate_params *lp,
                        log_error("Negative stripesize is invalid");
                        return 0;
                }
+               /* Check to make sure we won't overflow lp->stripe_size */
+               if(arg_uint_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT) {
+                       log_error("Stripe size cannot be larger than %s",
+                                 display_size(cmd, STRIPE_SIZE_LIMIT, SIZE_SHORT));
+                       return 0;
+               }
                lp->stripe_size = 2 * arg_uint_value(cmd, stripesize_ARG, 0);
        }
 
@@ -204,7 +214,8 @@ static int _read_stripe_params(struct lvcreate_params *lp,
                lp->stripe_size = find_config_int(cmd->cft->root,
                                                  "metadata/stripesize",
                                                  DEFAULT_STRIPESIZE) * 2;
-               log_print("Using default stripesize %dKB", lp->stripe_size / 2);
+               log_print("Using default stripesize %s",
+                         display_size(cmd, lp->stripe_size, SIZE_SHORT));
        }
 
        if (argc && (unsigned) argc < lp->stripes) {
@@ -219,10 +230,11 @@ static int _read_stripe_params(struct lvcreate_params *lp,
                return 0;
        }
 
+       /* MAX size check is in _lvcreate */
        if (lp->stripes > 1 && (lp->stripe_size < STRIPE_SIZE_MIN ||
-                               lp->stripe_size > STRIPE_SIZE_MAX ||
                                lp->stripe_size & (lp->stripe_size - 1))) {
-               log_error("Invalid stripe size %d", lp->stripe_size);
+               log_error("Invalid stripe size %s",
+                         display_size(cmd, lp->stripe_size, SIZE_SHORT));
                return 0;
        }
 
@@ -505,12 +517,23 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
                pvh = &vg->pvs;
 
        if (lp->stripe_size > vg->extent_size) {
-               log_error("Setting stripe size %d KB to physical extent "
-                         "size %u KB", lp->stripe_size / 2,
-                         vg->extent_size / 2);
+               log_error("Reducing requested stripe size %s to maximum, "
+                         "physical extent size %s",
+                         display_size(cmd, lp->stripe_size, SIZE_SHORT),
+                         display_size(cmd, vg->extent_size, SIZE_SHORT));
                lp->stripe_size = vg->extent_size;
        }
 
+       /* Need to check the vg's format to verify this - the cmd format isn't setup properly yet */
+       if (lp->stripes > 1 &&
+           !(vg->fid->fmt->features & FMT_UNLIMITED_STRIPESIZE) &&
+           (lp->stripe_size > STRIPE_SIZE_MAX)) {
+               log_error("Stripe size may not exceed %s",
+                         display_size(cmd, STRIPE_SIZE_MAX,
+                                      SIZE_SHORT));
+               return 0;
+       }
+
        if (lp->size) {
                /* No of 512-byte sectors */
                tmp_size = lp->size;
index 094c7f5a08bb4ce32e72b7329de77fca3dbf4e0e..f3956fa26c939dce4e14cbf7e68e3ad6bf401a54 100644 (file)
@@ -178,15 +178,35 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                        log_error("Stripesize may not be negative.");
                        return ECMD_FAILED;
                }
-               if (vg->fid->fmt->features & FMT_SEGMENTS)
+
+               if (arg_uint_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT) {
+                       log_error("Stripe size cannot be larger than %s",
+                                 display_size(cmd, STRIPE_SIZE_LIMIT, SIZE_SHORT));
+                       return 0;
+               }
+
+               if (!(vg->fid->fmt->features & FMT_SEGMENTS))
+                       log_print("Varied stripesize not supported. Ignoring.");
+               else if (arg_uint_value(cmd, stripesize_ARG, 0) > vg->extent_size) {
+                       log_error("Reducing stripe size %s to maximum, "
+                                 "physical extent size %s",
+                                 display_size(cmd,
+                                       arg_uint_value(cmd, stripesize_ARG, 0) * 2,
+                                       SIZE_SHORT),
+                                 display_size(cmd, vg->extent_size, SIZE_SHORT));
+                       lp->stripe_size = vg->extent_size;
+               } else
                        lp->stripe_size = 2 * arg_uint_value(cmd,
                                                             stripesize_ARG, 0);
-               else
-                       log_print("Varied stripesize not supported. Ignoring.");
+
                if (lp->mirrors) {
                        log_error("Mirrors and striping cannot be combined yet.");
                        return ECMD_FAILED;
                }
+               if (lp->stripe_size & (lp->stripe_size - 1)) {
+                       log_error("Stripe size must be power of 2");
+                       return 0;
+               }
        }
 
        lv = lvl->lv;
@@ -279,16 +299,18 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
 
                if (!lp->stripe_size && lp->stripes > 1) {
                        if (seg_stripesize) {
-                               log_print("Using stripesize of last segment "
-                                         "%dKB", seg_stripesize / 2);
+                               log_print("Using stripesize of last segment %s",
+                                         display_size(cmd, seg_stripesize,
+                                                      SIZE_SHORT));
                                lp->stripe_size = seg_stripesize;
                        } else {
                                lp->stripe_size =
                                        find_config_int(cmd->cft->root,
                                                        "metadata/stripesize",
                                                        DEFAULT_STRIPESIZE) * 2;
-                               log_print("Using default stripesize %dKB",
-                                         lp->stripe_size / 2);
+                               log_print("Using default stripesize %s",
+                                         display_size(cmd, lp->stripe_size,
+                                                      SIZE_SHORT));
                        }
                }
        }
@@ -362,6 +384,12 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                                  lp->extents, lp->extents - size_rest);
                        lp->extents = lp->extents - size_rest;
                }
+
+               if (lp->stripe_size < STRIPE_SIZE_MIN) {
+                       log_error("Invalid stripe size %s",
+                                 display_size(cmd, lp->stripe_size, SIZE_SHORT));
+                       return 0;
+               }
        }
 
        if (lp->extents == lv->le_count) {
This page took 0.046229 seconds and 5 git commands to generate.