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);
|
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)
|
static void sftl_make_request(struct request_queue *q, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct sftl_dev *sftl = (struct sftl_dev*)q->queuedata;
|
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));
|
(unsigned long)bio->bi_sector, (unsigned long)bio_sectors(bio));
|
||||||
if (sftl->buf_size >= sftl->buf_max)
|
if (sftl->buf_size >= sftl->buf_max)
|
||||||
{
|
{
|
||||||
// Need to flush the buffer before completing this bio
|
// Need to flush current buffer before completing this bio
|
||||||
int err = bio_submit_kern_seq(sftl->blkdev, sftl->buf, seg_clust*clust_sz+phy_sz, GFP_KERNEL,
|
void *buf = sftl->buf;
|
||||||
sftl->nextfreeseg*(seg_clust*clust_blocks+1), bio, sftl_complete_seg, WRITE);
|
struct sftl_buf_info *info = kmalloc(sizeof(struct sftl_buf_info), GFP_KERNEL);
|
||||||
if (err)
|
int err;
|
||||||
bio_endio(bio, -EIO);
|
info->free_buf = buf;
|
||||||
// FIXME Is it correct?.. I think no...
|
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;
|
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
|
// FIXME Correctly adjust free segment address
|
||||||
sftl->nextfreeseg++;
|
sftl->nextfreeseg++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
bio_endio(bio, 0);
|
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;
|
struct bio_seq *seq = bio->bi_private;
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
INFO("I/O err %d", err);
|
INFO("I/O error %d", err);
|
||||||
seq->err = err;
|
seq->err = err;
|
||||||
}
|
}
|
||||||
if (atomic_dec_and_test(&seq->count))
|
if (atomic_dec_and_test(&seq->count))
|
||||||
|
@ -362,6 +385,7 @@ static long bio_submit_kern_seq(
|
||||||
int n = 1;
|
int n = 1;
|
||||||
bio->bi_private = NULL;
|
bio->bi_private = NULL;
|
||||||
bio->bi_end_io = bio_map_kern_seq_endio;
|
bio->bi_end_io = bio_map_kern_seq_endio;
|
||||||
|
seq->err = 0;
|
||||||
seq->endio = endio;
|
seq->endio = endio;
|
||||||
seq->private = private;
|
seq->private = private;
|
||||||
data += bio->bi_size;
|
data += bio->bi_size;
|
||||||
|
@ -382,13 +406,13 @@ static long bio_submit_kern_seq(
|
||||||
}
|
}
|
||||||
return PTR_ERR(bio2);
|
return PTR_ERR(bio2);
|
||||||
}
|
}
|
||||||
data += bio2->bi_size;
|
|
||||||
len -= bio2->bi_size;
|
|
||||||
sector += bio2->bi_size >> 9;
|
|
||||||
bio2->bi_bdev = bdev;
|
bio2->bi_bdev = bdev;
|
||||||
bio2->bi_sector = sector;
|
bio2->bi_sector = sector;
|
||||||
bio2->bi_private = bio;
|
bio2->bi_private = bio;
|
||||||
bio2->bi_end_io = bio_map_kern_seq_endio;
|
bio2->bi_end_io = bio_map_kern_seq_endio;
|
||||||
|
data += bio2->bi_size;
|
||||||
|
len -= bio2->bi_size;
|
||||||
|
sector += bio2->bi_size >> 9;
|
||||||
bio = bio2;
|
bio = bio2;
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue