btrfs-progs: inspect: add command min-dev-size
authorDavid Sterba <dsterba@suse.com>
Mon, 20 Jul 2015 15:31:43 +0000 (17:31 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 31 Aug 2015 17:25:08 +0000 (19:25 +0200)
Previously in 'filesystem resize get_min_size', now
'inspect-internal min-dev-size'. We'd like to avoid cluttering the
'resize' syntax further.

The test has been updated to exercise the new option.

Signed-off-by: David Sterba <dsterba@suse.com>
Documentation/btrfs-filesystem.asciidoc
Documentation/btrfs-inspect-internal.asciidoc
btrfs-completion
cmds-inspect.c
tests/misc-tests/004-shrink-fs/test.sh

index 2b34242..31cd51b 100644 (file)
@@ -93,7 +93,7 @@ If a newlabel optional argument is passed, the label is changed.
 NOTE: the maximum allowable length shall be less than 256 chars
 
 // Some wording are extracted by the resize2fs man page
-*resize* [<devid>:][+/-]<size>[kKmMgGtTpPeE]|[<devid>:]max|[<devid>:]get_min_size <path>::
+*resize* [<devid>:][+/-]<size>[kKmMgGtTpPeE]|[<devid>:]max <path>::
 Resize a mounted filesystem identified by directory <path>. A particular device
 can be resized by specifying a <devid>.
 +
@@ -113,8 +113,6 @@ KiB, MiB, GiB, TiB, PiB, or EiB, respectively. Case does not matter.
 +
 If \'max' is passed, the filesystem will occupy all available space on the
 device devid.
-If \'get_min_size' is passed, return the minimum size the device can be
-shrunk to, without performing any resize operation.
 +
 The resize command does not manipulate the size of underlying
 partition.  If you wish to enlarge/reduce a filesystem, you must make sure you
index 9f6ffac..f3f915b 100644 (file)
@@ -41,6 +41,15 @@ set inode container's size.
 This is used to increase inode container's size in case it is
 not enough to read all the resolved results. The max value one can set is 64k.
 
+*min-dev-size* [options] <path>::
+Return the minimum size the device can be shrunk to, without performing any
+resize operation.
++
+`Options`
++
+--id::::
+specify the device id to query, default is 1
+
 *rootid* <path>::
 For a given file or directory, return the containing tree root id. For a
 subvolume return it's own tree id.
index 884d2e8..a34191b 100644 (file)
@@ -36,7 +36,7 @@ _btrfs()
     commands_device='scan add delete remove ready stats usage'
     commands_scrub='start cancel resume status'
     commands_rescue='chunk-recover super-recover'
-    commands_inspect_internal='inode-resolve logical-resolve subvolid-resolve rootid'
+    commands_inspect_internal='inode-resolve logical-resolve subvolid-resolve rootid min-dev-size'
     commands_property='get set list'
     commands_quota='enable disable rescan'
     commands_qgroup='assign remove create destroy show limit'
index 05f1ccf..1823584 100644 (file)
 #include <stdint.h>
 #include <sys/ioctl.h>
 #include <errno.h>
+#include <getopt.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
 #include "utils.h"
 #include "ctree.h"
 #include "send-utils.h"
-
+#include "disk-io.h"
 #include "commands.h"
 #include "btrfs-list.h"
 
@@ -481,7 +482,7 @@ static void adjust_dev_min_size(struct list_head *extents,
        }
 }
 
-static int get_min_size(int fd, DIR *dirstream, u64 devid)
+static int print_min_dev_size(int fd, u64 devid)
 {
        int ret = 1;
        /*
@@ -572,13 +573,64 @@ static int get_min_size(int fd, DIR *dirstream, u64 devid)
        printf("%llu bytes (%s)\n", min_size, pretty_size(min_size));
        ret = 0;
 out:
-       close_file_or_dir(fd, dirstream);
        free_dev_extent_list(&extents);
        free_dev_extent_list(&holes);
 
        return ret;
 }
 
+static const char* const cmd_inspect_min_dev_size_usage[] = {
+       "btrfs inspect-internal min-dev-size [options] <path>",
+       "Get the minimum size the device can be shrunk to. The",
+       "device id 1 is used by default.",
+       "--id DEVID   specify the device id to query",
+       NULL
+};
+
+static int cmd_inspect_min_dev_size(int argc, char **argv)
+{
+       int ret;
+       int fd = -1;
+       DIR *dirstream = NULL;
+       u64 devid = 1;
+
+       while (1) {
+               int c;
+               enum { GETOPT_VAL_DEVID = 256 };
+               static const struct option long_options[] = {
+                       { "id", required_argument, NULL, GETOPT_VAL_DEVID },
+                       {NULL, 0, NULL, 0}
+               };
+
+               c = getopt_long(argc, argv, "", long_options, NULL);
+               if (c < 0)
+                       break;
+
+               switch (c) {
+               case GETOPT_VAL_DEVID:
+                       devid = arg_strtou64(optarg);
+                       break;
+               default:
+                       usage(cmd_inspect_min_dev_size_usage);
+               }
+       }
+       if (check_argc_exact(argc - optind, 1))
+               usage(cmd_inspect_min_dev_size_usage);
+
+       fd = open_file_or_dir(argv[optind], &dirstream);
+       if (fd < 0) {
+               fprintf(stderr, "ERROR: can't access '%s'\n", argv[optind]);
+               ret = -ENOENT;
+               goto out;
+       }
+
+       ret = print_min_dev_size(fd, devid);
+out:
+       close_file_or_dir(fd, dirstream);
+
+       return !!ret;
+}
+
 static const char inspect_cmd_group_info[] =
 "query various internal information";
 
@@ -591,6 +643,8 @@ const struct cmd_group inspect_cmd_group = {
                { "subvolid-resolve", cmd_subvolid_resolve,
                        cmd_subvolid_resolve_usage, NULL, 0 },
                { "rootid", cmd_rootid, cmd_rootid_usage, NULL, 0 },
+               { "min-dev-size", cmd_inspect_min_dev_size,
+                       cmd_inspect_min_dev_size_usage, NULL, 0 },
                NULL_CMD_STRUCT
        }
 };
index 393cccf..b132152 100755 (executable)
@@ -9,14 +9,15 @@ source $TOP/tests/common
 check_prereq mkfs.btrfs
 setup_root_helper
 
+# Optionally take id of the device to shrink
 shrink_test()
 {
-       min_size=$($SUDO_HELPER $TOP/btrfs filesystem resize get_min_size $TEST_MNT)
-       if [ $? != 0 ]; then
-               _fail "Failed to get minimum size"
-       fi
+       min_size=$(run_check_stdout $SUDO_HELPER $TOP/btrfs inspect-internal min-dev-size ${1:+--id $1} $TEST_MNT)
        min_size=$(echo $min_size | cut -d ' ' -f 1)
        echo "min size = ${min_size}" >> $RESULTS
+       if [ -z "$min_size" ]; then
+               _fail "Failed to parse minimum size"
+       fi
        run_check $SUDO_HELPER $TOP/btrfs filesystem resize $min_size $TEST_MNT
 }
 
@@ -63,7 +64,7 @@ done
 run_check $SUDO_HELPER $TOP/btrfs balance start -mconvert=single \
        -sconvert=single -f $TEST_MNT
 for ((i = 1; i <= 3; i++)); do
-       shrink_test
+       shrink_test 1
 done
 
 run_check $SUDO_HELPER umount $TEST_MNT