From: NeilBrown Date: Sun, 13 Mar 2011 06:13:35 +0000 (+1100) Subject: Add lafs_validate_geometry for mkfs. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=646e2b6c44247dd5e114d2a2ec0b10ee6d8a11a8;p=lafs-utils.git Add lafs_validate_geometry for mkfs. Split this out of mkfs and put it in library for 'lafs' to use. Signed-off-by: NeilBrown --- diff --git a/include/lafs/lafs.h b/include/lafs/lafs.h index 897ead6..dc2696f 100644 --- a/include/lafs/lafs.h +++ b/include/lafs/lafs.h @@ -14,6 +14,11 @@ struct lafs *lafs_alloc(void); int lafs_new(struct lafs *, int block_bytes); +char *lafs_validate_geometry(long *block_bytes, + long *segment_bytes, + long *stride_bytes, + int *width, + long long device_bytes); struct lafs_device *lafs_add_device(struct lafs *, char *devname, int fd, loff_t segblocks, loff_t strideblock, int width, int usage_inum); diff --git a/lib/lafs_validate_geometry.c b/lib/lafs_validate_geometry.c new file mode 100644 index 0000000..3b7f03e --- /dev/null +++ b/lib/lafs_validate_geometry.c @@ -0,0 +1,98 @@ +/* lafs_validate_geometry. + * When adding a device to a LaFS we need to check the geometry + * parameters are all valid and consistent, and we need to set + * defaults. + * That is done here and used by mkfs and 'lafs'. + */ + +#define _GNU_SOURCE +#include +#include + +int is_pow2(long num) +{ + return (num & (num-1)) == 0; +} + + +char *lafs_validate_geometry(long *block_bytes, + long *segment_bytes, + long *stride_bytes, + int *width, + long long device_bytes) +{ + char *error = NULL; + + if (*block_bytes == 0) + *block_bytes = 1024; + + if (*block_bytes < 512 || *block_bytes > 4096 || + !is_pow2(*block_bytes)) { + asprintf(&error, "block size %ld is illegal - must be " + "power of 2 in range 512..4096", + *block_bytes); + return error; + } + + if (*width == 0) + *width = 1; + if (*width < 1 || *width > 128) { + asprintf(&error, "width %d is illegal - must be in range 1..128", + *width); + return error; + } + + if (*stride_bytes == 0) + *stride_bytes = *block_bytes; + + if (*stride_bytes < 0 || (*stride_bytes % *block_bytes) != 0) { + asprintf(&error, "stride %ld is illegal - must be " + "a multiple of block size", + *stride_bytes); + return error; + } + + /* segment size must be a multiple of block size and of width. + * It must either be a multiple or a sub-multiple of stride size + */ + if (*segment_bytes == 0) { + /* choose maximum size ?? */ + long seg; + long blocks = 65536 / *width; + blocks *= *width; + seg = *block_bytes * blocks; + if (seg * 17 > device_bytes) { + blocks = device_bytes / 16 / *block_bytes / *width; + blocks *= *width; + seg = *block_bytes * blocks; + } + if (*stride_bytes < seg) { + seg /= *stride_bytes; + seg *= *stride_bytes; + } else { + if ((*stride_bytes % seg) != 0) { + asprintf(&error, "explicit segment size must be " + "given with large stride"); + return error; + } + } + *segment_bytes = seg; + } + + if (*segment_bytes * 8 > device_bytes) + asprintf(&error, "segment size too large for device."); + else if (*segment_bytes < *block_bytes * 8) + asprintf(&error, "segment must hold at least 8 blocks."); + else if (*segment_bytes % *block_bytes) + asprintf(&error, "segment size must be a multiple of block size"); + else if (*segment_bytes % *width) + asprintf(&error, "segment size must be a multiple of width"); + else if (*segment_bytes > *stride_bytes && + (*segment_bytes % *stride_bytes)) + asprintf(&error, "segment size must be a multiple of stride size"); + else if (*segment_bytes < *stride_bytes && + (*stride_bytes % *segment_bytes)) + asprintf(&error, "segment size must be a divisor of stride size"); + + return error; +} diff --git a/tools/mkfs.lafs.c b/tools/mkfs.lafs.c index d24ee44..2d61ca0 100644 --- a/tools/mkfs.lafs.c +++ b/tools/mkfs.lafs.c @@ -165,98 +165,6 @@ void get_num(int *valp, char *arg, char *name) *valp = val; } -int is_pow2(long num) -{ - return (num & (num-1)) == 0; -} - - -void validate_parameters(long *block_bytes, long *segment_bytes, long *stride_bytes, - int *width, long long device_bytes) -{ - - if (*block_bytes == 0) - *block_bytes = 1024; - - if (*block_bytes < 512 || *block_bytes > 4096 || - !is_pow2(*block_bytes)) { - fprintf(stderr, "lafs.mkfs: block size %ld is illegal - must be power of 2 in range 512..4096\n", - *block_bytes); - exit(2); - } - - if (*width == 0) - *width = 1; - if (*width < 1 || *width > 128) { - fprintf(stderr, "lafs.mkfs: width %d is illegal - must be in range 1..128\n", *width); - exit(2); - } - - if (*stride_bytes == 0) - *stride_bytes = *block_bytes; - - if (*stride_bytes < 0 || (*stride_bytes % *block_bytes) != 0) { - fprintf(stderr, "lafs.mkfs: stride %ld is illegal - must be a multiple of block size\n", - *stride_bytes); - exit(2); - } - - /* segment size must be a multiple of block size and of width. - * It must either be a multiple or a sub-multiple of stride size - */ - if (*segment_bytes == 0) { - /* choose maximum size ?? */ - long seg; - long blocks = 65536 / *width; - blocks *= *width; - seg = *block_bytes * blocks; - if (seg * 17 > device_bytes) { - blocks = device_bytes / 16 / *block_bytes / *width; - blocks *= *width; - seg = *block_bytes * blocks; - } - if (*stride_bytes < seg) { - seg /= *stride_bytes; - seg *= *stride_bytes; - } else { - if ((*stride_bytes % seg) != 0) { - fprintf(stderr, "lafs.mkfs: explicit segment size must be given with large stride\n"); - exit(2); - } - } - *segment_bytes = seg; - } - - if (*segment_bytes * 8 > device_bytes) { - fprintf(stderr, "lafs.mkfs: segment size too large for device.\n"); - exit(2); - } - - if (*segment_bytes < *block_bytes * 8) { - fprintf(stderr, "lafs.mkfs: segment must hold at least 8 blocks.\n"); - exit(2); - } - - if (*segment_bytes % *block_bytes) { - fprintf(stderr, "lafs.mkfs: segment size must be a multiple of block size\n"); - exit(2); - } - if (*segment_bytes % *width) { - fprintf(stderr, "lafs.mkfs: segment size must be a multiple of width\n"); - exit(2); - } - if (*segment_bytes > *stride_bytes && - (*segment_bytes % *stride_bytes)) { - fprintf(stderr, "lafs.mkfs: segment size must be a multiple of stride size\n"); - exit(2); - } - if (*segment_bytes < *stride_bytes && - (*stride_bytes % *segment_bytes)) { - fprintf(stderr, "lafs.mkfs: segment size must be a divisor of stride size\n"); - exit(2); - } -} - int open_device(char *devname, long long *device_bytes, int regular_file) { /* must be able to get an exclusive open on the device and its size @@ -313,6 +221,7 @@ int main(int argc, char *argv[]) int regular_file = 0; int opt; int dev_fd; + char *error; struct lafs *lafs; struct lafs_device *dev; struct lafs_ino *ifile, *imfile, *rootdir, *orphans, *segmap; @@ -377,8 +286,14 @@ int main(int argc, char *argv[]) dev_fd = open_device(devname, &device_bytes, regular_file); /* Validate parameters */ - validate_parameters(&block_bytes, &segment_bytes, &stride_bytes, &width, - device_bytes); + error = lafs_validate_geometry(&block_bytes, &segment_bytes, + &stride_bytes, &width, + device_bytes); + if (error) { + fprintf(stderr, "mkfs.lafs: %s\n", error); + free(error); + exit(2); + } /* Create filesystem handle */ lafs = lafs_alloc();