Merge pull request #17 from jongrimm/master

ld_iscsi: add xstat64 & friends, + a couple bug fixes in ld_iscsi
This commit is contained in:
Ronnie Sahlberg
2012-09-14 18:20:49 -07:00

View File

@@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <asm/fcntl.h>
#include "iscsi.h"
#include "iscsi-private.h"
@@ -130,7 +131,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;
@@ -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)
@@ -251,7 +257,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) {
@@ -259,9 +265,20 @@ 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);
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");
@@ -308,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;
@@ -356,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");
}
}