[DRBD-cvs] r1769 - trunk/drbd
www-data
www-data at garcon.linbit.com
Thu Mar 17 14:05:18 CET 2005
Author: phil
Date: 2005-03-17 14:05:16 +0100 (Thu, 17 Mar 2005)
New Revision: 1769
Modified:
trunk/drbd/drbd_compat_wrappers.h
trunk/drbd/drbd_fs.c
trunk/drbd/drbd_int.h
trunk/drbd/drbd_receiver.c
trunk/drbd/drbd_req.c
Log:
This fixes the last known open issue with the big BIO support.
* With drbd_merge_bvec() callback we tell the rest of the kernel
that we do not like BIOs that cross our AL_EXTENT boundaries.
* I take into account that the device below us might have a
merge_bvec() function by itself, therefore we must provide
the sector number before calling bio_add_page()
* biot_add_page() might fail! -- still open
Modified: trunk/drbd/drbd_compat_wrappers.h
===================================================================
--- trunk/drbd/drbd_compat_wrappers.h 2005-03-15 20:51:32 UTC (rev 1768)
+++ trunk/drbd/drbd_compat_wrappers.h 2005-03-17 13:05:16 UTC (rev 1769)
@@ -157,18 +157,14 @@
}
static inline void
-drbd_ee_prepare_write(drbd_dev *mdev, struct Tl_epoch_entry* e,
- sector_t sector)
+drbd_ee_prepare_write(drbd_dev *mdev, struct Tl_epoch_entry* e)
{
- e->ee_sector = e->private_bio->bi_sector = sector;
e->private_bio->bi_end_io = drbd_dio_end_sec;
}
static inline void
-drbd_ee_prepare_read(drbd_dev *mdev, struct Tl_epoch_entry* e,
- sector_t sector)
+drbd_ee_prepare_read(drbd_dev *mdev, struct Tl_epoch_entry* e)
{
- e->ee_sector = e->private_bio->bi_sector = sector;
e->private_bio->bi_end_io = enslaved_read_bi_end_io;
}
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2005-03-15 20:51:32 UTC (rev 1768)
+++ trunk/drbd/drbd_fs.c 2005-03-17 13:05:16 UTC (rev 1769)
@@ -382,6 +382,7 @@
q->hardsect_size = max((unsigned short)512,b->hardsect_size);
q->seg_boundary_mask = PAGE_SIZE-1;
D_ASSERT(q->hardsect_size <= PAGE_SIZE); // or we are really screwed ;-)
+ blk_queue_merge_bvec(q, drbd_merge_bvec);
#undef min_not_zero
set_bit(MD_IO_ALLOWED,&mdev->flags);
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2005-03-15 20:51:32 UTC (rev 1768)
+++ trunk/drbd/drbd_int.h 2005-03-17 13:05:16 UTC (rev 1769)
@@ -1005,6 +1005,7 @@
extern void drbd_end_req(drbd_request_t *, int, int, sector_t);
extern int drbd_make_request_26(request_queue_t *q, struct bio *bio);
extern int drbd_read_remote(drbd_dev *mdev, drbd_request_t *req);
+extern int drbd_merge_bvec(request_queue_t *, struct bio *, struct bio_vec *);
// drbd_fs.c
extern char* ppsize(char* buf, size_t size);
@@ -1038,6 +1039,7 @@
// drbd_receiver.c
extern int drbd_release_ee(drbd_dev* mdev,struct list_head* list);
extern struct Tl_epoch_entry* drbd_alloc_ee(drbd_dev *mdev,
+ sector_t sector,
unsigned int data_size,
unsigned int gfp_mask);
extern void drbd_free_ee(drbd_dev *mdev, struct Tl_epoch_entry* e);
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2005-03-15 20:51:32 UTC (rev 1768)
+++ trunk/drbd/drbd_receiver.c 2005-03-17 13:05:16 UTC (rev 1769)
@@ -237,6 +237,7 @@
*/
struct Tl_epoch_entry* drbd_alloc_ee(drbd_dev *mdev,
+ sector_t sector,
unsigned int data_size,
unsigned int gfp_mask)
{
@@ -245,7 +246,7 @@
struct page *page;
struct bio *bio;
unsigned int ds;
- int i;
+ int bio_add,i;
e = kmem_cache_alloc(drbd_ee_cache, gfp_mask);
if (!e) return NULL;
@@ -254,17 +255,20 @@
if (!bio) goto fail1;
bio->bi_bdev = mdev->backing_bdev;
-
+ bio->bi_sector = sector;
+
ds = data_size;
while(ds) {
page = drbd_pp_alloc(mdev, gfp_mask);
if (!page) goto fail2;
- bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0);
+ bio_add=bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0);
+ D_ASSERT(bio_add);
ds -= min_t(int, ds, PAGE_SIZE);
}
bio->bi_private = e;
e->mdev = mdev;
+ e->ee_sector = sector;
e->ee_size = bio->bi_size;
D_ASSERT( data_size == bio->bi_size);
e->private_bio = bio;
@@ -776,7 +780,7 @@
}
STATIC struct Tl_epoch_entry *
-read_in_block(drbd_dev *mdev, int data_size)
+read_in_block(drbd_dev *mdev, sector_t sector, int data_size)
{
struct Tl_epoch_entry *e;
struct bio_vec *bvec;
@@ -784,7 +788,7 @@
struct bio *bio;
int ds,i,rr;
- e = drbd_alloc_ee(mdev,data_size,GFP_KERNEL);
+ e = drbd_alloc_ee(mdev,sector,data_size,GFP_KERNEL);
if(!e) return 0;
bio = e->private_bio;
ds = data_size;
@@ -883,7 +887,7 @@
{
struct Tl_epoch_entry *e;
- e = read_in_block(mdev,data_size);
+ e = read_in_block(mdev,sector,data_size);
if(!e) return FALSE;
dec_rs_pending(mdev);
@@ -897,7 +901,7 @@
return TRUE;
}
- drbd_ee_prepare_write(mdev,e,sector);
+ drbd_ee_prepare_write(mdev,e);
e->w.cb = e_end_resync_block;
spin_lock_irq(&mdev->ee_lock);
@@ -1055,7 +1059,7 @@
return FALSE;
sector = be64_to_cpu(p->sector);
- e = read_in_block(mdev,data_size);
+ e = read_in_block(mdev,sector,data_size);
if (!e) return FALSE;
if(!inc_local(mdev)) {
@@ -1067,7 +1071,7 @@
}
e->block_id = p->block_id; // no meaning on this side, e* on partner
- drbd_ee_prepare_write(mdev, e, sector);
+ drbd_ee_prepare_write(mdev, e);
e->w.cb = e_end_block;
/* This wait_event is here to make sure that never ever an
@@ -1201,7 +1205,7 @@
return FALSE;
}
- e = drbd_alloc_ee(mdev,size,GFP_KERNEL);
+ e = drbd_alloc_ee(mdev,sector,size,GFP_KERNEL);
if (!e) return FALSE;
e->block_id = p->block_id; // no meaning on this side, pr* on partner
@@ -1217,7 +1221,7 @@
return TRUE;
}
- drbd_ee_prepare_read(mdev,e,sector);
+ drbd_ee_prepare_read(mdev,e);
switch (h->command) {
case DataRequest:
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2005-03-15 20:51:32 UTC (rev 1768)
+++ trunk/drbd/drbd_req.c 2005-03-17 13:05:16 UTC (rev 1769)
@@ -401,3 +401,32 @@
return drbd_make_request_common(mdev,bio_rw(bio),bio->bi_size,
bio->bi_sector,bio);
}
+
+/* This is called by bio_add_page(). With this function we prevent
+ that we get BIOs that span over multiple AL_EXTENTs.
+ */
+int drbd_merge_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *bvec)
+{
+ unsigned int s = (unsigned int)bio->bi_sector << 9; // 32 bit...
+ unsigned int t;
+
+ if (bio->bi_size == 0) {
+ s = max_t(unsigned int,
+ AL_EXTENT_SIZE - (s & (AL_EXTENT_SIZE-1)),
+ PAGE_SIZE);
+ // As long as the BIO is emtpy we allow at least one page.
+ } else {
+ t = s >> AL_EXTENT_SIZE_B;
+ s = (s + bio->bi_size);
+
+ if( s >> AL_EXTENT_SIZE_B != t ) {
+ s = 0;
+ // This BIO already spans over an AL_EXTENTs boundary.
+ } else {
+ s = AL_EXTENT_SIZE - ( s & (AL_EXTENT_SIZE-1) );
+ // Bytes to the next AL_EXTENT boundary.
+ }
+ }
+
+ return s;
+}
More information about the drbd-cvs
mailing list