Re: ext2 on a CD-RW

From: Peter Osterlund
Date: Fri Jan 02 2004 - 11:16:13 EST


Jens Axboe <axboe@xxxxxxx> writes:

> On Fri, Jan 02 2004, Peter Osterlund wrote:
> >
> > Old versions of the packet writing code did just that, but Jens told
> > me that bio splitting was evil, so when the merge_bvec_fn
> > functionality was added to the kernel, I started to use it.
> >
> > http://lists.suse.com/archive/packet-writing/2002-Aug/0044.html
>
> Splitting is evil, but unfortunately it's a necessary evil... There are
> a few kernel helpers to make supporting it easier (see bio_split()). Not
> so sure how well that'll work for you, you may have to do the grunt work
> yourself.

It seems like bio_split() does exactly what I need. The patch below
makes 2kb blocksize ext2 work and also fixes the performance problem
compared to 4kb blocksize ext2. Thanks to everyone involved for their
help.

--- linux/drivers/block/pktcdvd.c.old 2004-01-02 16:58:52.000000000 +0100
+++ linux/drivers/block/pktcdvd.c 2004-01-02 16:59:26.000000000 +0100
@@ -2083,11 +2083,23 @@
(unsigned long long)bio->bi_sector,
(unsigned long long)(bio->bi_sector + bio_sectors(bio)));

- /* Some debug code to make sure the merge_bvec_fn function is working. */
+ /* Check if we have to split the bio */
{
+ struct bio_pair *bp;
sector_t last_zone;
+ int first_sectors;
+
last_zone = ZONE(bio->bi_sector + bio_sectors(bio) - 1, pd);
- BUG_ON(last_zone != zone);
+ if (last_zone != zone) {
+ BUG_ON(last_zone != zone + pd->settings.size);
+ first_sectors = last_zone - bio->bi_sector;
+ bp = bio_split(bio, bio_split_pool, first_sectors);
+ BUG_ON(!bp);
+ pkt_make_request(q, &bp->bio1);
+ pkt_make_request(q, &bp->bio2);
+ bio_pair_release(bp);
+ return 0;
+ }
}

/*
@@ -2153,6 +2165,15 @@
sector_t zone = ZONE(bio->bi_sector, pd);
int used = ((bio->bi_sector - zone) << 9) + bio->bi_size;
int remaining = (pd->settings.size << 9) - used;
+ int remaining2;
+
+ /*
+ * A bio <= PAGE_SIZE must be allowed. If it crosses a packet
+ * boundary, pkt_make_request() will split the bio.
+ */
+ remaining2 = PAGE_SIZE - bio->bi_size;
+ remaining = max_t(int, remaining, remaining2);
+
BUG_ON(remaining < 0);
return remaining;
}

--
Peter Osterlund - petero2@xxxxxxxxx
http://w1.894.telia.com/~u89404340
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/