#include "cmds-fi-usage.h"
#include "list_sort.h"
#include "disk-io.h"
-
+#include "cmds-fi-du.h"
/*
* for btrfs fi show, we maintain a hash of fsids we've already printed.
static const char * const cmd_filesystem_df_usage[] = {
"btrfs filesystem df [options] <path>",
"Show space usage information for a mount point",
- HELPINFO_OUTPUT_UNIT_DF,
+ HELPINFO_UNITS_SHORT_LONG,
NULL
};
static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
{
u64 count = 0;
- int ret, e;
+ int ret;
struct btrfs_ioctl_space_args *sargs;
sargs = malloc(sizeof(struct btrfs_ioctl_space_args));
sargs->total_spaces = 0;
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
- e = errno;
- if (ret) {
- fprintf(stderr, "ERROR: couldn't get space info - %s\n",
- strerror(e));
+ if (ret < 0) {
+ error("cannot get space info: %s\n", strerror(errno));
free(sargs);
- return -e;
+ return -errno;
}
/* This really should never happen */
if (!sargs->total_spaces) {
sargs->space_slots = count;
sargs->total_spaces = 0;
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
- e = errno;
- if (ret) {
- fprintf(stderr, "ERROR: get space info count %llu - %s\n",
- count, strerror(e));
+ if (ret < 0) {
+ error("cannot get space info with %llu slots: %s",
+ count, strerror(errno));
free(sargs);
- return -e;
+ return -errno;
}
*sargs_ret = sargs;
return 0;
unit_mode = get_unit_mode_from_arg(&argc, argv, 1);
- if (argc != 2 || argv[1][0] == '-')
+ clean_args_no_options(argc, argv, cmd_filesystem_df_usage);
+
+ if (check_argc_exact(argc - optind, 1))
usage(cmd_filesystem_df_usage);
- path = argv[1];
+ path = argv[optind];
- fd = open_file_or_dir(path, &dirstream);
- if (fd < 0) {
- fprintf(stderr, "ERROR: can't access '%s'\n", path);
+ fd = btrfs_open_dir(path, &dirstream, 1);
+ if (fd < 0)
return 1;
- }
+
ret = get_df(fd, &sargs);
if (ret == 0) {
print_df(sargs, unit_mode);
free(sargs);
} else {
- fprintf(stderr, "ERROR: get_df failed %s\n", strerror(-ret));
+ error("get_df failed %s", strerror(-ret));
}
close_file_or_dir(fd, dirstream);
if (!strncmp(uuidbuf, search, search_len))
return 1;
- if (strlen(label) && strcmp(label, search) == 0)
+ if (*label && strcmp(label, search) == 0)
return 1;
if (strcmp(mnt, search) == 0)
static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
struct btrfs_ioctl_dev_info_args *dev_info,
struct btrfs_ioctl_space_args *space_info,
- char *label, char *path, unsigned unit_mode)
+ char *label, unsigned unit_mode)
{
int i;
int fd;
return ret;
uuid_unparse(fs_info->fsid, uuidbuf);
- if (label && strlen(label))
+ if (label && *label)
printf("Label: '%s' ", label);
else
printf("Label: none ");
goto out;
}
- if (get_label_mounted(mnt->mnt_dir, label)) {
+ /* skip all fs already shown as mounted fs */
+ if (is_seen_fsid(fs_info_arg.fsid))
+ continue;
+
+ ret = get_label_mounted(mnt->mnt_dir, label);
+ /* provide backward kernel compatibility */
+ if (ret == -ENOTTY)
+ ret = get_label_unmounted(
+ (const char *)dev_info_arg->path, label);
+
+ if (ret) {
kfree(dev_info_arg);
goto out;
}
if (search && !match_search_item_kernel(fs_info_arg.fsid,
mnt->mnt_dir, label, search)) {
kfree(dev_info_arg);
+ dev_info_arg = NULL;
continue;
}
fd = open(mnt->mnt_dir, O_RDONLY);
if ((fd != -1) && !get_df(fd, &space_info_arg)) {
print_one_fs(&fs_info_arg, dev_info_arg,
- space_info_arg, label, mnt->mnt_dir,
- unit_mode);
+ space_info_arg, label, unit_mode);
kfree(space_info_arg);
memset(label, 0, sizeof(label));
found = 1;
if (fd != -1)
close(fd);
kfree(dev_info_arg);
+ dev_info_arg = NULL;
}
out:
static int dev_to_fsid(char *dev, __u8 *fsid)
{
struct btrfs_super_block *disk_super;
- char *buf;
+ char buf[BTRFS_SUPER_INFO_SIZE];
int ret;
int fd;
- buf = malloc(4096);
- if (!buf)
- return -ENOMEM;
-
fd = open(dev, O_RDONLY);
if (fd < 0) {
ret = -errno;
- free(buf);
return ret;
}
out:
close(fd);
- free(buf);
return ret;
}
if (is_seen_fsid(cur_fs->fsid))
continue;
- fs_copy = malloc(sizeof(*fs_copy));
+ fs_copy = calloc(1, sizeof(*fs_copy));
if (!fs_copy) {
ret = -ENOMEM;
goto out;
/*
* open_ctree_* detects seed/sprout mapping
*/
- fs_info = open_ctree_fs_info(device->name, 0, 0,
+ fs_info = open_ctree_fs_info(device->name, 0, 0, 0,
OPEN_CTREE_PARTIAL);
if (!fs_info)
continue;
"Show the structure of a filesystem",
"-d|--all-devices show only disks under /dev containing btrfs filesystem",
"-m|--mounted show only mounted btrfs",
- HELPINFO_OUTPUT_UNIT,
+ HELPINFO_UNITS_LONG,
"If no argument is given, structure of all present filesystems is shown.",
NULL
};
if (argc > optind) {
search = argv[optind];
- if (strlen(search) == 0)
+ if (*search == 0)
usage(cmd_filesystem_show_usage);
type = check_arg_type(search);
} else {
ret = dev_to_fsid(search, fsid);
if (ret) {
- fprintf(stderr,
- "ERROR: No btrfs on %s\n",
- search);
+ error("no btrfs on %s", search);
return 1;
}
uuid_unparse(fsid, uuid_buf);
ret = btrfs_scan_lblkid();
if (ret) {
- fprintf(stderr, "ERROR: %d while scanning\n", ret);
+ error("blkid device scan returned %d\n", ret);
return 1;
}
ret = search_umounted_fs_uuids(&all_uuids, search, &found);
if (ret < 0) {
- fprintf(stderr,
- "ERROR: %d while searching target device\n", ret);
+ error("searching target device returned error %d", ret);
return 1;
}
*/
ret = map_seed_devices(&all_uuids);
if (ret) {
- fprintf(stderr,
- "ERROR: %d while mapping seed devices\n", ret);
+ error("mapping seed devices returned error %d", ret);
return 1;
}
free_fs_devices(fs_devices);
}
out:
- printf("%s\n", PACKAGE_STRING);
free_seen_fsid();
return ret;
}
char *path;
DIR *dirstream = NULL;
- if (check_argc_exact(argc, 2))
+ clean_args_no_options(argc, argv, cmd_filesystem_sync_usage);
+
+ if (check_argc_exact(argc - optind, 1))
usage(cmd_filesystem_sync_usage);
- path = argv[1];
+ path = argv[optind];
- fd = open_file_or_dir(path, &dirstream);
- if (fd < 0) {
- fprintf(stderr, "ERROR: can't access '%s'\n", path);
+ fd = btrfs_open_dir(path, &dirstream, 1);
+ if (fd < 0)
return 1;
- }
printf("FSSync '%s'\n", path);
res = ioctl(fd, BTRFS_IOC_SYNC);
e = errno;
close_file_or_dir(fd, dirstream);
if( res < 0 ){
- fprintf(stderr, "ERROR: unable to fs-syncing '%s' - %s\n",
- path, strerror(e));
+ error("sync ioctl failed on '%s': %s", path, strerror(e));
return 1;
}
else if (strcmp(optarg, "lzo") == 0)
return BTRFS_COMPRESS_LZO;
else {
- fprintf(stderr, "Unknown compress type %s\n", s);
+ error("unknown compression type %s", s);
exit(1);
};
}
if (defrag_global_verbose)
printf("%s\n", fpath);
fd = open(fpath, O_RDWR);
- e = errno;
if (fd < 0)
goto error;
ret = do_defrag(fd, defrag_global_fancy_ioctl, &defrag_global_range);
e = errno;
close(fd);
if (ret && e == ENOTTY && defrag_global_fancy_ioctl) {
- fprintf(stderr, "ERROR: defrag range ioctl not "
+ error("defrag range ioctl not "
"supported in this kernel, please try "
- "without any options.\n");
+ "without any options.");
defrag_global_errors++;
return ENOTTY;
}
return 0;
error:
- fprintf(stderr, "ERROR: defrag failed on %s - %s\n", fpath, strerror(e));
+ error("defrag failed on %s: %s", fpath, strerror(e));
defrag_global_errors++;
return 0;
}
case 't':
thresh = parse_size(optarg);
if (thresh > (u32)-1) {
- fprintf(stderr,
- "WARNING: target extent size %llu too big, trimmed to %u\n",
+ warning(
+ "target extent size %llu too big, trimmed to %u",
thresh, (u32)-1);
thresh = (u32)-1;
}
dirstream = NULL;
fd = open_file_or_dir(argv[i], &dirstream);
if (fd < 0) {
- fprintf(stderr, "ERROR: failed to open %s - %s\n", argv[i],
+ error("cannot open %s: %s\n", argv[i],
strerror(errno));
defrag_global_errors++;
close_file_or_dir(fd, dirstream);
continue;
}
if (fstat(fd, &st)) {
- fprintf(stderr, "ERROR: failed to stat %s - %s\n",
+ error("failed to stat %s: %s",
argv[i], strerror(errno));
defrag_global_errors++;
close_file_or_dir(fd, dirstream);
continue;
}
if (!(S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
- fprintf(stderr,
- "ERROR: %s is not a directory or a regular file\n",
- argv[i]);
+ error("%s is not a directory or a regular file\n",
+ argv[i]);
defrag_global_errors++;
close_file_or_dir(fd, dirstream);
continue;
}
close_file_or_dir(fd, dirstream);
if (ret && e == ENOTTY && defrag_global_fancy_ioctl) {
- fprintf(stderr, "ERROR: defrag range ioctl not "
+ error("defrag range ioctl not "
"supported in this kernel, please try "
- "without any options.\n");
+ "without any options.");
defrag_global_errors++;
break;
}
if (ret) {
- fprintf(stderr, "ERROR: defrag failed on %s - %s\n",
- argv[i], strerror(e));
+ error("defrag failed on %s: %s", argv[i], strerror(e));
defrag_global_errors++;
}
}
- if (defrag_global_verbose)
- printf("%s\n", PACKAGE_STRING);
if (defrag_global_errors)
fprintf(stderr, "total %d failures\n", defrag_global_errors);
DIR *dirstream = NULL;
struct stat st;
- if (check_argc_exact(argc, 3))
+ clean_args_no_options(argc, argv, cmd_filesystem_resize_usage);
+
+ if (check_argc_exact(argc - optind, 2))
usage(cmd_filesystem_resize_usage);
- amount = argv[1];
- path = argv[2];
+ amount = argv[optind];
+ path = argv[optind + 1];
len = strlen(amount);
if (len == 0 || len >= BTRFS_VOL_NAME_MAX) {
- fprintf(stderr, "ERROR: size value too long ('%s)\n",
- amount);
+ error("resize value too long (%s)", amount);
return 1;
}
res = stat(path, &st);
if (res < 0) {
- fprintf(stderr, "ERROR: resize: cannot stat %s: %s\n",
- path, strerror(errno));
+ error("resize: cannot stat %s: %s", path, strerror(errno));
return 1;
}
if (!S_ISDIR(st.st_mode)) {
- fprintf(stderr,
- "ERROR: resize works on mounted filesystems and accepts only\n"
+ error("resize works on mounted filesystems and accepts only\n"
"directories as argument. Passing file containing a btrfs image\n"
"would resize the underlying filesystem instead of the image.\n");
return 1;
}
- fd = open_file_or_dir(path, &dirstream);
- if (fd < 0) {
- fprintf(stderr, "ERROR: can't access '%s'\n", path);
+ fd = btrfs_open_dir(path, &dirstream, 1);
+ if (fd < 0)
return 1;
- }
printf("Resize '%s' of '%s'\n", path, amount);
memset(&args, 0, sizeof(args));
if( res < 0 ){
switch (e) {
case EFBIG:
- fprintf(stderr, "ERROR: unable to resize '%s' - no enouth free space\n",
+ error("unable to resize '%s': no enough free space",
path);
break;
default:
- fprintf(stderr, "ERROR: unable to resize '%s' - %s\n",
- path, strerror(e));
+ error("unable to resize '%s': %s", path, strerror(e));
break;
}
return 1;
const char *err_str = btrfs_err_str(res);
if (err_str) {
- fprintf(stderr, "ERROR: btrfs error resizing '%s' - %s\n",
- path, err_str);
+ error("resizing of '%s' failed: %s", path, err_str);
} else {
- fprintf(stderr,
- "ERROR: btrfs error resizing '%s' - unknown btrfs_err_code %d\n",
+ error("resizing of '%s' failed: unknown error %d",
path, res);
}
return 1;
static int cmd_filesystem_label(int argc, char **argv)
{
- if (check_argc_min(argc, 2) || check_argc_max(argc, 3))
+ clean_args_no_options(argc, argv, cmd_filesystem_label_usage);
+
+ if (check_argc_min(argc - optind, 2) ||
+ check_argc_max(argc - optind, 3))
usage(cmd_filesystem_label_usage);
- if (argc > 2) {
- return set_label(argv[1], argv[2]);
+ if (argc - optind > 2) {
+ return set_label(argv[optind], argv[optind + 1]);
} else {
char label[BTRFS_LABEL_SIZE];
int ret;
- ret = get_label(argv[1], label);
+ ret = get_label(argv[optind], label);
if (!ret)
fprintf(stdout, "%s\n", label);
const struct cmd_group filesystem_cmd_group = {
filesystem_cmd_group_usage, filesystem_cmd_group_info, {
{ "df", cmd_filesystem_df, cmd_filesystem_df_usage, NULL, 0 },
+ { "du", cmd_filesystem_du, cmd_filesystem_du_usage, NULL, 0 },
{ "show", cmd_filesystem_show, cmd_filesystem_show_usage, NULL,
0 },
{ "sync", cmd_filesystem_sync, cmd_filesystem_sync_usage, NULL,