mirror of https://gitee.com/openkylin/linux.git
bcache: store a pointer to the on-disk sb in the cache and cached_dev structures
This allows to properly build the superblock bio including the offset in the page using the normal bio helpers. This fixes writing the superblock for page sizes larger than 4k where the sb write bio would need an offset in the bio_vec. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Coly Li <colyli@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
cfa0c56db9
commit
475389ae5c
|
@ -301,6 +301,7 @@ struct cached_dev {
|
||||||
struct block_device *bdev;
|
struct block_device *bdev;
|
||||||
|
|
||||||
struct cache_sb sb;
|
struct cache_sb sb;
|
||||||
|
struct cache_sb_disk *sb_disk;
|
||||||
struct bio sb_bio;
|
struct bio sb_bio;
|
||||||
struct bio_vec sb_bv[1];
|
struct bio_vec sb_bv[1];
|
||||||
struct closure sb_write;
|
struct closure sb_write;
|
||||||
|
@ -403,6 +404,7 @@ enum alloc_reserve {
|
||||||
struct cache {
|
struct cache {
|
||||||
struct cache_set *set;
|
struct cache_set *set;
|
||||||
struct cache_sb sb;
|
struct cache_sb sb;
|
||||||
|
struct cache_sb_disk *sb_disk;
|
||||||
struct bio sb_bio;
|
struct bio sb_bio;
|
||||||
struct bio_vec sb_bv[1];
|
struct bio_vec sb_bv[1];
|
||||||
|
|
||||||
|
|
|
@ -207,15 +207,15 @@ static void write_bdev_super_endio(struct bio *bio)
|
||||||
closure_put(&dc->sb_write);
|
closure_put(&dc->sb_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __write_super(struct cache_sb *sb, struct bio *bio)
|
static void __write_super(struct cache_sb *sb, struct cache_sb_disk *out,
|
||||||
|
struct bio *bio)
|
||||||
{
|
{
|
||||||
struct cache_sb_disk *out = page_address(bio_first_page_all(bio));
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_META;
|
||||||
bio->bi_iter.bi_sector = SB_SECTOR;
|
bio->bi_iter.bi_sector = SB_SECTOR;
|
||||||
bio->bi_iter.bi_size = SB_SIZE;
|
__bio_add_page(bio, virt_to_page(out), SB_SIZE,
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC|REQ_META);
|
offset_in_page(out));
|
||||||
bch_bio_map(bio, NULL);
|
|
||||||
|
|
||||||
out->offset = cpu_to_le64(sb->offset);
|
out->offset = cpu_to_le64(sb->offset);
|
||||||
out->version = cpu_to_le64(sb->version);
|
out->version = cpu_to_le64(sb->version);
|
||||||
|
@ -257,14 +257,14 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
|
||||||
down(&dc->sb_write_mutex);
|
down(&dc->sb_write_mutex);
|
||||||
closure_init(cl, parent);
|
closure_init(cl, parent);
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_init(bio, dc->sb_bv, 1);
|
||||||
bio_set_dev(bio, dc->bdev);
|
bio_set_dev(bio, dc->bdev);
|
||||||
bio->bi_end_io = write_bdev_super_endio;
|
bio->bi_end_io = write_bdev_super_endio;
|
||||||
bio->bi_private = dc;
|
bio->bi_private = dc;
|
||||||
|
|
||||||
closure_get(cl);
|
closure_get(cl);
|
||||||
/* I/O request sent to backing device */
|
/* I/O request sent to backing device */
|
||||||
__write_super(&dc->sb, bio);
|
__write_super(&dc->sb, dc->sb_disk, bio);
|
||||||
|
|
||||||
closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
|
closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
|
||||||
}
|
}
|
||||||
|
@ -306,13 +306,13 @@ void bcache_write_super(struct cache_set *c)
|
||||||
|
|
||||||
SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb));
|
SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb));
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_init(bio, ca->sb_bv, 1);
|
||||||
bio_set_dev(bio, ca->bdev);
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_end_io = write_super_endio;
|
bio->bi_end_io = write_super_endio;
|
||||||
bio->bi_private = ca;
|
bio->bi_private = ca;
|
||||||
|
|
||||||
closure_get(cl);
|
closure_get(cl);
|
||||||
__write_super(&ca->sb, bio);
|
__write_super(&ca->sb, ca->sb_disk, bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
closure_return_with_destructor(cl, bcache_write_super_unlock);
|
closure_return_with_destructor(cl, bcache_write_super_unlock);
|
||||||
|
@ -1275,8 +1275,8 @@ static void cached_dev_free(struct closure *cl)
|
||||||
|
|
||||||
mutex_unlock(&bch_register_lock);
|
mutex_unlock(&bch_register_lock);
|
||||||
|
|
||||||
if (dc->sb_bio.bi_inline_vecs[0].bv_page)
|
if (dc->sb_disk)
|
||||||
put_page(bio_first_page_all(&dc->sb_bio));
|
put_page(virt_to_page(dc->sb_disk));
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(dc->bdev))
|
if (!IS_ERR_OR_NULL(dc->bdev))
|
||||||
blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
||||||
|
@ -1365,9 +1365,7 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||||
memcpy(&dc->sb, sb, sizeof(struct cache_sb));
|
memcpy(&dc->sb, sb, sizeof(struct cache_sb));
|
||||||
dc->bdev = bdev;
|
dc->bdev = bdev;
|
||||||
dc->bdev->bd_holder = dc;
|
dc->bdev->bd_holder = dc;
|
||||||
|
dc->sb_disk = sb_disk;
|
||||||
bio_init(&dc->sb_bio, dc->sb_bio.bi_inline_vecs, 1);
|
|
||||||
bio_first_bvec_all(&dc->sb_bio)->bv_page = virt_to_page(sb_disk);
|
|
||||||
|
|
||||||
if (cached_dev_init(dc, sb->block_size << 9))
|
if (cached_dev_init(dc, sb->block_size << 9))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -2137,8 +2135,8 @@ void bch_cache_release(struct kobject *kobj)
|
||||||
for (i = 0; i < RESERVE_NR; i++)
|
for (i = 0; i < RESERVE_NR; i++)
|
||||||
free_fifo(&ca->free[i]);
|
free_fifo(&ca->free[i]);
|
||||||
|
|
||||||
if (ca->sb_bio.bi_inline_vecs[0].bv_page)
|
if (ca->sb_disk)
|
||||||
put_page(bio_first_page_all(&ca->sb_bio));
|
put_page(virt_to_page(ca->sb_disk));
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(ca->bdev))
|
if (!IS_ERR_OR_NULL(ca->bdev))
|
||||||
blkdev_put(ca->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
blkdev_put(ca->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
||||||
|
@ -2270,9 +2268,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||||
memcpy(&ca->sb, sb, sizeof(struct cache_sb));
|
memcpy(&ca->sb, sb, sizeof(struct cache_sb));
|
||||||
ca->bdev = bdev;
|
ca->bdev = bdev;
|
||||||
ca->bdev->bd_holder = ca;
|
ca->bdev->bd_holder = ca;
|
||||||
|
ca->sb_disk = sb_disk;
|
||||||
bio_init(&ca->sb_bio, ca->sb_bio.bi_inline_vecs, 1);
|
|
||||||
bio_first_bvec_all(&ca->sb_bio)->bv_page = virt_to_page(sb_disk);
|
|
||||||
|
|
||||||
if (blk_queue_discard(bdev_get_queue(bdev)))
|
if (blk_queue_discard(bdev_get_queue(bdev)))
|
||||||
ca->discard = CACHE_DISCARD(&ca->sb);
|
ca->discard = CACHE_DISCARD(&ca->sb);
|
||||||
|
|
Loading…
Reference in New Issue