[PATCH 2/3] osd_initiator: support bio chains

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Jeff Garzik <jgarzik@xxxxxxxxxx>
---
 drivers/scsi/osd/osd_initiator.c |   83 +++++++++++++++++++++++++++++++--------
 1 file changed, 67 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 2a5f077..2d35d65 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -709,14 +709,36 @@ EXPORT_SYMBOL(osd_req_remove_object);
 	struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem);
 */
 
+static unsigned int bio_chain_size(struct bio *bio)
+{
+	unsigned int chain_size = 0;
+
+	while (bio) {
+		chain_size += bio->bi_size;
+		bio = bio->bi_next;
+	}
+
+	return chain_size;
+}
+
 void osd_req_write(struct osd_request *or,
 	const struct osd_obj_id *obj, struct bio *bio, u64 offset)
 {
-	_osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, bio->bi_size);
+	unsigned int chain_size = 0;
+	struct bio *tmp_bio = bio;
+
+	while (tmp_bio) {
+		chain_size += tmp_bio->bi_size;
+		tmp_bio->bi_rw |= (1 << BIO_RW);
+
+		tmp_bio = tmp_bio->bi_next;
+	}
+
+	_osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, chain_size);
 	WARN_ON(or->out.bio || or->out.total_bytes);
-	bio->bi_rw |= (1 << BIO_RW);
+
 	or->out.bio = bio;
-	or->out.total_bytes = bio->bi_size;
+	or->out.total_bytes = chain_size;
 }
 EXPORT_SYMBOL(osd_req_write);
 
@@ -747,11 +769,21 @@ EXPORT_SYMBOL(osd_req_flush_object);
 void osd_req_read(struct osd_request *or,
 	const struct osd_obj_id *obj, struct bio *bio, u64 offset)
 {
-	_osd_req_encode_common(or, OSD_ACT_READ, obj, offset, bio->bi_size);
+	unsigned int chain_size = 0;
+	struct bio *tmp_bio = bio;
+
+	while (tmp_bio) {
+		chain_size += tmp_bio->bi_size;
+		tmp_bio->bi_rw &= ~(1 << BIO_RW);
+
+		tmp_bio = tmp_bio->bi_next;
+	}
+
+	_osd_req_encode_common(or, OSD_ACT_READ, obj, offset, chain_size);
 	WARN_ON(or->in.bio || or->in.total_bytes);
-	bio->bi_rw &= ~(1 << BIO_RW);
+
 	or->in.bio = bio;
-	or->in.total_bytes = bio->bi_size;
+	or->in.total_bytes = chain_size;
 }
 EXPORT_SYMBOL(osd_req_read);
 
@@ -1176,7 +1208,7 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or,
 		unsigned pad;
 
 		or->out_data_integ.data_bytes = cpu_to_be64(
-			or->out.bio ? or->out.bio->bi_size : 0);
+			or->out.bio ? bio_chain_size(or->out.bio) : 0);
 		or->out_data_integ.set_attributes_bytes = cpu_to_be64(
 			or->set_attr.total_bytes);
 		or->out_data_integ.get_attributes_bytes = cpu_to_be64(
@@ -1269,6 +1301,7 @@ int osd_finalize_request(struct osd_request *or,
 	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
 	bool has_in, has_out;
 	int ret;
+	struct bio *bio, *tmp;
 
 	if (options & OSD_REQ_FUA)
 		cdbh->options |= OSD_CDB_FUA;
@@ -1292,23 +1325,40 @@ int osd_finalize_request(struct osd_request *or,
 	}
 
 	if (or->out.bio) {
-		ret = blk_rq_append_bio(or->request->q, or->out.req,
-					or->out.bio);
-		if (ret) {
-			OSD_DEBUG("blk_rq_append_bio out failed\n");
-			return ret;
+		bio = or->out.bio;
+		while (bio) {
+			tmp = bio;
+			bio = bio->bi_next;
+
+			ret = blk_rq_append_bio(or->request->q, or->out.req,
+						tmp);
+			if (ret) {
+				OSD_DEBUG("blk_rq_append_bio out failed\n");
+				return ret;
+			}
 		}
 		OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n",
 			_LLU(or->out.total_bytes), or->out.req->data_len);
+
+		or->out.bio = NULL;
 	}
 	if (or->in.bio) {
-		ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio);
-		if (ret) {
-			OSD_DEBUG("blk_rq_append_bio in failed\n");
-			return ret;
+		bio = or->in.bio;
+		while (bio) {
+			tmp = bio;
+			bio = bio->bi_next;
+
+			ret = blk_rq_append_bio(or->request->q, or->in.req,
+						tmp);
+			if (ret) {
+				OSD_DEBUG("blk_rq_append_bio in failed\n");
+				return ret;
+			}
 		}
 		OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n",
 			_LLU(or->in.total_bytes), or->in.req->data_len);
+
+		or->in.bio = NULL;
 	}
 
 	or->out.pad_buff = sg_out_pad_buffer;
@@ -1618,6 +1668,7 @@ void osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused)
 void osd_sec_sign_data(void *data_integ __unused,
 		       struct bio *bio __unused, const u8 *cap_key __unused)
 {
+	/* NOTE: bio is a linked list */
 }
 
 /*
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux