[DRBD-cvs] DRBD CVS: drbd by phil from
drbd-user@lists.linbit.com
drbd-user@lists.linbit.com
Wed, 14 Jan 2004 15:48:36 +0100 (CET)
DRBD CVS committal
Author : phil
Host :
Module : drbd
Dir : drbd/drbd
Modified Files:
Tag: rel-0_7-branch
drbd_dsender.c drbd_int.h drbd_receiver.c
Log Message:
* Simplified drbd_free_ee() and _drbd_alloc_ee()
* Make use of bh->b_private for mdev, instead of that diry Macro...
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.44
retrieving revision 1.1.2.45
diff -u -3 -r1.1.2.44 -r1.1.2.45
--- drbd_dsender.c 14 Jan 2004 13:36:01 -0000 1.1.2.44
+++ drbd_dsender.c 14 Jan 2004 14:48:36 -0000 1.1.2.45
@@ -53,8 +53,7 @@
struct Tl_epoch_entry *e=NULL;
struct Drbd_Conf* mdev;
- // we could use pbh.b_private now for mdev
- mdev=drbd_mdev_of_bh(bh);
+ mdev=bh->b_private;
PARANOIA_BUG_ON(!IS_VALID_MDEV(mdev));
e = container_of(bh,struct Tl_epoch_entry,pbh);
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.86
retrieving revision 1.58.2.87
diff -u -3 -r1.58.2.86 -r1.58.2.87
--- drbd_int.h 14 Jan 2004 13:36:01 -0000 1.58.2.86
+++ drbd_int.h 14 Jan 2004 14:48:36 -0000 1.58.2.87
@@ -1050,17 +1050,6 @@
atomic_read(&mdev->unacked_cnt));
}
-static inline struct Drbd_Conf* drbd_mdev_of_bh(struct buffer_head *bh)
-{
-#ifdef DBG_BH_SECTOR
- if((bh->b_dev & 0xff00) != 0xab00) {
- printk(KERN_ERR DEVICE_NAME" bh->b_dev != 0xabxx\n");
- return drbd_conf;
- }
-#endif
- return drbd_conf + ( bh->b_dev & 0x00ff ) ;
-}
-
static inline void drbd_set_out_of_sync(drbd_dev* mdev,
sector_t sector, int blk_size)
{
@@ -1088,7 +1077,8 @@
{
bh->b_blocknr = sector; // We abuse b_blocknr here.
bh->b_size = size;
- bh->b_dev = 0xab00 | (int)(mdev-drbd_conf); // DRBD's magic mark
+ // bh->b_dev = 0xab00 | (int)(mdev-drbd_conf); // DRBD's magic mark
+ bh->b_private = mdev;
// we skip submit_bh, but use generic_make_request.
set_bit(BH_Req, &bh->b_state);
@@ -1104,7 +1094,8 @@
{
bh->b_blocknr = sector; // We abuse b_blocknr here.
bh->b_size = size;
- bh->b_dev = 0xab00 | (int)(mdev-drbd_conf); // DRBD's magic mark
+ // bh->b_dev = 0xab00 | (int)(mdev-drbd_conf); // DRBD's magic mark
+ bh->b_private = mdev;
// we skip submit_bh, but use generic_make_request.
set_bit(BH_Req, &bh->b_state);
@@ -1116,15 +1107,15 @@
#ifdef DBG_BH_SECTOR
static inline sector_t DRBD_BH_SECTOR(struct buffer_head *bh)
{
- if((bh->b_dev & 0xff00) != 0xab00) {
- printk(KERN_ERR DEVICE_NAME" bh->b_dev != 0xabxx\n");
+ if(!IS_VALID_MDEV(bh->b_private)) {
+ printk(KERN_ERR DEVICE_NAME" !IS_VALID_MDEV(bh->b_private)\n");
}
return bh->b_blocknr;
}
static inline sector_t APP_BH_SECTOR(struct buffer_head *bh)
{
- if((bh->b_dev & 0xff00) == 0xab00) {
- printk(KERN_ERR DEVICE_NAME" bh->b_dev == 0xabxx\n");
+ if(IS_VALID_MDEV(bh->b_private)) {
+ printk(KERN_ERR DEVICE_NAME" IS_VALID_MDEV(bh->b_private)\n");
}
return bh->b_blocknr * (bh->b_size>>9) ;
}
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_receiver.c,v
retrieving revision 1.97.2.77
retrieving revision 1.97.2.78
diff -u -3 -r1.97.2.77 -r1.97.2.78
--- drbd_receiver.c 14 Jan 2004 06:42:22 -0000 1.97.2.77
+++ drbd_receiver.c 14 Jan 2004 14:48:36 -0000 1.97.2.78
@@ -147,8 +147,7 @@
struct Tl_epoch_entry *e=NULL;
struct Drbd_Conf* mdev;
- // we could use pbh.b_private now for mdev
- mdev=drbd_mdev_of_bh(bh);
+ mdev=bh->b_private;
PARANOIA_BUG_ON(!IS_VALID_MDEV(mdev));
e = container_of(bh,struct Tl_epoch_entry,pbh);
@@ -203,58 +202,25 @@
drbd_wait_ee()
*/
-STATIC void _drbd_alloc_ee(drbd_dev *mdev,struct page* page)
+STATIC int _drbd_alloc_ee(drbd_dev *mdev,struct page* page,int mask)
{
struct Tl_epoch_entry* e;
- struct buffer_head *bh,*lbh,*fbh;
- int number,buffer_size,i;
- buffer_size=BM_BLOCK_SIZE;
- /*
- * I suggest to allways allocate full pages, even for b_size smaller
- * than PAGE_SIZE, otherwise we need to dump all EEs // realloc them
- * on each blocksize change. This won't work well for XFS.
- *
- * If we want do do it this way, the loop below can be replaced,
- * and the free_ee case simplyfies also.
- * We then of course waste much memory for blocksizes of 1K :(
- *
- * Alternative would be to have the EE lists as "arrays",
- * indexed by order of b_size.
- */
- // number=PAGE_SIZE/buffer_size;
- number=1;
- lbh=NULL;
- bh=NULL;
- fbh=NULL;
-
- for(i=0;i<number;i++) {
-
- e = kmem_cache_alloc(drbd_ee_cache, GFP_KERNEL);
-
- if( e == NULL ) {
- ERR("could not kmem_cache_alloc() new ee\n");
- BUG();
- }
-
- drbd_init_bh(&e->pbh, buffer_size);
- set_bh_page(&e->pbh,page,i*buffer_size); // sets b_data and b_page
+ e = kmem_cache_alloc(drbd_ee_cache, mask);
+ if( e == NULL ) return FALSE;
- bh->b_private=e;
+ drbd_init_bh(&e->pbh, BM_BLOCK_SIZE); // BM_BLOCK_SIZE == PAGE_SIZE !
+ set_bh_page(&e->pbh,page,0); // sets b_data and b_page
- e->block_id = ID_VACANT;
- spin_lock_irq(&mdev->ee_lock);
- list_add(&e->w.list,&mdev->free_ee);
- mdev->ee_vacant++;
- spin_unlock_irq(&mdev->ee_lock);
- if (lbh) {
- lbh->b_this_page = bh;
- } else {
- fbh = bh;
- }
- lbh=bh;
- }
- bh->b_this_page=fbh;
+ e->block_id = ID_VACANT;
+ spin_lock_irq(&mdev->ee_lock);
+ list_add(&e->w.list,&mdev->free_ee);
+ mdev->ee_vacant++;
+ spin_unlock_irq(&mdev->ee_lock);
+
+ e->pbh.b_this_page=&e->pbh;
+
+ return TRUE;
}
/* bool */
@@ -263,64 +229,38 @@
struct page *page;
page=alloc_page(mask);
- ERR_IF(!page) return FALSE;
+ if(!page) return FALSE;
- _drbd_alloc_ee(mdev,page);
- /*
- printk(KERN_ERR DEVICE_NAME "%d: vacant=%d in_use=%d sum=%d\n",
- (int)(mdev-drbd_conf),mdev->ee_vacant,mdev->ee_in_use,
- mdev->ee_vacant+mdev->ee_in_use);
- */
+ if(!_drbd_alloc_ee(mdev,page,mask)) {
+ __free_page(page);
+ return FALSE;
+ }
+
return TRUE;
}
STATIC struct page* drbd_free_ee(drbd_dev *mdev, struct list_head *list)
{
- struct list_head *le;
struct Tl_epoch_entry* e;
- struct buffer_head *bh,*nbh;
- int freeable=0;
struct page* page;
MUST_HOLD(&mdev->ee_lock);
- /* for "one bh per page" regardless of b_size,
- * this could be simplified. -lge
- */
-
- list_for_each(le,list) {
- bh=&list_entry(le, struct Tl_epoch_entry, w.list)->pbh;
- nbh=bh->b_this_page;
- freeable=1;
- while( nbh != bh ) {
- e=nbh->b_private;
- if(e->block_id != ID_VACANT) freeable=0;
- nbh=nbh->b_this_page;
- }
- if(freeable) goto free_it;
- }
- return 0;
- free_it:
- nbh=bh;
- page=bh->b_page;
- do {
- e=nbh->b_private;
- list_del(&e->w.list);
- mdev->ee_vacant--;
- D_ASSERT(nbh->b_page == page);
- nbh=nbh->b_this_page;
- /*printk(KERN_ERR DEVICE_NAME "%d: kfree(%p)\n",
- (int)(mdev-drbd_conf),e);*/
- kmem_cache_free(drbd_ee_cache, e);
- } while(nbh != bh);
+ e = list_entry(list->next, struct Tl_epoch_entry, w.list);
+ page = e->pbh.b_page;
+ kmem_cache_free(drbd_ee_cache, e);
+
return page;
-}
+}
void drbd_init_ee(drbd_dev *mdev)
{
while(mdev->ee_vacant < EE_MININUM ) {
- drbd_alloc_ee(mdev,GFP_USER);
+ if(!drbd_alloc_ee(mdev,GFP_USER)) {
+ ERR("Failed to allocate %d EEs !",EE_MININUM);
+ break;
+ }
}
}