diff options
-rw-r--r-- | btrfs.c | 4 | ||||
-rw-r--r-- | btrfs_cmds.c | 88 | ||||
-rw-r--r-- | btrfs_cmds.h | 1 | ||||
-rw-r--r-- | ioctl.h | 14 |
4 files changed, 107 insertions, 0 deletions
@@ -83,6 +83,10 @@ static struct Command commands[] = { "Show the info of a btrfs filesystem. If no <uuid> or <label>\n" "is passed, info of all the btrfs filesystem are shown." }, + { do_df_filesystem, 1, + "filesystem df", "<path>\n" + "Show space usage information for a mount point\n." + }, { do_balance, 1, "filesystem balance", "<path>\n" "Balance the chunks across the device." diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 86a79130..05134fd6 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -803,3 +803,91 @@ int do_set_default_subvol(int nargs, char **argv) return 0; } +int do_df_filesystem(int nargs, char **argv) +{ + struct btrfs_ioctl_space_args *sargs; + u64 count = 0, i; + int ret; + int fd; + char *path = argv[1]; + + fd = open_file_or_dir(path); + if (fd < 0) { + fprintf(stderr, "ERROR: can't access to '%s'\n", path); + return 12; + } + + sargs = malloc(sizeof(struct btrfs_ioctl_space_args)); + if (!sargs) + return -ENOMEM; + + sargs->space_slots = 0; + sargs->total_spaces = 0; + + ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs); + if (ret) { + free(sargs); + return ret; + } + if (!sargs->total_spaces) + return 0; + + count = sargs->total_spaces; + + sargs = realloc(sargs, sizeof(struct btrfs_ioctl_space_args) + + (count * sizeof(struct btrfs_ioctl_space_info))); + if (!sargs) + return -ENOMEM; + + sargs->space_slots = count; + sargs->total_spaces = 0; + + ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs); + if (ret) { + free(sargs); + return ret; + } + + for (i = 0; i < sargs->total_spaces; i++) { + char description[80]; + char *total_bytes; + char *used_bytes; + int written = 0; + u64 flags = sargs->spaces[i].flags; + + memset(description, 0, 80); + + if (flags & BTRFS_BLOCK_GROUP_DATA) { + snprintf(description, 5, "%s", "Data"); + written += 4; + } else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) { + snprintf(description, 7, "%s", "System"); + written += 6; + } else if (flags & BTRFS_BLOCK_GROUP_METADATA) { + snprintf(description, 9, "%s", "Metadata"); + written += 8; + } + + if (flags & BTRFS_BLOCK_GROUP_RAID0) { + snprintf(description+written, 8, "%s", ", RAID0"); + written += 7; + } else if (flags & BTRFS_BLOCK_GROUP_RAID1) { + snprintf(description+written, 8, "%s", ", RAID1"); + written += 7; + } else if (flags & BTRFS_BLOCK_GROUP_DUP) { + snprintf(description+written, 6, "%s", ", DUP"); + written += 5; + } else if (flags & BTRFS_BLOCK_GROUP_RAID10) { + snprintf(description+written, 9, "%s", ", RAID10"); + written += 8; + } + + total_bytes = pretty_sizes(sargs->spaces[i].total_bytes); + used_bytes = pretty_sizes(sargs->spaces[i].used_bytes); + printf("%s: total=%s, used=%s\n", description, total_bytes, + used_bytes); + } + free(sargs); + + return 0; +} diff --git a/btrfs_cmds.h b/btrfs_cmds.h index c63baa99..e8abd995 100644 --- a/btrfs_cmds.h +++ b/btrfs_cmds.h @@ -29,3 +29,4 @@ int do_resize(int nargs, char **argv); int do_subvol_list(int nargs, char **argv); int do_set_default_subvol(int nargs, char **argv); int list_subvols(int fd); +int do_df_filesystem(int nargs, char **argv); @@ -120,6 +120,18 @@ struct btrfs_ioctl_defrag_range_args { __u32 unused[5]; }; +struct btrfs_ioctl_space_info { + __u64 flags; + __u64 total_bytes; + __u64 used_bytes; +}; + +struct btrfs_ioctl_space_args { + __u64 space_slots; + __u64 total_spaces; + struct btrfs_ioctl_space_info spaces[0]; +}; + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -155,4 +167,6 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ struct btrfs_ioctl_ino_lookup_args) #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) +#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ + struct btrfs_ioctl_space_args) #endif |