- Fixed problems with 64-bit platforms with 32-bit user space and with non-4K pages
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 23 May 2008 15:12:34 +0000 (15:12 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 23 May 2008 15:12:34 +0000 (15:12 +0000)
 - From the main Makefile all all LSI/MPT related targets are commented out, because the recent changes in its Makefile have broken them.

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@391 d57e44dd-8a1f-0410-8b47-8ef2f437770f

Makefile
iscsi-scst/include/iscsi_scst.h
iscsi-scst/kernel/config.c
iscsi-scst/kernel/iscsi.c
iscsi-scst/usr/ctldev.c
iscsi-scst/usr/iscsi_scstd.c
iscsi-scst/usr/iscsid.h
iscsi-scst/usr/param.c

index b4e91ed..db82951 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -98,7 +98,7 @@ install:
 uninstall: 
        cd $(SCST_DIR) && $(MAKE) $@
        @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
-       @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
+#      @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
        @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@@ -107,7 +107,7 @@ clean:
        cd $(SCST_DIR) && $(MAKE) $@
        @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi
        @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
-       @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
+#      @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
        @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@@ -116,7 +116,7 @@ extraclean:
        cd $(SCST_DIR) && $(MAKE) $@
        @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi
        @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
-       @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
+#      @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
        @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
        @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
index 242ad07..04d03ce 100644 (file)
@@ -119,15 +119,18 @@ struct iscsi_event {
        u32 state;
 };
 
+struct iscsi_register_info {
+       aligned_u64 version;
+       u32 max_data_seg_len;
+};
+
 #define        DEFAULT_NR_QUEUED_CMNDS 32
 #define        MIN_NR_QUEUED_CMNDS     1
 #define        MAX_NR_QUEUED_CMNDS     256
 
-#define MAX_DATA_SEG_LEN       (4096/sizeof(struct iovec)*4096)
-
 #define NETLINK_ISCSI_SCST     25
 
-#define REGISTER_USERD         _IOW('s', 0, const char*)
+#define REGISTER_USERD         _IOW('s', 0, struct iscsi_register_info)
 #define ADD_TARGET             _IOW('s', 1, struct target_info)
 #define DEL_TARGET             _IOW('s', 2, struct target_info)
 #define ADD_SESSION            _IOW('s', 3, struct session_info)
index 63a32ad..255c8d8 100644 (file)
@@ -371,10 +371,18 @@ static int add_target(unsigned long ptr)
 
 static int iscsi_check_version(unsigned long arg)
 {
+       struct iscsi_register_info reg;
        char ver[sizeof(ISCSI_SCST_INTERFACE_VERSION)+1];
-       int res;
+       int res, max_data_seg_len;
 
-       res = copy_from_user(ver, (void *)arg, sizeof(ver));
+       res = copy_from_user(&reg, (void *)arg, sizeof(reg));
+       if (res < 0) {
+               PRINT_ERROR("%s", "Unable to get register info");
+               goto out;
+       }
+
+       res = copy_from_user(ver, (void *)(unsigned long)reg.version,
+                               sizeof(ver));
        if (res < 0) {
                PRINT_ERROR("%s", "Unable to get version string");
                goto out;
@@ -382,12 +390,20 @@ static int iscsi_check_version(unsigned long arg)
        ver[sizeof(ver)-1] = '\0';
 
        if (strcmp(ver, ISCSI_SCST_INTERFACE_VERSION) != 0) {
-               PRINT_ERROR("Incorrect version of user space %s (needed %s)",
+               PRINT_ERROR("Incorrect version of user space %s (expected %s)",
                        ver, ISCSI_SCST_INTERFACE_VERSION);
                res = -EINVAL;
                goto out;
        }
 
+       max_data_seg_len = ISCSI_CONN_IOV_MAX << PAGE_SHIFT;
+       if (reg.max_data_seg_len != max_data_seg_len) {
+               PRINT_ERROR("Incorrect max_data_seg_len %d (expected %d)",
+                       reg.max_data_seg_len, max_data_seg_len);
+               res = -EINVAL;
+               goto out;
+       }
+
 out:
        return res;
 }
index 14c6fb6..f64a409 100644 (file)
@@ -2907,8 +2907,6 @@ static int __init iscsi_init(void)
                "degraded mode. Refer README file for details");
 #endif
 
-       BUILD_BUG_ON(MAX_DATA_SEG_LEN != (ISCSI_CONN_IOV_MAX<<PAGE_SHIFT));
-
        if ((ctr_major = register_chrdev(0, ctr_name, &ctr_fops)) < 0) {
                PRINT_ERROR("failed to register the control device %d", ctr_major);
                err = ctr_major;
index 05fdeec..717b584 100644 (file)
@@ -34,7 +34,7 @@ struct session_file_operations {
        int (*connection_op) (int fd, u32 tid, u64 sid, u32 cid, void *arg);
 };
 
-static int ctrdev_open(void)
+static int ctrdev_open(int max_data_seg_len)
 {
        FILE *f;
        char devname[256];
@@ -42,6 +42,7 @@ static int ctrdev_open(void)
        int devn;
        int ctlfd = -1;
        int err;
+       struct iscsi_register_info reg = { 0 };
 
        if (!(f = fopen("/proc/devices", "r"))) {
                perror("Cannot open control path to the driver\n");
@@ -81,9 +82,12 @@ static int ctrdev_open(void)
                goto out;
        }
 
-       err = ioctl(ctlfd, REGISTER_USERD, ISCSI_SCST_INTERFACE_VERSION);
+       reg.version = ISCSI_SCST_INTERFACE_VERSION;
+       reg.max_data_seg_len = max_data_seg_len;
+       err = ioctl(ctlfd, REGISTER_USERD, &reg);
        if (err < 0) {
-               log_error("Unable to register: %s\n", strerror(errno));
+               log_error("Unable to register: %s. Incompatible version of the "
+                       "kernel module?\n", strerror(errno));
                close(ctlfd);
                ctlfd = -1;
                goto out;
index 4edf0c4..f4d6bfc 100644 (file)
@@ -518,6 +518,42 @@ static void event_loop(int timeout)
        }
 }
 
+int init_max_data_seg_len(void)
+{
+       int page_size = getpagesize();
+       int max_data_seg_len = page_size / sizeof(struct iovec) * page_size;
+
+       if ((session_keys[3].local_def != -1) ||
+           (session_keys[3].max != -1) ||
+           (session_keys[4].local_def != -1) ||
+           (session_keys[4].max != -1) ||
+           (session_keys[5].local_def != -1) ||
+           (session_keys[5].max != -1) ||
+           (session_keys[6].local_def != -1) ||
+           (session_keys[6].max != -1)) {
+               log_error("Wrong session_keys initialization");
+               exit(-1);
+       }
+
+       /* MaxRecvDataSegmentLength */
+       session_keys[3].local_def = max_data_seg_len;
+       session_keys[3].max = max_data_seg_len;
+
+       /* MaxXmitDataSegmentLength */
+       session_keys[4].local_def = max_data_seg_len;
+       session_keys[4].max = max_data_seg_len;
+
+       /* MaxBurstLength */
+       session_keys[5].local_def = max_data_seg_len;
+       session_keys[5].max = max_data_seg_len;
+
+       /* FirstBurstLength */
+       session_keys[6].local_def = max_data_seg_len;
+       session_keys[6].max = max_data_seg_len;
+
+       return max_data_seg_len;
+}
+
 int main(int argc, char **argv)
 {
        int ch, longindex, timeout = -1;
@@ -526,6 +562,7 @@ int main(int argc, char **argv)
        gid_t gid = 0;
        char *isns = NULL;
        int isns_ac = 0;
+       int max_data_seg_len;
 
        if (pipe(init_report_pipe) == -1) {
                perror("pipe");
@@ -573,7 +610,9 @@ int main(int argc, char **argv)
                exit(-1);
        };
 
-       if ((ctrl_fd = ki->ctldev_open()) < 0)
+       max_data_seg_len = init_max_data_seg_len();
+
+       if ((ctrl_fd = ki->ctldev_open(max_data_seg_len)) < 0)
                exit(-1);
 
        if ((ipc_fd = iscsi_adm_request_listen()) < 0) {
index 3774f0a..aa6993b 100644 (file)
@@ -210,7 +210,7 @@ extern int iscsi_adm_request_handle(int accept_fd);
 
 /* ctldev.c */
 struct iscsi_kernel_interface {
-       int (*ctldev_open) (void);
+       int (*ctldev_open) (int);
        int (*param_get) (u32, u64, int, struct iscsi_param *, int);
        int (*param_set) (u32, u64, int, u32, struct iscsi_param *, int);
        int (*target_create) (u32 *, char *);
index 3fe20e5..c53ee69 100644 (file)
@@ -293,10 +293,10 @@ struct iscsi_key session_keys[] = {
        {"InitialR2T", 1, 0, 0, 1, &or_ops},
        {"ImmediateData", 1, 1, 0, 1, &and_ops},
        {"MaxConnections", 1, 1, 1, 1, &minimum_ops},
-       {"MaxRecvDataSegmentLength", 8192, MAX_DATA_SEG_LEN, 512, MAX_DATA_SEG_LEN, &minimum_ops},
-       {"MaxXmitDataSegmentLength", 8192, MAX_DATA_SEG_LEN, 512, MAX_DATA_SEG_LEN, &minimum_ops},
-       {"MaxBurstLength", 262144, MAX_DATA_SEG_LEN, 512, MAX_DATA_SEG_LEN, &minimum_ops},
-       {"FirstBurstLength", 65536, MAX_DATA_SEG_LEN, 512, MAX_DATA_SEG_LEN, &minimum_ops},
+       {"MaxRecvDataSegmentLength", 8192, -1, 512, -1, &minimum_ops},
+       {"MaxXmitDataSegmentLength", 8192, -1, 512, -1, &minimum_ops},
+       {"MaxBurstLength", 262144, -1, 512, -1, &minimum_ops},
+       {"FirstBurstLength", 65536, -1, 512, -1, &minimum_ops},
        {"DefaultTime2Wait", 2, 2, 0, 3600, &maximum_ops},
        {"DefaultTime2Retain", 20, 20, 0, 3600, &minimum_ops},
        {"MaxOutstandingR2T", 1, 20, 1, 65535, &minimum_ops},