summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandan Rajendra <chandan@linux.vnet.ibm.com>2015-10-14 23:09:37 +0530
committerDavid Sterba <dsterba@suse.com>2015-11-02 09:35:04 +0100
commitc11e36a29e84b7dc142f4dad8d02902f4f7ae158 (patch)
tree08877d380af1bfc58d3c4678a69c7fc3529e2f1e
parentcd12def348a1d55fdc1c680f3ed9c393f77ab407 (diff)
Btrfs-progs: Do not force mixed block group creation unless '-M' option is specified
When creating small Btrfs filesystem instances (i.e. filesystem size <= 1GiB), mkfs.btrfs fails if both sectorsize and nodesize are specified on the command line and sectorsize != nodesize, since mixed block groups involves both data and metadata blocks sharing the same block group. This is an incorrect behavior when '-M' option isn't specified on the command line. This commit makes optional the creation of mixed block groups i.e. Mixed block groups are created only when -M option is specified on the command line. Since we now allow small filesystem instances with sectorsize != nodesize to be created, we can end up in the following situation, [root@localhost ~]# mkfs.btrfs -f -n 65536 /dev/loop0 btrfs-progs v3.19-rc2-405-g976307c See http://btrfs.wiki.kernel.org for more information. Performing full device TRIM (512.00MiB) ... Label: (null) UUID: 49fab72e-0c8b-466b-a3ca-d1bfe56475f0 Node size: 65536 Sector size: 4096 Filesystem size: 512.00MiB Block group profiles: Data: single 8.00MiB Metadata: DUP 40.00MiB System: DUP 12.00MiB SSD detected: no Incompat features: extref, skinny-metadata Number of devices: 1 Devices: ID SIZE PATH 1 512.00MiB /dev/loop0 [root@localhost ~]# mount /dev/loop0 /mnt/ mount: mount /dev/loop0 on /mnt failed: No space left on device The ENOSPC occurs during the creation of the UUID tree. This is because of things like large metadata block size, DUP mode used for metadata and global reservation consuming space. Also, large nodesize does not make sense on small filesystems, hence this should not be an issue. Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--Documentation/mkfs.btrfs.asciidoc35
-rw-r--r--cmds-device.c3
-rw-r--r--cmds-replace.c3
-rw-r--r--mkfs.c20
-rw-r--r--utils.c5
-rw-r--r--utils.h2
6 files changed, 45 insertions, 23 deletions
diff --git a/Documentation/mkfs.btrfs.asciidoc b/Documentation/mkfs.btrfs.asciidoc
index a9aa3cb4..5789762a 100644
--- a/Documentation/mkfs.btrfs.asciidoc
+++ b/Documentation/mkfs.btrfs.asciidoc
@@ -133,9 +133,42 @@ UNIT
As default the unit is the byte, however it is possible to append a suffix
to the arguments like 'k' for KBytes, 'm' for MBytes...
+NOTES
+-----
+Since mixed block group creation is optional, we allow small
+filesystem instances with differing values for sectorsize and nodesize
+to be created and could end up in the following situation,
+
+ [root@localhost ~]# mkfs.btrfs -f -n 65536 /dev/loop0
+ btrfs-progs v3.19-rc2-405-g976307c
+ See http://btrfs.wiki.kernel.org for more information.
+
+ Performing full device TRIM (512.00MiB) ...
+ Label: (null)
+ UUID: 49fab72e-0c8b-466b-a3ca-d1bfe56475f0
+ Node size: 65536
+ Sector size: 4096
+ Filesystem size: 512.00MiB
+ Block group profiles:
+ Data: single 8.00MiB
+ Metadata: DUP 40.00MiB
+ System: DUP 12.00MiB
+ SSD detected: no
+ Incompat features: extref, skinny-metadata
+ Number of devices: 1
+ Devices:
+ ID SIZE PATH
+ 1 512.00MiB /dev/loop0
+ [root@localhost ~]# mount /dev/loop0 /mnt/
+ mount: mount /dev/loop0 on /mnt failed: No space left on device
+
+The ENOSPC occurs during the creation of the UUID tree. This is
+because of things like large metadata block size, DUP mode used for
+metadata and global reservation consuming space.
+
AVAILABILITY
------------
-*btrfs* is part of btrfs-progs.
+*mkfs.btrfs* is part of btrfs-progs.
Please refer to the btrfs wiki http://btrfs.wiki.kernel.org for
further details.
diff --git a/cmds-device.c b/cmds-device.c
index 37fd284a..e461aa12 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -92,7 +92,6 @@ static int cmd_device_add(int argc, char **argv)
struct btrfs_ioctl_vol_args ioctl_args;
int devfd, res;
u64 dev_block_count = 0;
- int mixed = 0;
char *path;
res = test_dev_for_mkfs(argv[i], force);
@@ -109,7 +108,7 @@ static int cmd_device_add(int argc, char **argv)
}
res = btrfs_prepare_device(devfd, argv[i], 1, &dev_block_count,
- 0, &mixed, discard);
+ 0, discard);
close(devfd);
if (res) {
ret++;
diff --git a/cmds-replace.c b/cmds-replace.c
index 375a4608..4e0e9472 100644
--- a/cmds-replace.c
+++ b/cmds-replace.c
@@ -129,7 +129,6 @@ static int cmd_replace_start(int argc, char **argv)
int force_using_targetdev = 0;
u64 dstdev_block_count;
int do_not_background = 0;
- int mixed = 0;
DIR *dirstream = NULL;
u64 srcdev_size;
u64 dstdev_size;
@@ -261,7 +260,7 @@ static int cmd_replace_start(int argc, char **argv)
strncpy((char *)start_args.start.tgtdev_name, dstdev,
BTRFS_DEVICE_PATH_NAME_MAX);
ret = btrfs_prepare_device(fddstdev, dstdev, 1, &dstdev_block_count, 0,
- &mixed, 0);
+ 0);
if (ret)
goto leave_with_error;
diff --git a/mkfs.c b/mkfs.c
index ecd6fbf8..5940abd9 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -152,7 +152,7 @@ err:
}
static int make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root,
- int mixed, struct mkfs_allocation *allocation)
+ struct mkfs_allocation *allocation)
{
struct btrfs_key location;
int ret;
@@ -1439,8 +1439,6 @@ int main(int ac, char **av)
break;
case 'b':
block_count = parse_size(optarg);
- if (block_count <= BTRFS_MKFS_SMALL_VOLUME_SIZE)
- mixed = 1;
zero_end = 0;
break;
case 'V':
@@ -1490,7 +1488,7 @@ int main(int ac, char **av)
exit(1);
}
}
-
+
while (dev_cnt-- > 0) {
file = av[optind++];
if (is_block_device(file) == 1)
@@ -1504,10 +1502,9 @@ int main(int ac, char **av)
file = av[optind++];
ssd = is_ssd(file);
- if (is_vol_small(file) || mixed) {
+ if (mixed) {
if (verbose)
- printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
- mixed = 1;
+ printf("Forcing mixed metadata/data groups\n");
}
/*
@@ -1603,7 +1600,7 @@ int main(int ac, char **av)
exit(1);
}
ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count,
- block_count, &mixed, discard);
+ block_count, discard);
if (ret) {
close(fd);
exit(1);
@@ -1703,7 +1700,7 @@ int main(int ac, char **av)
exit(1);
}
- ret = make_root_dir(trans, root, mixed, &allocation);
+ ret = make_root_dir(trans, root, &allocation);
if (ret) {
fprintf(stderr, "failed to setup the root directory\n");
exit(1);
@@ -1724,8 +1721,6 @@ int main(int ac, char **av)
goto raid_groups;
while (dev_cnt-- > 0) {
- int old_mixed = mixed;
-
file = av[optind++];
/*
@@ -1748,12 +1743,11 @@ int main(int ac, char **av)
continue;
}
ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count,
- block_count, &mixed, discard);
+ block_count, discard);
if (ret) {
close(fd);
exit(1);
}
- mixed = old_mixed;
ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
sectorsize, sectorsize, sectorsize);
diff --git a/utils.c b/utils.c
index 39ca9275..7ac62f40 100644
--- a/utils.c
+++ b/utils.c
@@ -847,7 +847,7 @@ out:
}
int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
- u64 max_block_count, int *mixed, int discard)
+ u64 max_block_count, int discard)
{
u64 block_count;
struct stat st;
@@ -867,9 +867,6 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
if (max_block_count)
block_count = min(block_count, max_block_count);
- if (block_count < BTRFS_MKFS_SMALL_VOLUME_SIZE && !(*mixed))
- *mixed = 1;
-
if (discard) {
/*
* We intentionally ignore errors from the discard ioctl. It
diff --git a/utils.h b/utils.h
index 9961ec70..33b410cf 100644
--- a/utils.h
+++ b/utils.h
@@ -121,7 +121,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg);
int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid);
int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
- u64 max_block_count, int *mixed, int discard);
+ u64 max_block_count, int discard);
int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int fd, char *path,
u64 block_count, u32 io_width, u32 io_align,