forked from Mirrors/btrfs-progs
btrfs-progs: mkfs: Separate shrink from rootdir
Make --shrink a separate option for --rootdir, and change the default to off. The shrinking behaviour is not a commonly used feature but can be useful for creating minimal pre-filled images, in one step, without requiring to mount. Signed-off-by: Qu Wenruo <wqu@suse.com> [ update changelog and error messages ] Signed-off-by: David Sterba <dsterba@suse.com>master
parent
c28418daed
commit
1c9c5f7fb3
|
@ -101,6 +101,17 @@ Please see the mount option 'discard' for that in `btrfs`(5).
|
|||
*-r|--rootdir <rootdir>*::
|
||||
Populate the toplevel subvolume with files from 'rootdir'. This does not
|
||||
require root permissions and does not mount the filesystem.
|
||||
+
|
||||
NOTE: This option may enlarge the image or file to ensure it's large enough to
|
||||
contain the files from 'rootdir'.
|
||||
|
||||
*--shrink*:
|
||||
Shrink the filesystem to its minimal size, only works with *-r|--rootdir*
|
||||
option.
|
||||
+
|
||||
NOTE: If the destination is regular file, this option will also reduce the
|
||||
file size. Or it will only reduce the filesystem available space.
|
||||
Extra space will not be usable unless resized using 'btrfs filesystem resize'.
|
||||
|
||||
*-O|--features <feature1>[,<feature2>...]*::
|
||||
A list of filesystem features turned on at mkfs time. Not all features are
|
||||
|
|
27
mkfs/main.c
27
mkfs/main.c
|
@ -731,9 +731,11 @@ int main(int argc, char **argv)
|
|||
int ssd = 0;
|
||||
int force_overwrite = 0;
|
||||
char *source_dir = NULL;
|
||||
int source_dir_set = 0;
|
||||
bool source_dir_set = false;
|
||||
bool shrink_rootdir = false;
|
||||
u64 source_dir_size = 0;
|
||||
u64 min_dev_size;
|
||||
u64 shrink_size;
|
||||
int dev_cnt = 0;
|
||||
int saved_optind;
|
||||
char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 };
|
||||
|
@ -743,6 +745,7 @@ int main(int argc, char **argv)
|
|||
|
||||
while(1) {
|
||||
int c;
|
||||
enum { GETOPT_VAL_SHRINK = 257 };
|
||||
static const struct option long_options[] = {
|
||||
{ "alloc-start", required_argument, NULL, 'A'},
|
||||
{ "byte-count", required_argument, NULL, 'b' },
|
||||
|
@ -760,6 +763,7 @@ int main(int argc, char **argv)
|
|||
{ "features", required_argument, NULL, 'O' },
|
||||
{ "uuid", required_argument, NULL, 'U' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "shrink", no_argument, NULL, GETOPT_VAL_SHRINK },
|
||||
{ "help", no_argument, NULL, GETOPT_VAL_HELP },
|
||||
{ NULL, 0, NULL, 0}
|
||||
};
|
||||
|
@ -827,7 +831,7 @@ int main(int argc, char **argv)
|
|||
goto success;
|
||||
case 'r':
|
||||
source_dir = optarg;
|
||||
source_dir_set = 1;
|
||||
source_dir_set = true;
|
||||
break;
|
||||
case 'U':
|
||||
strncpy(fs_uuid, optarg,
|
||||
|
@ -839,6 +843,9 @@ int main(int argc, char **argv)
|
|||
case 'q':
|
||||
verbose = 0;
|
||||
break;
|
||||
case GETOPT_VAL_SHRINK:
|
||||
shrink_rootdir = true;
|
||||
break;
|
||||
case GETOPT_VAL_HELP:
|
||||
default:
|
||||
print_usage(c != GETOPT_VAL_HELP);
|
||||
|
@ -861,6 +868,10 @@ int main(int argc, char **argv)
|
|||
error("the option -r is limited to a single device");
|
||||
goto error;
|
||||
}
|
||||
if (shrink_rootdir && !source_dir_set) {
|
||||
error("the option --shrink must be used with --rootdir");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (*fs_uuid) {
|
||||
uuid_t dummy_uuid;
|
||||
|
@ -1189,10 +1200,14 @@ raid_groups:
|
|||
error("error wihle filling filesystem: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
ret = btrfs_mkfs_shrink_fs(fs_info, NULL);
|
||||
if (ret < 0) {
|
||||
error("error while shrinking filesystem: %d", ret);
|
||||
goto out;
|
||||
if (shrink_rootdir) {
|
||||
ret = btrfs_mkfs_shrink_fs(fs_info, &shrink_size,
|
||||
shrink_rootdir);
|
||||
if (ret < 0) {
|
||||
error("error while shrinking filesystem: %d",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -899,11 +899,13 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_mkfs_shrink_fs(struct btrfs_fs_info *fs_info, u64 *new_size_ret)
|
||||
int btrfs_mkfs_shrink_fs(struct btrfs_fs_info *fs_info, u64 *new_size_ret,
|
||||
bool shrink_file_size)
|
||||
{
|
||||
u64 new_size;
|
||||
struct btrfs_device *device;
|
||||
struct list_head *cur;
|
||||
struct stat64 file_stat;
|
||||
int nr_devs = 0;
|
||||
int ret;
|
||||
|
||||
|
@ -931,5 +933,22 @@ int btrfs_mkfs_shrink_fs(struct btrfs_fs_info *fs_info, u64 *new_size_ret)
|
|||
return ret;
|
||||
if (new_size_ret)
|
||||
*new_size_ret = new_size;
|
||||
|
||||
if (shrink_file_size) {
|
||||
ret = fstat64(device->fd, &file_stat);
|
||||
if (ret < 0) {
|
||||
error("failed to stat devid %llu: %s", device->devid,
|
||||
strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
if (!S_ISREG(file_stat.st_mode))
|
||||
return ret;
|
||||
ret = ftruncate64(device->fd, new_size);
|
||||
if (ret < 0) {
|
||||
error("failed to truncate device file of devid %llu: %s",
|
||||
device->devid, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ int btrfs_mkfs_fill_dir(const char *source_dir, struct btrfs_root *root,
|
|||
bool verbose);
|
||||
u64 btrfs_mkfs_size_dir(const char *dir_name, u32 sectorsize, u64 min_dev_size,
|
||||
u64 meta_profile, u64 data_profile);
|
||||
int btrfs_mkfs_shrink_fs(struct btrfs_fs_info *fs_info, u64 *new_size_ret);
|
||||
int btrfs_mkfs_shrink_fs(struct btrfs_fs_info *fs_info, u64 *new_size_ret,
|
||||
bool shrink_file_size);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue