mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-24 23:22:27 +00:00
btrfs-progs: require mkfs -f force option to overwrite filesystem or partition table
The core of this is shamelessly stolen from xfsprogs. Use blkid to detect an existing filesystem or partition table on any of the target devices. If something is found, require the '-f' option to overwrite it, hopefully avoiding disaster due to mistyped devicenames, etc. # mkfs.btrfs /dev/sda1 WARNING! - Btrfs v0.20-rc1-59-gd00279c-dirty IS EXPERIMENTAL WARNING! - see http://btrfs.wiki.kernel.org before using /dev/sda1 appears to contain an existing filesystem (xfs). Use the -f option to force overwrite. # This does introduce a requirement on libblkid. Signed-off-by: Eric Sandeen <sandeen@redhat.com>
This commit is contained in:
parent
3b85739dd6
commit
2a2d8e1962
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
|||||||
INSTALL = install
|
INSTALL = install
|
||||||
prefix ?= /usr/local
|
prefix ?= /usr/local
|
||||||
bindir = $(prefix)/bin
|
bindir = $(prefix)/bin
|
||||||
LIBS=-luuid -lm -lz
|
LIBS=-luuid -lblkid -lm -lz
|
||||||
|
|
||||||
ifeq ("$(origin V)", "command line")
|
ifeq ("$(origin V)", "command line")
|
||||||
BUILD_VERBOSE = $(V)
|
BUILD_VERBOSE = $(V)
|
||||||
|
@ -6,6 +6,7 @@ mkfs.btrfs \- create a btrfs filesystem
|
|||||||
[ \fB\-A\fP\fI alloc-start\fP ]
|
[ \fB\-A\fP\fI alloc-start\fP ]
|
||||||
[ \fB\-b\fP\fI byte-count\fP ]
|
[ \fB\-b\fP\fI byte-count\fP ]
|
||||||
[ \fB\-d\fP\fI data-profile\fP ]
|
[ \fB\-d\fP\fI data-profile\fP ]
|
||||||
|
[ \fB\-f\fP\fI ]
|
||||||
[ \fB\-l\fP\fI leafsize\fP ]
|
[ \fB\-l\fP\fI leafsize\fP ]
|
||||||
[ \fB\-L\fP\fI label\fP ]
|
[ \fB\-L\fP\fI label\fP ]
|
||||||
[ \fB\-m\fP\fI metadata profile\fP ]
|
[ \fB\-m\fP\fI metadata profile\fP ]
|
||||||
@ -38,6 +39,11 @@ mkfs.btrfs uses all the available storage for the filesystem.
|
|||||||
Specify how the data must be spanned across the devices specified. Valid
|
Specify how the data must be spanned across the devices specified. Valid
|
||||||
values are raid0, raid1, raid10 or single.
|
values are raid0, raid1, raid10 or single.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-f\fR
|
||||||
|
Force overwrite when an existing filesystem is detected on the device.
|
||||||
|
By default, mkfs.btrfs will not write to the device if it suspects that
|
||||||
|
there is a filesystem or partition table on the device already.
|
||||||
|
.TP
|
||||||
\fB\-l\fR, \fB\-\-leafsize \fIsize\fR
|
\fB\-l\fR, \fB\-\-leafsize \fIsize\fR
|
||||||
Specify the leaf size, the least data item in which btrfs stores data. The
|
Specify the leaf size, the least data item in which btrfs stores data. The
|
||||||
default value is the page size.
|
default value is the page size.
|
||||||
|
100
mkfs.c
100
mkfs.c
@ -41,7 +41,6 @@
|
|||||||
#include <attr/xattr.h>
|
#include <attr/xattr.h>
|
||||||
#include <blkid/blkid.h>
|
#include <blkid/blkid.h>
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include "kerncompat.h"
|
|
||||||
#include "ctree.h"
|
#include "ctree.h"
|
||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
#include "volumes.h"
|
#include "volumes.h"
|
||||||
@ -1260,6 +1259,86 @@ static int is_ssd(const char *file)
|
|||||||
return !atoi((const char *)&rotational);
|
return !atoi((const char *)&rotational);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for existing filesystem or partition table on device.
|
||||||
|
* Returns:
|
||||||
|
* 1 for existing fs or partition
|
||||||
|
* 0 for nothing found
|
||||||
|
* -1 for internal error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
check_overwrite(
|
||||||
|
char *device)
|
||||||
|
{
|
||||||
|
const char *type;
|
||||||
|
blkid_probe pr = NULL;
|
||||||
|
int ret;
|
||||||
|
blkid_loff_t size;
|
||||||
|
|
||||||
|
if (!device || !*device)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = -1; /* will reset on success of all setup calls */
|
||||||
|
|
||||||
|
pr = blkid_new_probe_from_filename(device);
|
||||||
|
if (!pr)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
size = blkid_probe_get_size(pr);
|
||||||
|
if (size < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* nothing to overwrite on a 0-length device */
|
||||||
|
if (size == 0) {
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = blkid_probe_enable_partitions(pr, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = blkid_do_fullprobe(pr);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blkid returns 1 for nothing found and 0 when it finds a signature,
|
||||||
|
* but we want the exact opposite, so reverse the return value here.
|
||||||
|
*
|
||||||
|
* In addition print some useful diagnostics about what actually is
|
||||||
|
* on the device.
|
||||||
|
*/
|
||||||
|
if (ret) {
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s appears to contain an existing "
|
||||||
|
"filesystem (%s).\n", device, type);
|
||||||
|
} else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s appears to contain a partition "
|
||||||
|
"table (%s).\n", device, type);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s appears to contain something weird "
|
||||||
|
"according to blkid\n", device);
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (pr)
|
||||||
|
blkid_free_probe(pr);
|
||||||
|
if (ret == -1)
|
||||||
|
fprintf(stderr,
|
||||||
|
"probe of %s failed, cannot detect "
|
||||||
|
"existing filesystem.\n", device);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
char *file;
|
char *file;
|
||||||
@ -1287,6 +1366,7 @@ int main(int ac, char **av)
|
|||||||
int metadata_profile_opt = 0;
|
int metadata_profile_opt = 0;
|
||||||
int nodiscard = 0;
|
int nodiscard = 0;
|
||||||
int ssd = 0;
|
int ssd = 0;
|
||||||
|
int force_overwrite = 0;
|
||||||
|
|
||||||
char *source_dir = NULL;
|
char *source_dir = NULL;
|
||||||
int source_dir_set = 0;
|
int source_dir_set = 0;
|
||||||
@ -1299,7 +1379,7 @@ int main(int ac, char **av)
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
int c;
|
int c;
|
||||||
c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:r:VMK", long_options,
|
c = getopt_long(ac, av, "A:b:fl:n:s:m:d:L:r:VMK", long_options,
|
||||||
&option_index);
|
&option_index);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
break;
|
break;
|
||||||
@ -1307,6 +1387,9 @@ int main(int ac, char **av)
|
|||||||
case 'A':
|
case 'A':
|
||||||
alloc_start = parse_size(optarg);
|
alloc_start = parse_size(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
force_overwrite = 1;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
data_profile = parse_profile(optarg);
|
data_profile = parse_profile(optarg);
|
||||||
data_profile_opt = 1;
|
data_profile_opt = 1;
|
||||||
@ -1376,6 +1459,12 @@ int main(int ac, char **av)
|
|||||||
fprintf(stderr, "%s is a swap device\n", file);
|
fprintf(stderr, "%s is a swap device\n", file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (!force_overwrite) {
|
||||||
|
if (check_overwrite(file)) {
|
||||||
|
fprintf(stderr, "Use the -f option to force overwrite.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = check_mounted(file);
|
ret = check_mounted(file);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "error checking %s mount status\n", file);
|
fprintf(stderr, "error checking %s mount status\n", file);
|
||||||
@ -1485,6 +1574,13 @@ int main(int ac, char **av)
|
|||||||
int old_mixed = mixed;
|
int old_mixed = mixed;
|
||||||
|
|
||||||
file = av[optind++];
|
file = av[optind++];
|
||||||
|
if (!force_overwrite) {
|
||||||
|
if (check_overwrite(file)) {
|
||||||
|
fprintf(stderr, "Use the -f option to force overwrite.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = is_swap_device(file);
|
ret = is_swap_device(file);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "error checking %s status: %s\n", file,
|
fprintf(stderr, "error checking %s status: %s\n", file,
|
||||||
|
Loading…
Reference in New Issue
Block a user