Signed-off-by: Hugo Mills <h...@carfax.org.uk>
---
 cmds-filesystem.c |  173 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 152 insertions(+), 21 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 2210020..3150ff7 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <uuid/uuid.h>
@@ -39,11 +40,129 @@ static const char * const filesystem_cmd_group_usage[] = {
 };
 
 static const char * const cmd_df_usage[] = {
-       "btrfs filesystem df <path>",
+       "btrfs filesystem df [options] <path>",
        "Show space usage information for a mount point",
+       "",
+       "-r      Use old-style RAID-n terminology",
+       "-e      Explain new-style NcMsPp terminology",
        NULL
 };
 
+static const char *cmd_df_short_options = "re";
+static const struct option cmd_df_options[] = {
+       { "raid",    no_argument, NULL, 'r' },
+       { "explain", no_argument, NULL, 'e' },
+       { NULL, 0, NULL, 0 }
+};
+
+#define RAID_NAMES_NEW 0
+#define RAID_NAMES_OLD 1
+#define RAID_NAMES_LONG 2
+
+static int write_raid_name(char* buffer, int size, u64 flags, int raid_format)
+{
+       int copies, stripes, parity;
+       int out;
+       int written = 0;
+
+       if (raid_format == RAID_NAMES_OLD) {
+               if (flags & BTRFS_BLOCK_GROUP_RAID0) {
+                       return snprintf(buffer, size, "%s", "RAID0");
+               } else if (flags & BTRFS_BLOCK_GROUP_RAID1) {
+                       return snprintf(buffer, size, "%s", "RAID1");
+               } else if (flags & BTRFS_BLOCK_GROUP_DUP) {
+                       return snprintf(buffer, size, "%s", "DUP");
+               } else if (flags & BTRFS_BLOCK_GROUP_RAID10) {
+                       return snprintf(buffer, size, "%s", "RAID10");
+               } else if (flags & BTRFS_BLOCK_GROUP_RAID5) {
+                       return snprintf(buffer, size, "%s", "RAID5");
+               } else if (flags & BTRFS_BLOCK_GROUP_RAID6) {
+                       return snprintf(buffer, size, "%s", "RAID6");
+               }
+               return 0;
+       }
+
+       if (flags & (BTRFS_BLOCK_GROUP_RAID1
+                                | BTRFS_BLOCK_GROUP_RAID10
+                                | BTRFS_BLOCK_GROUP_DUP)) {
+               copies = 2;
+       } else {
+               copies = 1;
+       }
+
+       if (raid_format == RAID_NAMES_LONG)
+               out = snprintf(buffer, size, "%d copies", copies);
+       else
+               out = snprintf(buffer, size, "%dc", copies);
+       if (size < out)
+               return written + size;
+       written += out;
+       size -= out;
+
+       if (flags & BTRFS_BLOCK_GROUP_DUP) {
+               if (raid_format == RAID_NAMES_LONG)
+                       out = snprintf(buffer+written, size, " low redundancy");
+               else
+                       out = snprintf(buffer+written, size, "d");
+               if (size < out)
+                       return written + size;
+               written += out;
+               size -= out;
+       }
+
+       if (flags & (BTRFS_BLOCK_GROUP_RAID0
+                                | BTRFS_BLOCK_GROUP_RAID10
+                                | BTRFS_BLOCK_GROUP_RAID5
+                                | BTRFS_BLOCK_GROUP_RAID6)) {
+               stripes = -1;
+       } else {
+               stripes = 0;
+       }
+
+       if (stripes == -1) {
+               if (raid_format == RAID_NAMES_LONG)
+                       out = snprintf(buffer+written, size, ", fit stripes");
+               else
+                       out = snprintf(buffer+written, size, "Xs");
+       } else if (stripes == 0) {
+               out = 0;
+       } else {
+               if (raid_format == RAID_NAMES_LONG)
+                       out = snprintf(buffer+written, size, ", %d stripes", 
stripes);
+               else
+                       out = snprintf(buffer+written, size, "%ds", stripes);
+       }
+
+       if (size < out)
+               return written + size;
+       written += out;
+       size -= out;
+
+       if (flags & BTRFS_BLOCK_GROUP_RAID5) {
+               parity = 1;
+       } else if (flags & BTRFS_BLOCK_GROUP_RAID6) {
+               parity = 2;
+       } else {
+               parity = 0;
+       }
+
+       if (parity == 0) {
+               out = 0;
+       } else {
+               if (raid_format == RAID_NAMES_LONG)
+                       out = snprintf(buffer+written, size, ", %d parity", 
parity);
+               else
+                       out = snprintf(buffer+written, size, "%dp", parity);
+       }
+
+       if (size < out)
+               return written + size;
+       written += out;
+       size -= out;
+
+       return written;
+}
+
 static int cmd_df(int argc, char **argv)
 {
        struct btrfs_ioctl_space_args *sargs, *sargs_orig;
@@ -52,11 +171,32 @@ static int cmd_df(int argc, char **argv)
        int fd;
        int e;
        char *path;
+       int raid_format = RAID_NAMES_NEW;
+
+       while (1) {
+               int option_index = 0;
+               int c = getopt_long(argc, argv,
+                                                       cmd_df_short_options, 
cmd_df_options,
+                                                       &option_index);
+               if (c == -1)
+                       break;
 
-       if (check_argc_exact(argc, 2))
+               switch (c) {
+               case 'r':
+                       raid_format = RAID_NAMES_OLD;
+                       break;
+               case 'e':
+                       raid_format = RAID_NAMES_LONG;
+                       break;
+               default:
+                       usage(cmd_df_usage);
+               }
+       }
+
+       if (check_argc_exact(argc - optind, 1))
                usage(cmd_df_usage);
 
-       path = argv[1];
+       path = argv[optind];
 
        fd = open_file_or_dir(path);
        if (fd < 0) {
@@ -135,24 +275,15 @@ static int cmd_df(int argc, char **argv)
                        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;
-               } else if (flags & BTRFS_BLOCK_GROUP_RAID5) {
-                       snprintf(description+written, 9, "%s", ", RAID5");
-                       written += 7;
-               } else if (flags & BTRFS_BLOCK_GROUP_RAID6) {
-                       snprintf(description+written, 9, "%s", ", RAID6");
-                       written += 7;
+               if ((flags & ~(BTRFS_BLOCK_GROUP_DATA
+                                          | BTRFS_BLOCK_GROUP_SYSTEM
+                                          | BTRFS_BLOCK_GROUP_METADATA)) != 0) 
{
+                       snprintf(description+written, 3, ", ");
+                       written += 2;
+                       written += write_raid_name(description+written,
+                                                                          
sizeof(description)-written,
+                                                                          
flags,
+                                                                          
raid_format);
                }
 
                total_bytes = pretty_sizes(sargs->spaces[i].total_bytes);
-- 
1.7.10.4

--
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

Reply via email to