Stupidly switch buffer
parent
b814b86302
commit
b39ce6cd68
48
sftl.c
48
sftl.c
|
@ -91,6 +91,21 @@ static void sftl_complete_seg(struct bio *bio, int err)
|
|||
bio_put(bio);
|
||||
}
|
||||
|
||||
struct sftl_buf_info
|
||||
{
|
||||
struct bio *complete_bio;
|
||||
void *free_buf;
|
||||
};
|
||||
|
||||
static void sftl_complete_buf(struct bio *bio, int err)
|
||||
{
|
||||
struct sftl_buf_info *i = bio->bi_private;
|
||||
bio_endio(i->complete_bio, err);
|
||||
bio_put(bio);
|
||||
kfree(i->free_buf);
|
||||
kfree(i);
|
||||
}
|
||||
|
||||
static void sftl_make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
struct sftl_dev *sftl = (struct sftl_dev*)q->queuedata;
|
||||
|
@ -151,20 +166,28 @@ static void sftl_make_request(struct request_queue *q, struct bio *bio)
|
|||
(unsigned long)bio->bi_sector, (unsigned long)bio_sectors(bio));
|
||||
if (sftl->buf_size >= sftl->buf_max)
|
||||
{
|
||||
// Need to flush the buffer before completing this bio
|
||||
int err = bio_submit_kern_seq(sftl->blkdev, sftl->buf, seg_clust*clust_sz+phy_sz, GFP_KERNEL,
|
||||
sftl->nextfreeseg*(seg_clust*clust_blocks+1), bio, sftl_complete_seg, WRITE);
|
||||
if (err)
|
||||
bio_endio(bio, -EIO);
|
||||
// FIXME Is it correct?.. I think no...
|
||||
// Need to flush current buffer before completing this bio
|
||||
void *buf = sftl->buf;
|
||||
struct sftl_buf_info *info = kmalloc(sizeof(struct sftl_buf_info), GFP_KERNEL);
|
||||
int err;
|
||||
info->free_buf = buf;
|
||||
info->complete_bio = bio;
|
||||
// We stupidly switch buffer (there always will be a finite number of those)
|
||||
sftl->buf = kmalloc(seg_clust*clust_sz + phy_sz, GFP_KERNEL);
|
||||
sftl->buf_size = 0;
|
||||
err = bio_submit_kern_seq(sftl->blkdev, buf, seg_clust*clust_sz+phy_sz, GFP_KERNEL,
|
||||
sftl->nextfreeseg*(seg_clust*clust_blocks+1), info, sftl_complete_buf, WRITE);
|
||||
if (err)
|
||||
{
|
||||
bio_endio(bio, -EIO);
|
||||
kfree(buf);
|
||||
kfree(info);
|
||||
}
|
||||
// FIXME Correctly adjust free segment address
|
||||
sftl->nextfreeseg++;
|
||||
}
|
||||
else
|
||||
{
|
||||
bio_endio(bio, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +341,7 @@ static void bio_map_kern_seq_endio(struct bio *bio, int err)
|
|||
struct bio_seq *seq = bio->bi_private;
|
||||
if (err)
|
||||
{
|
||||
INFO("I/O err %d", err);
|
||||
INFO("I/O error %d", err);
|
||||
seq->err = err;
|
||||
}
|
||||
if (atomic_dec_and_test(&seq->count))
|
||||
|
@ -362,6 +385,7 @@ static long bio_submit_kern_seq(
|
|||
int n = 1;
|
||||
bio->bi_private = NULL;
|
||||
bio->bi_end_io = bio_map_kern_seq_endio;
|
||||
seq->err = 0;
|
||||
seq->endio = endio;
|
||||
seq->private = private;
|
||||
data += bio->bi_size;
|
||||
|
@ -382,13 +406,13 @@ static long bio_submit_kern_seq(
|
|||
}
|
||||
return PTR_ERR(bio2);
|
||||
}
|
||||
data += bio2->bi_size;
|
||||
len -= bio2->bi_size;
|
||||
sector += bio2->bi_size >> 9;
|
||||
bio2->bi_bdev = bdev;
|
||||
bio2->bi_sector = sector;
|
||||
bio2->bi_private = bio;
|
||||
bio2->bi_end_io = bio_map_kern_seq_endio;
|
||||
data += bio2->bi_size;
|
||||
len -= bio2->bi_size;
|
||||
sector += bio2->bi_size >> 9;
|
||||
bio = bio2;
|
||||
n++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue