-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi all and happy new year.
this is my first patch of the new year. Hooping that this is a good sign. :-) The enclosed patch try to address the problem raised by Justin: how circumvent the check performed by mkfs.btrfs ? I add a "-f|--force" switch which permits to bypass the check if a device is already mounted. I update the man page too. You can pull the change from http://cassiopea.homelinux.net/git/btrfs-progs-unstable.git branch force-mkfs commit (2900a150cde604f82f1437c931792bfa59c4780b) Comments are welcome Regards G.Baroncelli - -- gpg key: Goffredo Baroncelli (ghigo) <kreij...@inwind.it> Key fingerprint = 4769 7E51 5293 D36C 814E C054 BF04 F161 3DC5 0512 On 01/03/2011 12:14 AM, Goffredo Baroncelli wrote: > On 01/02/2011 08:52 PM, J G wrote: >> I just encountered some odd behavior from mkbtrfs. >> The end goal is to restore a backup to newly created BTRFS partitions while >> using the latest btrfs-tools. >> Here's the steps to what I did: >> * Booted SystemRescueCD >> * Partitioned the drives (two 750GB drives with 12 partitions each) >> * Created an extra partition on sda as a temporary holding place for the >> backed up files and so I can update btrfs-tools >> * Formatted/mounted/restored backup files to the temporary partition which I >> mounted on /mnt/backup >> * mount -t proc none /mnt/backup/proc; mount -o bind /dev /mnt/backup/dev >> * chroot /mnt/backup /bin/bash >> * Updated btrfs-tools to the latest git pull from today >> (v0.19-35-g1b444cd-dirty). >> * mkbtrfs /dev/sda5 /dev/sdb5 -L root >> >> mkbtrfs returned with: >> >> error checking /dev/sda5 mount status >> >> So I used strace to find out how it was checking for the mount status. Now, >> I'm no expert here, but I'm confused as to just why it failed. The last >> thing of note: >> >> lstat("/boot", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 >> lstat("/boot/sysrcd.dat", 0x7fffb29681e0) = -1 ENOENT (No such file or >> directory) >> close(3) = 0 >> munmap(0x7f11df372000, 4096) = 0 >> write(2, "error checking /dev/sda5 mount s"..., 38error checking /dev/sda5 >> mount status >> ) = 38 >> >> >> doesn't explain much. I see that it's checking /proc/mounts to see what's >> mounted, and then it fails on stating /boot/sysrcd.dat (which doesn't exist >> in the non-chrooted FS, btw). >> >> To make this even weirder, if I format sda5/sdb5 using the SysRescCD version >> of mkbtrfs (v0.19) and then format sda5/sdb5 using the chroot version, it >> works fine. >> >> Any ideas here? I would expect that mkbtrfs would work inside of a chroot >> without any assistance from the original root. >> >> I have the full strace from the chrooted mkbtrfs failing and from it >> succeeding, if that's helpful. > > On the basis of the provided information, and on the code it seems that > mkfs.btrfs tries hard to check that the user is not formatting a mounted > disk (or loop). So mkfs.btrfs scan the /proc/mount file and checks every > devices. To do the check it needs to access the original file if this is > a "loop backend". This is reasonable. > > In this case in a chroot-ed environment the loop file is not accessible. > > If you need a [dirty] "quick hack" to by-pass the problem (not tested): > - unmount the proc filesystem > - create an empty file /proc/mounts > - run btrfs.fsck > - mount the proc filesystem (removing the fake mounts file) > - perform a "btrfs device scan" > - mount the filesystem > > Of course the "right" solution is to add a "--force" switch which > permits to by-pass these checks. Other mkfs.* tools have this switch. > >>From the mkfs.ext4 man page: > [...] > -F Force mke2fs to create a filesystem, > even if the specified device is not > a partition on a block special > device, or if other parameters do > not make sense. In order to force > mke2fs to create a filesystem even > if the filesystem appears to be in > use or is mounted (a truly dangerous > thing to do), this option must be > specified twice. > > [...] > > >> >> .:Justin:. >> >> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> . >> > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > . > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFNIh34vwTxYT3FBRIRAl1tAJ9k1LVUfahdlvLvK7b4gct55fom3QCfd1Ab 0JfVbWgKf7DXd0Gg1YzaPdU= =Jt+e -----END PGP SIGNATURE-----
diff --git a/man/mkfs.btrfs.8.in b/man/mkfs.btrfs.8.in index 1e14c6c..f51291c 100644 --- a/man/mkfs.btrfs.8.in +++ b/man/mkfs.btrfs.8.in @@ -5,14 +5,14 @@ mkfs.btrfs \- create an btrfs filesystem .B mkfs.btrfs [ \fB\-A\fP\fI alloc-start\fP ] [ \fB\-b\fP\fI byte-count\fP ] -[ \fB \-d\fP\fI data-profile\fP ] -[ \fB \-l\fP\fI leafsize\fP ] -[ \fB \-L\fP\fI label\fP ] -[ \fB \-m\fP\fI metadata profile\fP ] -[ \fB \-n\fP\fI nodesize\fP ] -[ \fB \-s\fP\fI sectorsize\fP ] -[ \fB \-h\fP ] -[ \fB \-V\fP ] \fI device\fP [ \fI device ...\fP ] +[ \fB\-d\fP\fI data-profile\fP ] +[ \fB\-f\fP ] +[ \fB\-l\fP\fI leafsize\fP ] +[ \fB\-L\fP\fI label\fP ] +[ \fB\-m\fP\fI metadata profile\fP ] +[ \fB\-n\fP\fI nodesize\fP ] +[ \fB\-s\fP\fI sectorsize\fP ] +[ \fB\-V\fP ] \fIdevice\fP [ \fIdevice ...\fP ] .SH DESCRIPTION .B mkfs.btrfs is used to create an btrfs filesystem (usually in a disk partition, or an array @@ -34,6 +34,9 @@ mkfs.btrfs uses all the available storage for the filesystem. Specify how the data must be spanned across the devices specified. Valid values are raid0, raid1, raid10 or single. .TP +\fB\-f\fR, \fB\-\-force \fR +Don't check if the device is already mounted. +.TP \fB\-l\fR, \fB\-\-leafsize \fIsize\fR Specify the leaf size, the least data item in which btrfs stores data. The default value is the page size. diff --git a/mkfs.c b/mkfs.c index 2e99b95..21bcc7a 100644 --- a/mkfs.c +++ b/mkfs.c @@ -271,6 +271,7 @@ static void print_usage(void) fprintf(stderr, "\t -A --alloc-start the offset to start the FS\n"); fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n"); fprintf(stderr, "\t -d --data data profile, raid0, raid1, raid10 or single\n"); + fprintf(stderr, "\t -f --force don't check if a device is already mounted\n"); fprintf(stderr, "\t -l --leafsize size of btree leaves\n"); fprintf(stderr, "\t -L --label set a label\n"); fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n"); @@ -332,6 +333,7 @@ static struct option long_options[] = { { "sectorsize", 1, NULL, 's' }, { "data", 1, NULL, 'd' }, { "version", 0, NULL, 'V' }, + { "force", 0, NULL, 'f' }, { 0, 0, 0, 0} }; @@ -358,10 +360,11 @@ int main(int ac, char **av) int first_fd; int ret; int i; + int force=0; while(1) { int c; - c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:V", long_options, + c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:Vf", long_options, &option_index); if (c < 0) break; @@ -401,6 +404,9 @@ int main(int ac, char **av) case 'V': print_version(); break; + case 'f': + force=1; + break; default: print_usage(); } @@ -423,13 +429,16 @@ int main(int ac, char **av) file = av[optind++]; ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); + if(!force){ + if (ret < 0) { + fprintf(stderr, "error checking %s mount status\n", + file); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is mounted\n", file); + exit(1); + } } ac--; fd = open(file, O_RDWR); @@ -479,15 +488,17 @@ int main(int ac, char **av) zero_end = 1; while(ac-- > 0) { file = av[optind++]; - ret = check_mounted(file); - if (ret < 0) { - fprintf(stderr, "error checking %s mount status\n", - file); - exit(1); - } - if (ret == 1) { - fprintf(stderr, "%s is mounted\n", file); - exit(1); + if(!force){ + ret = check_mounted(file); + if (ret < 0) { + fprintf(stderr, "error checking %s" + " mount status\n",file); + exit(1); + } + if (ret == 1) { + fprintf(stderr, "%s is mounted\n", file); + exit(1); + } } fd = open(file, O_RDWR); if (fd < 0) {
mkfs.btrfs-force.diff.sig
Description: PGP signature