aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtd_blkdevs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtd_blkdevs.c')
-rw-r--r--drivers/mtd/mtd_blkdevs.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index e0a2373bf0e2..a534e1f0c348 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -40,7 +40,7 @@
40static LIST_HEAD(blktrans_majors); 40static LIST_HEAD(blktrans_majors);
41static DEFINE_MUTEX(blktrans_ref_mutex); 41static DEFINE_MUTEX(blktrans_ref_mutex);
42 42
43void blktrans_dev_release(struct kref *kref) 43static void blktrans_dev_release(struct kref *kref)
44{ 44{
45 struct mtd_blktrans_dev *dev = 45 struct mtd_blktrans_dev *dev =
46 container_of(kref, struct mtd_blktrans_dev, ref); 46 container_of(kref, struct mtd_blktrans_dev, ref);
@@ -67,7 +67,7 @@ unlock:
67 return dev; 67 return dev;
68} 68}
69 69
70void blktrans_dev_put(struct mtd_blktrans_dev *dev) 70static void blktrans_dev_put(struct mtd_blktrans_dev *dev)
71{ 71{
72 mutex_lock(&blktrans_ref_mutex); 72 mutex_lock(&blktrans_ref_mutex);
73 kref_put(&dev->ref, blktrans_dev_release); 73 kref_put(&dev->ref, blktrans_dev_release);
@@ -119,18 +119,43 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
119 } 119 }
120} 120}
121 121
122int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
123{
124 if (kthread_should_stop())
125 return 1;
126
127 return dev->bg_stop;
128}
129EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
130
122static int mtd_blktrans_thread(void *arg) 131static int mtd_blktrans_thread(void *arg)
123{ 132{
124 struct mtd_blktrans_dev *dev = arg; 133 struct mtd_blktrans_dev *dev = arg;
134 struct mtd_blktrans_ops *tr = dev->tr;
125 struct request_queue *rq = dev->rq; 135 struct request_queue *rq = dev->rq;
126 struct request *req = NULL; 136 struct request *req = NULL;
137 int background_done = 0;
127 138
128 spin_lock_irq(rq->queue_lock); 139 spin_lock_irq(rq->queue_lock);
129 140
130 while (!kthread_should_stop()) { 141 while (!kthread_should_stop()) {
131 int res; 142 int res;
132 143
144 dev->bg_stop = false;
133 if (!req && !(req = blk_fetch_request(rq))) { 145 if (!req && !(req = blk_fetch_request(rq))) {
146 if (tr->background && !background_done) {
147 spin_unlock_irq(rq->queue_lock);
148 mutex_lock(&dev->lock);
149 tr->background(dev);
150 mutex_unlock(&dev->lock);
151 spin_lock_irq(rq->queue_lock);
152 /*
153 * Do background processing just once per idle
154 * period.
155 */
156 background_done = !dev->bg_stop;
157 continue;
158 }
134 set_current_state(TASK_INTERRUPTIBLE); 159 set_current_state(TASK_INTERRUPTIBLE);
135 160
136 if (kthread_should_stop()) 161 if (kthread_should_stop())
@@ -152,6 +177,8 @@ static int mtd_blktrans_thread(void *arg)
152 177
153 if (!__blk_end_request_cur(req, res)) 178 if (!__blk_end_request_cur(req, res))
154 req = NULL; 179 req = NULL;
180
181 background_done = 0;
155 } 182 }
156 183
157 if (req) 184 if (req)
@@ -172,8 +199,10 @@ static void mtd_blktrans_request(struct request_queue *rq)
172 if (!dev) 199 if (!dev)
173 while ((req = blk_fetch_request(rq)) != NULL) 200 while ((req = blk_fetch_request(rq)) != NULL)
174 __blk_end_request_all(req, -ENODEV); 201 __blk_end_request_all(req, -ENODEV);
175 else 202 else {
203 dev->bg_stop = true;
176 wake_up_process(dev->thread); 204 wake_up_process(dev->thread);
205 }
177} 206}
178 207
179static int blktrans_open(struct block_device *bdev, fmode_t mode) 208static int blktrans_open(struct block_device *bdev, fmode_t mode)
@@ -379,9 +408,10 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
379 new->rq->queuedata = new; 408 new->rq->queuedata = new;
380 blk_queue_logical_block_size(new->rq, tr->blksize); 409 blk_queue_logical_block_size(new->rq, tr->blksize);
381 410
382 if (tr->discard) 411 if (tr->discard) {
383 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, 412 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq);
384 new->rq); 413 new->rq->limits.max_discard_sectors = UINT_MAX;
414 }
385 415
386 gd->queue = new->rq; 416 gd->queue = new->rq;
387 417