diff options
-rw-r--r-- | drivers/mtd/mtd_blkdevs.c | 26 | ||||
-rw-r--r-- | include/linux/mtd/blktrans.h | 2 |
2 files changed, 28 insertions, 0 deletions
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 344ac10..e0b5f644 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -119,11 +119,22 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, } } +int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) +{ + if (kthread_should_stop()) + return 1; + + return !elv_queue_empty(dev->rq); +} +EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); + static int mtd_blktrans_thread(void *arg) { struct mtd_blktrans_dev *dev = arg; + struct mtd_blktrans_ops *tr = dev->tr; struct request_queue *rq = dev->rq; struct request *req = NULL; + int background_done = 0; spin_lock_irq(rq->queue_lock); @@ -131,6 +142,19 @@ static int mtd_blktrans_thread(void *arg) int res; if (!req && !(req = blk_fetch_request(rq))) { + if (tr->background && !background_done) { + spin_unlock_irq(rq->queue_lock); + mutex_lock(&dev->lock); + tr->background(dev); + mutex_unlock(&dev->lock); + spin_lock_irq(rq->queue_lock); + /* + * Do background processing just once per idle + * period. + */ + background_done = 1; + continue; + } set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) @@ -152,6 +176,8 @@ static int mtd_blktrans_thread(void *arg) if (!__blk_end_request_cur(req, res)) req = NULL; + + background_done = 0; } if (req) diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h index 26529eb..66bec4b 100644 --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h @@ -62,6 +62,7 @@ struct mtd_blktrans_ops { unsigned long block, char *buffer); int (*discard)(struct mtd_blktrans_dev *dev, unsigned long block, unsigned nr_blocks); + void (*background)(struct mtd_blktrans_dev *dev); /* Block layer ioctls */ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); @@ -85,6 +86,7 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); +extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); #endif /* __MTD_TRANS_H__ */ |