diff options
author | Johannes Thumshirn <jthumshirn@suse.de> | 2016-11-17 10:31:18 +0100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-11-17 20:15:25 -0500 |
commit | bf0f2d380f15f1fa05254b000ddeeb560dfb8638 (patch) | |
tree | ea8d464ada113c1f598589b4c724946f45410716 | |
parent | ad7660cc1ef13551e3d0a649aaba7c728b8c0ac0 (diff) |
block: add reference counting for struct bsg_job
Add reference counting to 'struct bsg_job' so we can implement a reuqest
timeout handler for bsg_jobs, which is needed for Fibre Channel.
Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | block/bsg-lib.c | 7 | ||||
-rw-r--r-- | include/linux/bsg-lib.h | 2 |
2 files changed, 7 insertions, 2 deletions
diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 650f427d915b..632fb4006c40 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -32,8 +32,10 @@ * bsg_destroy_job - routine to teardown/delete a bsg job * @job: bsg_job that is to be torn down */ -static void bsg_destroy_job(struct bsg_job *job) +static void bsg_destroy_job(struct kref *kref) { + struct bsg_job *job = container_of(kref, struct bsg_job, kref); + put_device(job->dev); /* release reference for the request */ kfree(job->request_payload.sg_list); @@ -84,7 +86,7 @@ static void bsg_softirq_done(struct request *rq) struct bsg_job *job = rq->special; blk_end_request_all(rq, rq->errors); - bsg_destroy_job(job); + kref_put(&job->kref, bsg_destroy_job); } static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req) @@ -142,6 +144,7 @@ static int bsg_create_job(struct device *dev, struct request *req) job->dev = dev; /* take a reference for the request */ get_device(job->dev); + kref_init(&job->kref); return 0; failjob_rls_rqst_payload: diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h index a226652a5a6c..58e0717fda6e 100644 --- a/include/linux/bsg-lib.h +++ b/include/linux/bsg-lib.h @@ -40,6 +40,8 @@ struct bsg_job { struct device *dev; struct request *req; + struct kref kref; + /* Transport/driver specific request/reply structs */ void *request; void *reply; |