Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 177937
b: refs/heads/master
c: 5d0961f
h: refs/heads/master
i:
  177935: 5fb3d2f
v: v3
  • Loading branch information
Boaz Harrosh authored and James Bottomley committed Dec 10, 2009
1 parent 192acd1 commit 9b5ceb0
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aeab3fd7b865bc4086a80a83cfdd67dded3b41a0
refs/heads/master: 5d0961fd1f25e117f907f3af3aaa870637049252
88 changes: 47 additions & 41 deletions trunk/drivers/scsi/osd/osd_initiator.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,67 +432,76 @@ static void _osd_free_seg(struct osd_request *or __unused,
seg->alloc_size = 0;
}

static void _put_request(struct request *rq , bool is_async)
static void _put_request(struct request *rq)
{
if (is_async) {
WARN_ON(rq->bio);
__blk_put_request(rq->q, rq);
} else {
/*
* If osd_finalize_request() was called but the request was not
* executed through the block layer, then we must release BIOs.
* TODO: Keep error code in or->async_error. Need to audit all
* code paths.
*/
if (unlikely(rq->bio))
blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
else
blk_put_request(rq);
}
/*
* If osd_finalize_request() was called but the request was not
* executed through the block layer, then we must release BIOs.
* TODO: Keep error code in or->async_error. Need to audit all
* code paths.
*/
if (unlikely(rq->bio))
blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
else
blk_put_request(rq);
}

void osd_end_request(struct osd_request *or)
{
struct request *rq = or->request;
/* IMPORTANT: make sure this agrees with osd_execute_request_async */
bool is_async = (or->request->end_io_data == or);

_osd_free_seg(or, &or->set_attr);
_osd_free_seg(or, &or->enc_get_attr);
_osd_free_seg(or, &or->get_attr);

if (rq) {
if (rq->next_rq) {
_put_request(rq->next_rq, is_async);
_put_request(rq->next_rq);
rq->next_rq = NULL;
}

_put_request(rq, is_async);
_put_request(rq);
}
_osd_request_free(or);
}
EXPORT_SYMBOL(osd_end_request);

static void _set_error_resid(struct osd_request *or, struct request *req,
int error)
{
or->async_error = error;
or->req_errors = req->errors ? : error;
or->sense_len = req->sense_len;
if (or->out.req)
or->out.residual = or->out.req->resid_len;
if (or->in.req)
or->in.residual = or->in.req->resid_len;
}

int osd_execute_request(struct osd_request *or)
{
return or->async_error =
blk_execute_rq(or->request->q, NULL, or->request, 0);
int error = blk_execute_rq(or->request->q, NULL, or->request, 0);

_set_error_resid(or, or->request, error);
return error;
}
EXPORT_SYMBOL(osd_execute_request);

static void osd_request_async_done(struct request *req, int error)
{
struct osd_request *or = req->end_io_data;

or->async_error = error;

if (unlikely(error)) {
OSD_DEBUG("osd_request_async_done error recieved %d "
"errors 0x%x\n", error, req->errors);
if (!req->errors) /* don't miss out on this one */
req->errors = error;
_set_error_resid(or, req, error);
if (req->next_rq) {
__blk_put_request(req->q, req->next_rq);
req->next_rq = NULL;
}

__blk_put_request(req->q, req);
or->request = NULL;
or->in.req = NULL;
or->out.req = NULL;

if (or->async_done)
or->async_done(or, or->async_private);
else
Expand Down Expand Up @@ -1489,21 +1498,18 @@ int osd_req_decode_sense_full(struct osd_request *or,
#endif
int ret;

if (likely(!or->request->errors)) {
osi->out_resid = 0;
osi->in_resid = 0;
if (likely(!or->req_errors))
return 0;
}

osi = osi ? : &local_osi;
memset(osi, 0, sizeof(*osi));

ssdb = or->request->sense;
sense_len = or->request->sense_len;
ssdb = (typeof(ssdb))or->sense;
sense_len = or->sense_len;
if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) {
OSD_ERR("Block-layer returned error(0x%x) but "
"sense_len(%u) || key(%d) is empty\n",
or->request->errors, sense_len, ssdb->sense_key);
or->req_errors, sense_len, ssdb->sense_key);
goto analyze;
}

Expand All @@ -1525,7 +1531,7 @@ int osd_req_decode_sense_full(struct osd_request *or,
"additional_code=0x%x async_error=%d errors=0x%x\n",
osi->key, original_sense_len, sense_len,
osi->additional_code, or->async_error,
or->request->errors);
or->req_errors);

if (original_sense_len < sense_len)
sense_len = original_sense_len;
Expand Down Expand Up @@ -1695,10 +1701,10 @@ int osd_req_decode_sense_full(struct osd_request *or,
ret = -EIO;
}

if (or->out.req)
osi->out_resid = or->out.req->resid_len ?: or->out.total_bytes;
if (or->in.req)
osi->in_resid = or->in.req->resid_len ?: or->in.total_bytes;
if (!or->out.residual)
or->out.residual = or->out.total_bytes;
if (!or->in.residual)
or->in.residual = or->in.total_bytes;

return ret;
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/include/scsi/osd_initiator.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ struct osd_request {
struct _osd_io_info {
struct bio *bio;
u64 total_bytes;
u64 residual;
struct request *req;
struct _osd_req_data_segment *last_seg;
u8 *pad_buff;
Expand All @@ -150,12 +151,14 @@ struct osd_request {
gfp_t alloc_flags;
unsigned timeout;
unsigned retries;
unsigned sense_len;
u8 sense[OSD_MAX_SENSE_LEN];
enum osd_attributes_mode attributes_mode;

osd_req_done_fn *async_done;
void *async_private;
int async_error;
int req_errors;
};

static inline bool osd_req_is_ver1(struct osd_request *or)
Expand Down Expand Up @@ -297,8 +300,6 @@ enum osd_err_priority {
};

struct osd_sense_info {
u64 out_resid; /* Zero on success otherwise out residual */
u64 in_resid; /* Zero on success otherwise in residual */
enum osd_err_priority osd_err_pri;

int key; /* one of enum scsi_sense_keys */
Expand Down

0 comments on commit 9b5ceb0

Please sign in to comment.