[PATCH 1/2] TGTIMG add a new --thin-provisioning flag when creating disk devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Tomo,

Please find attached a patch that adds a new argument to tgtimg to
allow to create thin-provisioned files.

The default for tgtimg is to fully allocate all device files it creates.
Using this flag allows to create a "sparse" file for use by the LUN.


regards
ronnie sahlberg

Attachment: 0001-TGTIMG-Add-support-for-thin-provisioning.patch.gz
Description: GNU Zip compressed data

From fc6859e6ab9dea7bbf71a8f411519dbf5f02f0ef Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
Date: Fri, 30 Mar 2012 16:46:38 +1100
Subject: [PATCH 1/2] TGTIMG: Add support for thin-provisioning

A new flag --ting-provisioning is added to the tgtimg command.
When used this flag will create a sparse file without any
allocation guarantee.
It will also verify that FALLOC_FL_PUNCH_HOLE works.

If such files are created, a future patch to tgtd will add
support for the UNMAP command that is used by initiators to
release blocks that are no longer in use.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 doc/tgtimg.8.xml |   22 ++++++++++++++++++++++
 usr/tgtimg.c     |   45 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/doc/tgtimg.8.xml b/doc/tgtimg.8.xml
index 5a787af..e067db0 100644
--- a/doc/tgtimg.8.xml
+++ b/doc/tgtimg.8.xml
@@ -21,6 +21,7 @@
 		<arg choice="opt">-s --size &lt;size&gt;</arg>
 		<arg choice="opt">-t --type &lt;media-type&gt;</arg>
 		<arg choice="opt">-f --file &lt;path&gt;</arg>
+		<arg choice="opt">-T --thin-provisioning</arg>
 	</cmdsynopsis>
 	<cmdsynopsis>
 		<command>tgtimg --help</command>
@@ -126,6 +127,27 @@ Supported media types for tape devices are :
         </listitem>
       </varlistentry>
 
+      <varlistentry><term><option>-T, --thin-provisioning</option></term>
+        <listitem>
+          <para>
+	    This argument makes the allocation of the image format use
+	    thin-provisioning. This means that the file created will be a
+	    sparse file that will allocate blocks from the filesystem on demand.
+          </para>
+          <para>
+	    Be careful when using thin-provisioning. If the filesystem
+	    fills up a iSCSI write to a thin-provisioned LUN
+	    can fail. Initiators generally do not handle "out of space" errors
+	    gracefully.
+          </para>
+          <para>
+	    Thin-provisioning uses FALLOC_FL_PUNCH_HOLE which is only available
+	    on some linux filesystems. Thin-provisioning can only be used for
+	    DISK images.
+          </para>
+        </listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
diff --git a/usr/tgtimg.c b/usr/tgtimg.c
index f4388d9..bb417fe 100644
--- a/usr/tgtimg.c
+++ b/usr/tgtimg.c
@@ -1,5 +1,5 @@
 /*
- *	Create blank media files for bs_tape backing store
+ *	Create media files for TGTD devices
  *
  * Copyright (C) 2008 Mark Harvey markh794@xxxxxxxxx
  *
@@ -22,6 +22,7 @@
 #define _XOPEN_SOURCE 600
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/falloc.h>
 #include <getopt.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -59,6 +60,7 @@ struct option const long_options[] = {
 	{"size", required_argument, NULL, 's'},
 	{"type", required_argument, NULL, 't'},
 	{"file", required_argument, NULL, 'f'},
+	{"thin-provisioning", no_argument, NULL, 'T'},
 	{NULL, 0, NULL, 0},
 };
 
@@ -71,7 +73,7 @@ static void usage(int status)
 		printf("\
 Linux SCSI Target Framework Image File Utility, version %s\n\
 \n\
-  --op new --device-type tape --barcode=[code] --size=[size] --type=[type] --file=[path]\n\
+  --op new --device-type tape --barcode=[code] --size=[size] --type=[type] --file=[path] [--thin-provisioning]\n\
 			create a new tape image file.\n\
 			[code] is a string of chars.\n\
 			[size] is media size(in megabytes).\n\
@@ -83,6 +85,7 @@ Linux SCSI Target Framework Image File Utility, version %s\n\
   --op show --device-type tape --file=[path]\n\
 			dump the tape image file contents.\n\
 			[path] is the tape image file\n\
+  --thin-provisioning   create a sparse file for the media\n\
   --help                display this help and exit\n\
 \n\
 Report bugs to <stgt@xxxxxxxxxxxxxxx>.\n", TGT_VERSION);
@@ -414,7 +417,7 @@ static int mmc_ops(int op, char *path, char *media_type)
 	return 0;
 }
 
-static int sbc_new(int op, char *path, char *capacity, char *media_type)
+static int sbc_new(int op, char *path, char *capacity, char *media_type, int thin)
 {
 	int fd;
 
@@ -438,9 +441,29 @@ static int sbc_new(int op, char *path, char *capacity, char *media_type)
 			perror("Failed creating file");
 			exit(2);
 		}
-		if (posix_fallocate(fd, 0, size*1024*1024LL) == -1) {
-			perror("posix_fallocate failed.");
-			exit(3);
+		if (thin) {
+#ifdef FALLOC_FL_PUNCH_HOLE
+			if (ftruncate(fd, size*1024*1024LL) != 0) {
+				perror("Failed to set file size");
+				exit(6);
+			}
+			if (fallocate(fd,
+				FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
+				0, size*1024*1024LL) != 0) {
+				perror("Thin provisioning not available on"
+					" this file");
+				exit(5);
+			}
+#else
+			perror("This version of tgtimg is not compiled "
+				"with thin-provisioning support.");
+			exit(6);
+#endif
+		} else {
+			if (posix_fallocate(fd, 0, size*1024*1024LL) == -1) {
+				perror("posix_fallocate failed.");
+				exit(3);
+			}
 		}
 
 		free(buf);
@@ -456,7 +479,7 @@ static int sbc_new(int op, char *path, char *capacity, char *media_type)
 	return 0;
 }
 
-static int sbc_ops(int op, char *path, char *capacity, char *media_type)
+static int sbc_ops(int op, char *path, char *capacity, char *media_type, int thin)
 {
 	if (op == OP_NEW) {
 		if (!media_type) {
@@ -471,7 +494,7 @@ static int sbc_ops(int op, char *path, char *capacity, char *media_type)
 			eprintf("Missing the capacity param\n");
 			usage(1);
 		}
-		return sbc_new(op, path, capacity, media_type);
+		return sbc_new(op, path, capacity, media_type, thin);
 	} else {
 		eprintf("unknown the operation type\n");
 		usage(1);
@@ -489,6 +512,7 @@ int main(int argc, char **argv)
 	int dev_type = TYPE_TAPE;
 	int op = -1;
 	char *path = NULL;
+	int thin = 0;
 
 	while ((ch = getopt_long(argc, argv, short_options,
 				 long_options, &longindex)) >= 0) {
@@ -514,6 +538,9 @@ int main(int argc, char **argv)
 		case 'h':
 			usage(0);
 			break;
+		case 'T':
+			thin = 1;
+			break;
 		default:
 			eprintf("unrecognized option '%s'\n", optarg);
 			usage(1);
@@ -543,7 +570,7 @@ int main(int argc, char **argv)
 		mmc_ops(op, path, media_type);
 		break;
 	case TYPE_DISK:
-		sbc_ops(op, path, media_capacity, media_type);
+		sbc_ops(op, path, media_capacity, media_type, thin);
 		break;
 	default:
 		eprintf("unsupported the device type operation\n");
-- 
1.7.3.1


[Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [XFree86]     [Video Devices]

Add to Google Powered by Linux