[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