Networked storage devices need a swap-on/off callback in order to setup some state and reserve memory. Place the block device callback in the request_queue as suggested by James Bottomley. Signed-off-by: Peter Zijlstra Cc: Jens Axboe Cc: James Bottomley --- include/linux/blkdev.h | 19 +++++++++++++++++++ mm/swapfile.c | 4 ++++ 2 files changed, 23 insertions(+) Index: linux-2.6-git/include/linux/blkdev.h =================================================================== --- linux-2.6-git.orig/include/linux/blkdev.h 2007-01-08 11:53:13.000000000 +0100 +++ linux-2.6-git/include/linux/blkdev.h 2007-01-16 14:14:50.000000000 +0100 @@ -341,6 +341,7 @@ typedef int (merge_bvec_fn) (request_que typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *); typedef void (prepare_flush_fn) (request_queue_t *, struct request *); typedef void (softirq_done_fn)(struct request *); +typedef int (swapdev_fn)(void*, int); enum blk_queue_state { Queue_down, @@ -379,6 +380,8 @@ struct request_queue issue_flush_fn *issue_flush_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; + swapdev_fn *swapdev_fn; + void *swapdev_obj; /* * Dispatch queue sorting @@ -766,6 +769,22 @@ request_queue_t *blk_alloc_queue(gfp_t); request_queue_t *blk_alloc_queue_node(gfp_t, int); extern void blk_put_queue(request_queue_t *); +static inline +void blk_queue_swapdev(struct request_queue *rq, + swapdev_fn *swapdev_fn, void *swapdev_obj) +{ + rq->swapdev_fn = swapdev_fn; + rq->swapdev_obj = swapdev_obj; +} + +static inline +int blk_queue_swapdev_fn(struct request_queue *rq, int enable) +{ + if (rq->swapdev_fn) + return rq->swapdev_fn(rq->swapdev_obj, enable); + return 0; +} + /* * tag stuff */ Index: linux-2.6-git/mm/swapfile.c =================================================================== --- linux-2.6-git.orig/mm/swapfile.c 2007-01-15 09:59:02.000000000 +0100 +++ linux-2.6-git/mm/swapfile.c 2007-01-16 14:14:50.000000000 +0100 @@ -1305,6 +1305,7 @@ asmlinkage long sys_swapoff(const char _ inode = mapping->host; if (S_ISBLK(inode->i_mode)) { struct block_device *bdev = I_BDEV(inode); + blk_queue_swapdev_fn(bdev->bd_disk->queue, 0); set_blocksize(bdev, p->old_block_size); bd_release(bdev); } else { @@ -1524,6 +1525,9 @@ asmlinkage long sys_swapon(const char __ error = set_blocksize(bdev, PAGE_SIZE); if (error < 0) goto bad_swap; + error = blk_queue_swapdev_fn(bdev->bd_disk->queue, 1); + if (error < 0) + goto bad_swap; p->bdev = bdev; } else if (S_ISREG(inode->i_mode)) { p->bdev = inode->i_sb->s_bdev; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/