From 7e03dadf20f7f2f3bfac9e83cf71d4ecce60782e Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 21 Dec 2007 16:25:35 -0500 Subject: Add online resizing ioctls btrfsctl -r size mount_point --- btrfsctl.c | 21 +++++++++++++++++++-- ioctl.h | 2 ++ mkfs.c | 42 +++++++++++++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/btrfsctl.c b/btrfsctl.c index 4dfc42bd..22f253a0 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -41,7 +41,12 @@ static inline int ioctl(int fd, int define, void *arg) { return 0; } void print_usage(void) { - printf("usage: btrfsctl [ -s snapshot_name ] dir\n"); + printf("usage: btrfsctl [ -s name ] [-d] [-r size] file_or_dir\n"); + printf("\t-d filename defragments one file\n"); + printf("\t-d directory defragments the entire Btree\n"); + printf("\t-s snap_name existing_subvol creates a new snapshot\n"); + printf("\t-s snap_name tree_root creates a new subvolume\n"); + printf("\t-r [+-]size[gkm] resize the FS\n"); exit(1); } @@ -79,10 +84,22 @@ int main(int ac, char **av) command = BTRFS_IOC_SNAP_CREATE; } else if (strcmp(av[i], "-d") == 0) { if (i >= ac - 1) { - fprintf(stderr, "-d requires an arg"); + fprintf(stderr, "-d requires an arg\n"); print_usage(); } command = BTRFS_IOC_DEFRAG; + } else if (strcmp(av[i], "-r") == 0) { + if (i >= ac - 1) { + fprintf(stderr, "-r requires an arg\n"); + print_usage(); + } + name = av[i + 1]; + len = strlen(name); + if (len == 0 || len >= BTRFS_VOL_NAME_MAX) { + fprintf(stderr, "-r size too long\n"); + exit(1); + } + command = BTRFS_IOC_RESIZE; } } if (command == 0) { diff --git a/ioctl.h b/ioctl.h index 8bc47dec..8c629066 100644 --- a/ioctl.h +++ b/ioctl.h @@ -30,4 +30,6 @@ struct btrfs_ioctl_vol_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ struct btrfs_ioctl_vol_args) +#define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, \ + struct btrfs_ioctl_vol_args) #endif diff --git a/mkfs.c b/mkfs.c index b49b0884..57c54b91 100644 --- a/mkfs.c +++ b/mkfs.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "kerncompat.h" #include "ctree.h" #include "disk-io.h" @@ -39,6 +40,32 @@ static inline int ioctl(int fd, int define, u64 *size) { return 0; } #endif +static u64 parse_size(char *s) +{ + int len = strlen(s); + char c; + u64 mult = 1; + + if (!isdigit(s[len - 1])) { + c = tolower(s[len - 1]); + switch (c) { + case 'g': + mult *= 1024; + case 'm': + mult *= 1024; + case 'k': + mult *= 1024; + case 'b': + break; + default: + fprintf(stderr, "Unknown size descriptor %c\n", c); + exit(1); + } + s[len - 1] = '\0'; + } + return atol(s) * mult; +} + static int __make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid) { @@ -367,13 +394,13 @@ int main(int ac, char **av) break; switch(c) { case 'l': - leafsize = atol(optarg); + leafsize = parse_size(optarg); break; case 'n': - nodesize = atol(optarg); + nodesize = parse_size(optarg); break; case 's': - stripesize = atol(optarg); + stripesize = parse_size(optarg); break; default: print_usage(); @@ -391,7 +418,7 @@ int main(int ac, char **av) if (ac >= 1) { file = av[optind]; if (ac == 2) { - block_count = atol(av[optind + 1]); + block_count = parse_size(av[optind + 1]); if (!block_count) { fprintf(stderr, "error finding block count\n"); exit(1); @@ -416,13 +443,14 @@ int main(int ac, char **av) fprintf(stderr, "unable to find %s size\n", file); exit(1); } - block_count /= sectorsize; } - if (block_count < 256) { + block_count /= sectorsize; + block_count *= sectorsize; + + if (block_count < 256 * 1024 * 1024) { fprintf(stderr, "device %s is too small\n", file); exit(1); } - block_count = block_count * sectorsize; memset(buf, 0, sectorsize); for(i = 0; i < 64; i++) { ret = write(fd, buf, sectorsize); -- cgit v1.2.3