LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File gfs2_mkfs_should_support_discard_request_generation.patch of Package cluster (Project home:sschapiro:openstack:upstream)

commit ab93700c01af315656c63a5c5bd7387a347a390d
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Thu Dec 9 15:17:10 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

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 e442a25..efe3bfb 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -34,6 +34,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
  *
@@ -157,6 +170,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 */
@@ -165,6 +179,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 6af8c3a..4197dac 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -16,6 +16,7 @@
 #include <signal.h>
 #include <sys/time.h>
 #include <libintl.h>
+#include <sys/ioctl.h>
 
 #define _(String) gettext(String)
 
@@ -23,6 +24,8 @@
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
 
+int discard = 1;
+
 /**
  * This function is for libgfs2's sake.
  */
@@ -53,6 +56,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"
@@ -62,6 +66,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:
@@ -108,6 +136,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;
@@ -618,6 +650,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);