Add online resizing ioctls

btrfsctl -r size mount_point
master
Chris Mason 2007-12-21 16:25:35 -05:00 committed by David Woodhouse
parent c4603e35d7
commit 7e03dadf20
3 changed files with 56 additions and 9 deletions

View File

@ -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) {

View File

@ -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

42
mkfs.c
View File

@ -29,6 +29,7 @@
#include <unistd.h>
#include <uuid/uuid.h>
#include <linux/fs.h>
#include <ctype.h>
#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);