Index: SCRATCH/drivers/char/raw.c =================================================================== --- SCRATCH.orig/drivers/char/raw.c 2003-08-25 15:06:40.000000000 +0200 +++ SCRATCH/drivers/char/raw.c 2003-08-25 15:11:17.000000000 +0200 @@ -470,6 +470,8 @@ int raw_kvec_rw(struct file *filp, int r goto out; } + cb.dovary = raw_devices[minor].varyio; + /* * Split the IO into KIO_MAX_SECTORS chunks, mapping and * unmapping the single kiobuf as we go to perform each chunk of Index: SCRATCH/fs/aio.c =================================================================== --- SCRATCH.orig/fs/aio.c 2003-08-25 15:06:39.000000000 +0200 +++ SCRATCH/fs/aio.c 2003-08-25 15:11:17.000000000 +0200 @@ -1077,6 +1077,7 @@ static void generic_aio_next_chunk(void cb.fn = (rw == READ) ? generic_aio_complete_read : generic_aio_complete_write; cb.data = iocb; + cb.dovary = 0; dprintk("generic_aio_rw: cb.vec=%p\n", cb.vec); if (unlikely(IS_ERR(cb.vec))) @@ -1179,6 +1180,7 @@ ssize_t generic_aio_rw(int rw, struct fi cb.fn = (rw == READ) ? generic_aio_complete_read : generic_aio_complete_write; cb.data = req; + cb.dovary = 0; dprintk("generic_aio_rw: cb.vec=%p\n", cb.vec); if (IS_ERR(cb.vec)) Index: SCRATCH/fs/buffer.c =================================================================== --- SCRATCH.orig/fs/buffer.c 2003-08-25 15:06:41.000000000 +0200 +++ SCRATCH/fs/buffer.c 2003-08-25 15:11:17.000000000 +0200 @@ -3237,6 +3237,8 @@ int brw_kvec_async(int rw, kvec_cb_t cb, unsigned sector_size = 1 << sector_shift; int i; unsigned int atomic_seq; + int dovary = cb.dovary; + int iosize; struct brw_cb *brw_cb; @@ -3292,19 +3294,27 @@ int brw_kvec_async(int rw, kvec_cb_t cb, while (length > 0) { struct buffer_head *tmp; + iosize = sector_size; tmp = kmem_cache_alloc(bh_cachep, GFP_NOIO); err = -ENOMEM; if (!tmp) goto error; + if (dovary && ((offset & RAWIO_BLOCKMASK) == 0)) { + iosize = RAWIO_BLOCKSIZE; + if (iosize > length) + iosize = length; + } + tmp->b_dev = B_FREE; - tmp->b_size = sector_size; + tmp->b_size = iosize; set_bh_page(tmp, page, offset); tmp->b_this_page = tmp; init_buffer(tmp, end_buffer_io_kiobuf_async, NULL); tmp->b_dev = dev; - tmp->b_blocknr = blknr++; + tmp->b_blocknr = blknr; + blknr += iosize >> sector_shift; tmp->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | (1 << BH_Req) | (1 << BH_Atomic); bh_elv_seq(tmp) = atomic_seq; @@ -3316,8 +3326,8 @@ int brw_kvec_async(int rw, kvec_cb_t cb, } brw_cb->bh[brw_cb->nr++] = tmp; - length -= sector_size; - offset += sector_size; + length -= iosize; + offset += iosize; if (offset >= PAGE_SIZE) { offset = 0; @@ -3332,8 +3342,13 @@ int brw_kvec_async(int rw, kvec_cb_t cb, submit: atomic_set(&brw_cb->io_count, brw_cb->nr+1); /* okay, we've setup all our io requests, now fire them off! */ - for (i=0; inr; i++) - submit_bh(rw, brw_cb->bh[i]); + for (i=0; inr; i++) { + if (dovary) { + brw_cb->bh[i]->b_blocknr *= sector_size >> 9; + submit_bh_blknr(rw, brw_cb->bh[i]); + } else + submit_bh(rw, brw_cb->bh[i]); + } brw_cb_put(brw_cb); if (atomic_seq) blk_refile_atomic_queue(atomic_seq); Index: SCRATCH/include/linux/kiovec.h =================================================================== --- SCRATCH.orig/include/linux/kiovec.h 2003-08-25 15:06:39.000000000 +0200 +++ SCRATCH/include/linux/kiovec.h 2003-08-25 15:11:17.000000000 +0200 @@ -21,6 +21,7 @@ struct kvec_cb { struct kvec *vec; void (*fn)(void *data, struct kvec *vec, ssize_t res); void *data; + int dovary; }; struct kvec_cb_list {