Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 834

kernel-2.6.18-238.el5.src.rpm

From: mchristi@redhat.com <mchristi@redhat.com>
Date: Tue, 19 Aug 2008 16:13:28 -0500
Subject: [firmware] fix ibft offset calculation
Message-id: 1219180408-15910-1-git-send-email-mchristi@redhat.com
O-Subject: [PATCH 1/1] [RHEL 5.3] Fix ibft offset calculation
Bugzilla: 444776

From: Mike Christie <michaelc@cs.wisc.edu>

This is for bz 444776 where we are not displaying the ibft info
when the target name was short.

The patch was from dell. They tested there. I also tested it with
a intel nic that has ibft capabilities using different name lengths
to verify it fixed the problem.

Patch was sent upstream here
http://marc.info/?l=linux-kernel&m=121908240611902&w=2
It has not been merged into a tree yet.

Here is a more indepth explantion of the problem from Dell (patch
was also from Dell):

The issue is because of an offset calculatation error in the iscsi_ibft.c
code.  Due to this error directory structure for the target
in /sys/firmware/ibft does not get created and so the initiator is unable to
connect to the target.

Note that this bug surfaced only with an name that had a short section at the
end.
eg: "iqn.1984-05.com.dell:dell".
It did not surface when the iqn's had a longer section at the end.
eg: "iqn.2001-04.com.example:storage.disk2.sys1.xyz"

So, the eot_offset was calculated such that an extra 48 bytes i.e. the size of
the ibft_header which has already been accounted was subtracted twice.

This was not evident with longer iqn names because they would overshoot the
total ibft length more than 48 bytes and thus would escape the bug.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>

diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 4c76064..392d7d6 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -665,8 +665,7 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header,
 
 	control = (void *)header + sizeof(*header);
 	end = (void *)control + control->hdr.length;
-	eot_offset = (void *)header + header->length -
-		     (void *)control - sizeof(*header);
+	eot_offset = (void *)header + header->length - (void *)control;
 	rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
 			     sizeof(*control));
 	rc |= control->hdr.index != 0;