[DRBD-cvs] r1697 - in branches/drbd-0.7: drbd user

svn at svn.drbd.org svn at svn.drbd.org
Wed Jan 12 15:35:00 CET 2005


Author: phil
Date: 2005-01-12 15:34:57 +0100 (Wed, 12 Jan 2005)
New Revision: 1697

Modified:
   branches/drbd-0.7/drbd/drbd_bitmap.c
   branches/drbd-0.7/drbd/drbd_fs.c
   branches/drbd-0.7/drbd/drbd_receiver.c
   branches/drbd-0.7/user/drbdsetup.c
Log:
Fixed online resizing

- Allow it on connected devices, as long as one node is primary.
  This is necessary to have the right resync after growing.
- Fixed bitmap resizing. Before bm_set was completely wrong when 
  shrinking the device. bm_set was slightly wrong when growing
  the device.



Modified: branches/drbd-0.7/drbd/drbd_bitmap.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_bitmap.c	2005-01-10 19:50:51 UTC (rev 1696)
+++ branches/drbd-0.7/drbd/drbd_bitmap.c	2005-01-12 14:34:57 UTC (rev 1697)
@@ -269,6 +269,33 @@
 	return cleared;
 }
 
+STATIC void bm_set_surplus(struct drbd_bitmap * b)
+{
+	const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) -1;
+	size_t w = b->bm_bits >> LN2_BPL;
+
+	if ( w < b->bm_words ) {
+		b->bm[w++] |= ~mask;
+	}
+
+	if ( w < b->bm_words ) {
+		b->bm[w++] = ~(0UL);
+	}
+}
+
+STATIC unsigned long bm_count_bits(struct drbd_bitmap * b)
+{
+	unsigned long *bm = b->bm;
+	unsigned long *ep = b->bm + b->bm_words;
+	unsigned long bits = 0;
+
+	while ( bm < ep ) {
+		bits += hweight_long(*bm++);
+	}
+
+	return bits;
+}
+
 #define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512)
 
 /*
@@ -283,7 +310,7 @@
 {
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long bits, bytes, words, *nbm, *obm = 0;
-	int err = 0;
+	int err = 0, growing;
 
 	D_BUG_ON(!b);
 	MUST_BE_LOCKED();
@@ -344,19 +371,22 @@
 		obm = b->bm;
 		// brgs. move several MB within spinlock...
 		if (obm) {
+			bm_set_surplus(b);
 			D_ASSERT(b->bm[b->bm_words] == DRBD_MAGIC);
 			memcpy(nbm,obm,min_t(size_t,b->bm_words,words)*sizeof(long));
 		}
-		if (b->bm_words < words) { // set all newly allocated bits
+		growing = words > b->bm_words;
+		if (growing) { // set all newly allocated bits
 			memset(nbm,-1,(words - b->bm_words)*sizeof(long));
+			b->bm_set  += bits - b->bm_bits;
 		}
 		nbm[words] = DRBD_MAGIC;
 		b->bm = nbm;
-		b->bm_set  += bits - b->bm_bits;
 		b->bm_bits  = bits;
 		b->bm_words = words;
 		b->bm_dev_capacity = capacity;
 		bm_clear_surplus(b);
+		if( !growing ) b->bm_set = bm_count_bits(b);
 		bm_end_info(mdev, __FUNCTION__ );
 		spin_unlock_irq(&b->bm_lock);
 		INFO("resync bitmap: bits=%lu words=%lu\n",bits,words);

Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2005-01-10 19:50:51 UTC (rev 1696)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2005-01-12 14:34:57 UTC (rev 1697)
@@ -1122,13 +1122,17 @@
 			err = -EBUSY;
 			break;
 		}
+		if ( (mdev->state == Secondary && mdev->o_state == Secondary) 
+			err = -EINPROGRESS;
+			break;
+		}
 		err=0;
 		mdev->lo_usize = (unsigned long)arg;
 		drbd_bm_lock(mdev);
 		drbd_determin_dev_size(mdev);
 		drbd_md_write(mdev); // Write mdev->la_size to disk.
 		drbd_bm_unlock(mdev);
-		if (mdev->cstate == Connected) drbd_send_param(mdev,0);
+		if (mdev->cstate == Connected) drbd_send_param(mdev,1);
 		break;
 
 	case DRBD_IOCTL_SET_NET_CONFIG:

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2005-01-10 19:50:51 UTC (rev 1696)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2005-01-12 14:34:57 UTC (rev 1697)
@@ -1426,6 +1426,12 @@
 
 	set_bit(MD_DIRTY,&mdev->flags); // we are changing state!
 
+	if( mdev->lo_usize != be64_to_cpu(p->u_size) ) {
+		mdev->lo_usize = be64_to_cpu(p->u_size);
+		INFO("Peer sets u_size to %lu KB\n",
+		     (unsigned long)mdev->lo_usize);
+	}
+
 /*lge:
  * FIXME
  * please get the order of tests (re)settings for consider_sync
@@ -1455,12 +1461,6 @@
 	mdev->sync_conf.group =
 		min_t(int,mdev->sync_conf.group,be32_to_cpu(p->sync_group));
 
-	if( mdev->lo_usize != be64_to_cpu(p->u_size) ) {
-		mdev->lo_usize = be64_to_cpu(p->u_size);
-		INFO("Peer sets u_size to %lu KB\n",
-		     (unsigned long)mdev->lo_usize);
-	}
-
 	if(!p_size) {
 		/* no point in trying to sync a diskless peer: */
 		consider_sync = 0;

Modified: branches/drbd-0.7/user/drbdsetup.c
===================================================================
--- branches/drbd-0.7/user/drbdsetup.c	2005-01-10 19:50:51 UTC (rev 1696)
+++ branches/drbd-0.7/user/drbdsetup.c	2005-01-12 14:34:57 UTC (rev 1697)
@@ -1191,11 +1191,16 @@
 	}
     }
 
-  fprintf(stderr,"err=ioctl(drbd_fd,DRBD_IOCTL_SET_DISK_SIZE,%lu);\n",u_size);
   err=ioctl(drbd_fd,DRBD_IOCTL_SET_DISK_SIZE,u_size);
   if(err)
     {
       PERROR("ioctl(,SET_DISK_SIZE,) failed");
+      if(err==EBUSY) {
+	fprintf(stderr,"Online resizing is not allowed during resync.");
+      }
+      if(err==EINPROGRESS) {
+	fprintf(stderr,"One node must be primary to do online resizing.");
+      }
       return 20;
     }
 



More information about the drbd-cvs mailing list