From 56ed92ab711e295d855deb3c56bdff48dc56ae1f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 4 Feb 2009 11:36:27 +0900 Subject: [PATCH] --- yaml --- r: 136261 b: refs/heads/master c: c96952ed7031e7c576ecf90cf95b8ec099d5295a h: refs/heads/master i: 136259: b3039d97c5d5e81726faa12bc9cf6284968d60c6 v: v3 --- [refs] | 2 +- trunk/drivers/scsi/sg.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 61c6917c7f45..d16cc3fa2549 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a3b7aeaba29e3dd995ece05ba50db9e0650c16b6 +refs/heads/master: c96952ed7031e7c576ecf90cf95b8ec099d5295a diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 18d079e3990e..cdd83cf97100 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -138,6 +138,7 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */ volatile char done; /* 0->before bh, 1->before read, 2->read */ struct request *rq; struct bio *bio; + struct execute_work ew; } Sg_request; typedef struct sg_fd { /* holds the state of a file descriptor */ @@ -1234,6 +1235,15 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } +static void sg_rq_end_io_usercontext(struct work_struct *work) +{ + struct sg_request *srp = container_of(work, struct sg_request, ew.work); + struct sg_fd *sfp = srp->parentfp; + + sg_finish_rem_req(srp); + kref_put(&sfp->f_ref, sg_remove_sfp); +} + /* * This function is a "bottom half" handler that is called by the mid * level when a command is completed (or has failed). @@ -1312,10 +1322,9 @@ static void sg_rq_end_io(struct request *rq, int uptodate) */ wake_up_interruptible(&sfp->read_wait); kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); + kref_put(&sfp->f_ref, sg_remove_sfp); } else - sg_finish_rem_req(srp); /* call with srp->done == 0 */ - - kref_put(&sfp->f_ref, sg_remove_sfp); + execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew); } static struct file_operations sg_fops = {