diff --git a/man/mkfs.btrfs.8.in b/man/mkfs.btrfs.8.in index 25e817b3..fc2e1d2e 100644 --- a/man/mkfs.btrfs.8.in +++ b/man/mkfs.btrfs.8.in @@ -63,6 +63,9 @@ Specify the sectorsize, the minimum block allocation. \fB\-r\fR, \fB\-\-rootdir \fIrootdir\fR Specify a directory to copy into the newly created fs. .TP +\fB\-T\fR, \fB\-\-nodiscard \fR +Do not perform whole device TRIM operation by default. +.TP \fB\-V\fR, \fB\-\-version\fR Print the \fBmkfs.btrfs\fP version and exit. .SH AVAILABILITY diff --git a/mkfs.c b/mkfs.c index c44c7e6f..dff5eb8d 100644 --- a/mkfs.c +++ b/mkfs.c @@ -348,6 +348,7 @@ static void print_usage(void) fprintf(stderr, "\t -n --nodesize size of btree nodes\n"); fprintf(stderr, "\t -s --sectorsize min block allocation\n"); fprintf(stderr, "\t -r --rootdir the source directory\n"); + fprintf(stderr, "\t -T --nodiscard do not perform whole device TRIM\n"); fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION); exit(1); } @@ -409,6 +410,7 @@ static struct option long_options[] = { { "data", 1, NULL, 'd' }, { "version", 0, NULL, 'V' }, { "rootdir", 1, NULL, 'r' }, + { "nodiscard", 0, NULL, 'T' }, { 0, 0, 0, 0} }; @@ -1224,6 +1226,7 @@ int main(int ac, char **av) int mixed = 0; int data_profile_opt = 0; int metadata_profile_opt = 0; + int nodiscard = 0; char *source_dir = NULL; int source_dir_set = 0; @@ -1234,7 +1237,7 @@ int main(int ac, char **av) while(1) { int c; - c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:r:VM", long_options, + c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:r:VMT", long_options, &option_index); if (c < 0) break; @@ -1280,6 +1283,9 @@ int main(int ac, char **av) source_dir = optarg; source_dir_set = 1; break; + case 'T': + nodiscard=1; + break; default: print_usage(); } @@ -1318,7 +1324,8 @@ int main(int ac, char **av) exit(1); } first_file = file; - ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count, &mixed); + ret = __btrfs_prepare_device(fd, file, zero_end, + &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; else if (block_count > dev_block_count) { @@ -1416,8 +1423,8 @@ int main(int ac, char **av) continue; } dev_block_count = block_count; - ret = btrfs_prepare_device(fd, file, zero_end, - &dev_block_count, &mixed); + ret = __btrfs_prepare_device(fd, file, zero_end, + &dev_block_count, &mixed, nodiscard); mixed = old_mixed; BUG_ON(ret); diff --git a/utils.c b/utils.c index 58330308..aade9e2c 100644 --- a/utils.c +++ b/utils.c @@ -538,6 +538,12 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, int *mixed) +{ + /* discard by default when called from 'device add' */ + return __btrfs_prepare_device(fd, file, zero_end, block_count_ret, mixed, 0); +} +int __btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, + int *mixed, int nodiscard) { u64 block_count; u64 bytenr; @@ -564,11 +570,13 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, *mixed = 1; } - /* - * We intentionally ignore errors from the discard ioctl. It is - * not necessary for the mkfs functionality but just an optimization. - */ - discard_blocks(fd, 0, block_count); + if (!nodiscard) { + /* + * We intentionally ignore errors from the discard ioctl. It is + * not necessary for the mkfs functionality but just an optimization. + */ + discard_blocks(fd, 0, block_count); + } ret = zero_dev_start(fd); if (ret) { diff --git a/utils.h b/utils.h index c5f55e15..c147c12b 100644 --- a/utils.h +++ b/utils.h @@ -28,6 +28,8 @@ 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, int *mixed); +int __btrfs_prepare_device(int fd, char *file, int zero_end, + u64 *block_count_ret, int *mixed, int nodiscard); 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,