From 60a96e0ebfe988025603ba15a36e66fe99d9c944 Mon Sep 17 00:00:00 2001 From: Jon Grimm Date: Fri, 14 Sep 2012 11:19:09 -0500 Subject: [PATCH 1/5] off by one error for calculating num_blocks --- src/ld_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 77cc5af..2494779 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -130,7 +130,7 @@ int open(const char *path, int flags, mode_t mode) iscsi_fd_list[fd].dup2fd = -1; iscsi_fd_list[fd].iscsi = iscsi; iscsi_fd_list[fd].block_size = rc10->block_size; - iscsi_fd_list[fd].num_blocks = rc10->lba; + iscsi_fd_list[fd].num_blocks = rc10->lba + 1; iscsi_fd_list[fd].offset = 0; iscsi_fd_list[fd].lun = iscsi_url->lun; From eb90ab98c1cb2a8c9dc3fd833c64a9f873dfab0b Mon Sep 17 00:00:00 2001 From: Jon Grimm Date: Fri, 14 Sep 2012 12:02:05 -0500 Subject: [PATCH 2/5] ld_iscsi: return block size for stat and friends --- src/ld_iscsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 2494779..2100c76 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -210,6 +210,7 @@ int __fxstat(int ver, int fd, struct stat *buf) memset(buf, 0, sizeof(struct stat)); buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IFREG; buf->st_size = iscsi_fd_list[fd].num_blocks * iscsi_fd_list[fd].block_size; + buf->st_blksize = iscsi_fd_list[fd].block_size; return 0; } From 74496e36fd3b1f2676cec93b8ec96300aa5f3064 Mon Sep 17 00:00:00 2001 From: Jon Grimm Date: Fri, 14 Sep 2012 12:22:07 -0500 Subject: [PATCH 3/5] ld_iscsi: don't try to read beyond last lba --- src/ld_iscsi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 2100c76..46de32e 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -252,7 +252,7 @@ ssize_t read(int fd, void *buf, size_t count) { if ((iscsi_fd_list[fd].is_iscsi == 1) && (iscsi_fd_list[fd].in_flight == 0)) { uint64_t offset; - uint32_t num_blocks; + uint32_t num_blocks, lba; struct scsi_task *task; if (iscsi_fd_list[fd].dup2fd >= 0) { @@ -260,6 +260,17 @@ ssize_t read(int fd, void *buf, size_t count) } offset = iscsi_fd_list[fd].offset / iscsi_fd_list[fd].block_size * iscsi_fd_list[fd].block_size; num_blocks = (iscsi_fd_list[fd].offset - offset + count + iscsi_fd_list[fd].block_size - 1) / iscsi_fd_list[fd].block_size; + lba = offset / iscsi_fd_list[fd].block_size; + + /* Don't try to read beyond the last LBA */ + if (lba >= iscsi_fd_list[fd].num_blocks) { + return 0; + } + /* Trim num_blocks requested to last lba */ + if ((lba + num_blocks) > iscsi_fd_list[fd].num_blocks) { + num_blocks = iscsi_fd_list[fd].num_blocks - lba; + count = num_blocks * iscsi_fd_list[fd].block_size; + } iscsi_fd_list[fd].in_flight = 1; task = iscsi_read10_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, offset / iscsi_fd_list[fd].block_size, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); From a434a90d64ea4325331dbf3ffc72e8208c7468c9 Mon Sep 17 00:00:00 2001 From: Jon Grimm Date: Fri, 14 Sep 2012 12:27:37 -0500 Subject: [PATCH 4/5] ld_iscsi: minor, use value already calculated in 'lba' local var in call to readcapacity --- src/ld_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 46de32e..24585c9 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -273,7 +273,7 @@ ssize_t read(int fd, void *buf, size_t count) } iscsi_fd_list[fd].in_flight = 1; - task = iscsi_read10_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, offset / iscsi_fd_list[fd].block_size, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); + task = iscsi_read10_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, lba, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); iscsi_fd_list[fd].in_flight = 0; if (task == NULL || task->status != SCSI_STATUS_GOOD) { fprintf(stderr, "ld-iscsi: failed to send read10 command\n"); From 365f6ddf10058c3f87cb7ad79f7d7fc23180bf03 Mon Sep 17 00:00:00 2001 From: Jon Grimm Date: Fri, 14 Sep 2012 12:41:11 -0500 Subject: [PATCH 5/5] ld_iscsi: add xstat64, lxstat64, fsxstat64, open64 --- src/ld_iscsi.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 24585c9..e0e7ad8 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "iscsi.h" #include "iscsi-private.h" @@ -143,6 +144,11 @@ int open(const char *path, int flags, mode_t mode) return real_open(path, flags, mode); } +int open64(const char *path, int flags, mode_t mode) +{ + return open(path, flags | O_LARGEFILE, mode); +} + int (*real_close)(int fd); int close(int fd) @@ -210,7 +216,6 @@ int __fxstat(int ver, int fd, struct stat *buf) memset(buf, 0, sizeof(struct stat)); buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IFREG; buf->st_size = iscsi_fd_list[fd].num_blocks * iscsi_fd_list[fd].block_size; - buf->st_blksize = iscsi_fd_list[fd].block_size; return 0; } @@ -320,6 +325,54 @@ int dup2(int oldfd, int newfd) } +int (*real_fxstat64)(int ver, int fd, struct stat64 *buf); + +int __fxstat64(int ver, int fd, struct stat64 *buf) +{ + if (iscsi_fd_list[fd].is_iscsi == 1) { + if (iscsi_fd_list[fd].dup2fd >= 0) { + return __fxstat64(ver, iscsi_fd_list[fd].dup2fd, buf); + } + + memset(buf, 0, sizeof(struct stat64)); + buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IFREG; + buf->st_size = iscsi_fd_list[fd].num_blocks * iscsi_fd_list[fd].block_size; + return 0; + } + + return real_fxstat64(ver, fd, buf); +} + + +int (*real_lxstat64)(int ver, __const char *path, struct stat64 *buf); + +int __lxstat64(int ver, const char *path, struct stat64 *buf) +{ + if (!strncmp(path, "iscsi:", 6)) { + int fd, ret; + + fd = open64(path, 0, 0); + if (fd == -1) { + return fd; + } + + ret = __fxstat64(ver, fd, buf); + close(fd); + return ret; + } + + return real_lxstat64(ver, path, buf); +} + + +int (*real_xstat64)(int ver, __const char *path, struct stat64 *buf); + +int __xstat64(int ver, const char *path, struct stat64 *buf) +{ + return __lxstat64(ver, path, buf); +} + + static void __attribute__((constructor)) _init(void) { int i; @@ -368,4 +421,19 @@ static void __attribute__((constructor)) _init(void) fprintf(stderr, "ld_iscsi: Failed to dlsym(dup2)\n"); exit(10); } + + real_fxstat64 = dlsym(RTLD_NEXT, "__fxstat64"); + if (real_fxstat64 == NULL) { + fprintf(stderr, "ld_iscsi: Failed to dlsym(__fxstat64)\n"); + } + + real_lxstat64 = dlsym(RTLD_NEXT, "__lxstat64"); + if (real_lxstat64 == NULL) { + fprintf(stderr, "ld_iscsi: Failed to dlsym(_lxstat64)\n"); + } + + real_xstat64 = dlsym(RTLD_NEXT, "__xstat64"); + if (real_xstat64 == NULL) { + fprintf(stderr, "ld_iscsi: Failed to dlsym(__xstat64)\n"); + } }