[stgt] [PATCH] LBPPBE: when opening the backing file, check the blocksize of the underlying filesystem and set lbppbe automatically.

Ronnie Sahlberg ronniesahlberg at gmail.com
Wed Apr 18 11:26:47 CEST 2012


Unless the user has set an explicit value through tgtadm in which case we leave the system using the value the user has set.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
 doc/targets.conf.5.xml |    7 ++++++-
 usr/bs_aio.c           |   19 ++++++++++++-------
 usr/bs_rdwr.c          |   10 ++++++++--
 usr/bs_ssc.c           |    2 +-
 usr/spc.c              |    1 +
 usr/target.c           |    9 +++++++++
 usr/tgtd.h             |    5 +++++
 usr/util.c             |    8 +++++---
 usr/util.h             |    3 ++-
 9 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/doc/targets.conf.5.xml b/doc/targets.conf.5.xml
index f754df3..833e40a 100644
--- a/doc/targets.conf.5.xml
+++ b/doc/targets.conf.5.xml
@@ -336,7 +336,12 @@
 	<listitem>
 	  <para>
 	    Specify the Logical blocks per physical block
-	    exponent. This is an internal option that should not be
+	    exponent. By default TGTD will set the lbppbe to automatically
+	    match the underlying filesystem. Use this parameter to override
+	    that setting.
+	  </para>
+	  <para>
+	    This is an internal option that should not be
 	    set directly.
 	  </para>
 	</listitem>
diff --git a/usr/bs_aio.c b/usr/bs_aio.c
index cbd91ba..75ae66f 100644
--- a/usr/bs_aio.c
+++ b/usr/bs_aio.c
@@ -304,6 +304,7 @@ static int bs_aio_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 {
 	struct bs_aio_info *info = BS_AIO_I(lu);
 	int ret, afd;
+	uint32_t blksize = 0;
 
 	info->iodepth = AIO_MAX_IODEPTH;
 	eprintf("create aio context for tgt:%d lun:%"PRId64 ", max iodepth:%d\n",
@@ -331,13 +332,14 @@ static int bs_aio_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 
 	eprintf("open %s, RW, O_DIRECT for tgt:%d lun:%"PRId64 "\n",
 		path, info->lu->tgt->tid, info->lu->lun);
-	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|O_DIRECT, size);
+	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|O_DIRECT, size,
+				&blksize);
 	/* If we get access denied, try opening the file in readonly mode */
 	if (*fd == -1 && (errno == EACCES || errno == EROFS)) {
 		eprintf("open %s, READONLY, O_DIRECT for tgt:%d lun:%"PRId64 "\n",
 			path, info->lu->tgt->tid, info->lu->lun);
 		*fd = backed_file_open(path, O_RDONLY|O_LARGEFILE|O_DIRECT,
-				       size);
+				       size, &blksize);
 		lu->attrs.readonly = 1;
 	}
 	if (*fd < 0) {
@@ -346,11 +348,14 @@ static int bs_aio_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 		ret = *fd;
 		goto remove_tgt_evt;
 	}
-	else {
-		eprintf("%s opened successfully for tgt:%d lun:%"PRId64 "\n",
-			path, info->lu->tgt->tid, info->lu->lun);
-		return 0;
-	}
+
+	eprintf("%s opened successfully for tgt:%d lun:%"PRId64 "\n",
+		path, info->lu->tgt->tid, info->lu->lun);
+
+	if (!lu->attrs.no_auto_lbppbe)
+		update_lbppbe(lu, blksize);
+
+	return 0;
 
 remove_tgt_evt:
 	tgt_event_del(afd);
diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index 9e15603..fbc9a2c 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -231,16 +231,22 @@ static void bs_rdwr_request(struct scsi_cmd *cmd)
 
 static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 {
-	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|lu->bsoflags, size);
+	uint32_t blksize = 0;
+
+	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|lu->bsoflags, size,
+				&blksize);
 	/* If we get access denied, try opening the file in readonly mode */
 	if (*fd == -1 && (errno == EACCES || errno == EROFS)) {
 		*fd = backed_file_open(path, O_RDONLY|O_LARGEFILE|lu->bsoflags,
-				       size);
+				       size, &blksize);
 		lu->attrs.readonly = 1;
 	}
 	if (*fd < 0)
 		return *fd;
 
+	if (!lu->attrs.no_auto_lbppbe)
+		update_lbppbe(lu, blksize);
+
 	return 0;
 }
 
diff --git a/usr/bs_ssc.c b/usr/bs_ssc.c
index 6412972..93d08a6 100644
--- a/usr/bs_ssc.c
+++ b/usr/bs_ssc.c
@@ -619,7 +619,7 @@ static int bs_ssc_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 
 	ssc = dtype_priv(lu);
 
-	*fd = backed_file_open(path, O_RDWR | O_LARGEFILE, size);
+	*fd = backed_file_open(path, O_RDWR | O_LARGEFILE, size, NULL);
 	if (*fd < 0) {
 		eprintf("Could not open %s %m\n", path);
 		return *fd;
diff --git a/usr/spc.c b/usr/spc.c
index 459993c..b0a305f 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -1750,6 +1750,7 @@ tgtadm_err lu_config(struct scsi_lu *lu, char *params, match_fn_t *fn)
 		case Opt_lbppbe:
 			match_strncpy(buf, &args[0], sizeof(buf));
 			attrs->lbppbe = atoi(buf);
+			attrs->no_auto_lbppbe = 1;
 			break;
 		case Opt_la_lba:
 			match_strncpy(buf, &args[0], sizeof(buf));
diff --git a/usr/target.c b/usr/target.c
index dd3ca91..cbbe833 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -2209,6 +2209,15 @@ tgtadm_err system_show(int mode, struct concat_buf *b)
 	return TGTADM_SUCCESS;
 }
 
+void update_lbppbe(struct scsi_lu *lu, int blksize)
+{
+	lu->attrs.lbppbe = 0;
+	while (blksize > (1U << lu->blk_shift)) {
+		lu->attrs.lbppbe++;
+		blksize >>= 1;
+	}
+}
+
 int is_system_available(void)
 {
 	return (sys_state == TGT_SYSTEM_READY);
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 03036ba..d93fa1a 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -78,6 +78,8 @@ struct lu_phy_attr {
 	char sense_format;	/* Descrptor format sense data supported */
 				/* For the following see READ CAPACITY (16) */
 	unsigned char lbppbe;	/* Logical blocks per physical block exponent */
+	char no_auto_lbppbe;    /* Do not update it automatically when the
+				   backing file changes */
 	uint16_t la_lba;	/* Lowest aligned LBA */
 
 	/* VPD pages 0x80 -> 0xff masked with 0x80*/
@@ -348,4 +350,7 @@ struct event_data {
 int call_program(const char *cmd,
 		    void (*callback)(void *data, int result), void *data,
 		    char *output, int op_len, int flags);
+
+void update_lbppbe(struct scsi_lu *lu, int blksize);
+
 #endif
diff --git a/usr/util.c b/usr/util.c
index c78a999..6c9bad7 100644
--- a/usr/util.c
+++ b/usr/util.c
@@ -82,7 +82,7 @@ int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd)
 	return 0;
 }
 
-int backed_file_open(char *path, int oflag, uint64_t *size)
+int backed_file_open(char *path, int oflag, uint64_t *size, uint32_t *blksize)
 {
 	int fd, err;
 	struct stat64 st;
@@ -99,9 +99,11 @@ int backed_file_open(char *path, int oflag, uint64_t *size)
 		goto close_fd;
 	}
 
-	if (S_ISREG(st.st_mode))
+	if (S_ISREG(st.st_mode)) {
 		*size = st.st_size;
-	else if (S_ISBLK(st.st_mode)) {
+		if (blksize)
+			*blksize = st.st_blksize;
+	} else if (S_ISBLK(st.st_mode)) {
 		err = ioctl(fd, BLKGETSIZE64, size);
 		if (err < 0) {
 			eprintf("Cannot get size, %m\n");
diff --git a/usr/util.h b/usr/util.h
index 4bf157d..c016e5a 100644
--- a/usr/util.h
+++ b/usr/util.h
@@ -62,7 +62,8 @@
 
 extern int get_blk_shift(unsigned int size);
 extern int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd);
-extern int backed_file_open(char *path, int oflag, uint64_t *size);
+extern int backed_file_open(char *path, int oflag, uint64_t *size,
+				uint32_t *blksize);
 extern int set_non_blocking(int fd);
 extern int str_to_open_flags(char *buf);
 extern char *open_flags_to_str(char *dest, int flags);
-- 
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list