btrfs-progs: add discard support to mkfs
authorChristoph Hellwig <hch@lst.de>
Thu, 21 Apr 2011 20:24:07 +0000 (16:24 -0400)
committerChris Mason <chris.mason@oracle.com>
Tue, 25 Oct 2011 13:18:32 +0000 (09:18 -0400)
Discard the whole device before starting to create the filesystem structures.
Modelled after similar support in mkfs.xfs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
btrfs_cmds.c
utils.c

index 6de73f4..32f6b25 100644 (file)
@@ -732,13 +732,26 @@ int do_add_volume(int nargs, char **args)
                return 12;
        }
 
-       for(i=1 ; i < (nargs-1) ; i++ ){
+       for (i = 1; i < (nargs-1); i++ ){
                struct btrfs_ioctl_vol_args ioctl_args;
                int     devfd, res;
                u64 dev_block_count = 0;
                struct stat st;
                int mixed = 0;
 
+               res = check_mounted(args[i]);
+               if (res < 0) {
+                       fprintf(stderr, "error checking %s mount status\n",
+                               args[i]);
+                       ret++;
+                       continue;
+               }
+               if (res == 1) {
+                       fprintf(stderr, "%s is mounted\n", args[i]);
+                       ret++;
+                       continue;
+               }
+
                devfd = open(args[i], O_RDWR);
                if (!devfd) {
                        fprintf(stderr, "ERROR: Unable to open device '%s'\n", args[i]);
@@ -746,8 +759,8 @@ int do_add_volume(int nargs, char **args)
                        ret++;
                        continue;
                }
-               ret = fstat(devfd, &st);
-               if (ret) {
+               res = fstat(devfd, &st);
+               if (res) {
                        fprintf(stderr, "ERROR: Unable to stat '%s'\n", args[i]);
                        close(devfd);
                        ret++;
@@ -781,7 +794,7 @@ int do_add_volume(int nargs, char **args)
        }
 
        close(fdmnt);
-       ifret)
+       if (ret)
                return ret+20;
        else
                return 0;
diff --git a/utils.c b/utils.c
index 13373c9..17e5afe 100644 (file)
--- a/utils.c
+++ b/utils.c
 static inline int ioctl(int fd, int define, u64 *size) { return 0; }
 #endif
 
+#ifndef BLKDISCARD
+#define BLKDISCARD     _IO(0x12,119)
+#endif
+
+static int
+discard_blocks(int fd, u64 start, u64 len)
+{
+       u64 range[2] = { start, len };
+
+       if (ioctl(fd, BLKDISCARD, &range) < 0)
+               return errno;
+       return 0;
+}
+
 static u64 reference_root_table[] = {
        [1] =   BTRFS_ROOT_TREE_OBJECTID,
        [2] =   BTRFS_EXTENT_TREE_OBJECTID,
@@ -537,6 +551,13 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
                printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
                *mixed = 1;
        }
+
+       /*
+        * We intentionally ignore errors from the discard ioctl.  It is
+        * not necessary for the mkfs functionality but just an optimization.
+        */
+       discard_blocks(fd, 0, block_count);
+
        ret = zero_dev_start(fd);
        if (ret) {
                fprintf(stderr, "failed to zero device start %d\n", ret);