gfs2-utils: master - mkfs.gfs2 should support discard request generation

Bob Peterson rpeterso at fedoraproject.org
Thu Dec 9 21:08:43 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=b2287ab25756f2e7c384af92a9dfebc8ffab2b83
Commit:        b2287ab25756f2e7c384af92a9dfebc8ffab2b83
Parent:        4e70727853794c5c6dbf93c98ee5a4e5015be868
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Thu Dec 9 15:08:52 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Thu Dec 9 15:08:52 2010 -0600

mkfs.gfs2 should support discard request generation

This patch allows mkfs.gfs2 to issue discard ioctls to the underlying
devices.  All the file system blocks are discarded before the file system
is formatted, as was done for other file systems.

rhbz#656956
---
 gfs2/man/mkfs.gfs2.8  |    5 +++++
 gfs2/mkfs/main_grow.c |   18 ++++++++++++++++++
 gfs2/mkfs/main_mkfs.c |   35 +++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/gfs2/man/mkfs.gfs2.8 b/gfs2/man/mkfs.gfs2.8
index 279c12f..63348f8 100644
--- a/gfs2/man/mkfs.gfs2.8
+++ b/gfs2/man/mkfs.gfs2.8
@@ -39,6 +39,11 @@ The number of journals for gfs2_mkfs to create.  You need at least one
 journal per machine that will mount the filesystem.  If this option is
 not specified, one journal will be created.
 .TP
+\fB-K\fP
+Keep, do not attempt to discard blocks at mkfs time (discarding blocks
+initially is useful on solid state devices and  sparse  /  thin-provisioned
+storage).
+.TP
 \fB-O\fP
 This option prevents gfs2_mkfs from asking for confirmation before writing
 the filesystem.
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 21f7f7a..e76affc 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -36,6 +36,19 @@ static unsigned int rgsize = 0;
 extern int create_new_inode(struct gfs2_sbd *sdp);
 extern int rename2system(struct gfs2_sbd *sdp, char *new_dir, char *new_name);
 
+#ifndef BLKDISCARD
+#define BLKDISCARD      _IO(0x12,119)
+#endif
+
+static int discard_blocks(int fd, uint64_t start, uint64_t len)
+{
+	__uint64_t range[2] = { start, len };
+
+	if (ioctl(fd, BLKDISCARD, &range) < 0)
+		return errno;
+	return 0;
+}
+
 /**
  * usage - Print out the usage message
  *
@@ -158,6 +171,7 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
 {
 	uint64_t rgrp = 0;
 	osi_list_t *head = &sdp->rglist;
+	struct rgrp_list *rl;
 
 	*old_rg_count = 0;
 	/* Delete the old RGs from the rglist */
@@ -166,6 +180,10 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
 		(*old_rg_count)++;
 		osi_list_del(head->next);
 	}
+	/* Issue a discard ioctl for the new portion */
+	rl = osi_list_entry(&sdp->rglist.next, struct rgrp_list, list);
+	discard_blocks(sdp->device_fd, rl->start * sdp->bsize,
+		       (sdp->device.length - rl->start) * sdp->bsize);
 	/* Build the remaining resource groups */
 	build_rgrps(sdp, !test);
 
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 719893b..3cec996 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -18,6 +18,7 @@
 #include <signal.h>
 #include <sys/time.h>
 #include <libintl.h>
+#include <sys/ioctl.h>
 
 #define _(String) gettext(String)
 
@@ -25,6 +26,8 @@
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
 
+int discard = 1;
+
 /**
  * This function is for libgfs2's sake.
  */
@@ -55,6 +58,7 @@ print_usage(const char *prog_name)
 		"  -h               Print this help, then exit\n"
 		"  -J <MB>          Size of journals\n"
 		"  -j <num>         Number of journals\n"
+		"  -K               Don't try to discard unused blocks\n"
 		"  -O               Don't ask for confirmation\n"
 		"  -p <name>        Name of the locking protocol\n"
 		"  -q               Don't print anything\n"
@@ -64,6 +68,30 @@ print_usage(const char *prog_name)
 		"  -V               Print program version information, then exit\n"), prog_name);
 }
 
+#ifndef BLKDISCARD
+#define BLKDISCARD      _IO(0x12,119)
+#endif
+
+static int discard_blocks(struct gfs2_sbd *sdp)
+{
+        __uint64_t range[2];
+
+	range[0] = 0;
+	range[1] = sdp->device.length * sdp->bsize;
+	if (sdp->debug)
+		printf("Issuing discard ioctl: range: %llu - %llu...",
+		       (unsigned long long)range[0],
+		       (unsigned long long)range[1]);
+	if (ioctl(sdp->device_fd, BLKDISCARD, &range) < 0) {
+		if (sdp->debug)
+			printf("error = %d\n", errno);
+		return errno;
+	}
+	if (sdp->debug)
+		printf("Successful.\n");
+        return 0;
+}
+
 /**
  * decode_arguments - decode command line arguments and fill in the struct gfs2_sbd
  * @argc:
@@ -110,6 +138,10 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
 			sdp->md.journals = atoi(optarg);
 			break;
 
+		case 'K':
+			discard = 0;
+			break;
+
 		case 'O':
 			sdp->override = TRUE;
 			break;
@@ -620,6 +652,9 @@ void main_mkfs(int argc, char *argv[])
 		exit(-1);
 	}
 
+	if (discard)
+		discard_blocks(sdp);
+
 	/* Compute the resource group layouts */
 
 	compute_rgrp_layout(sdp, rgsize_specified);


More information about the cluster-commits mailing list