FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 01-17-2009, 08:03 AM
Ante
 
Default UBUNTU: Update drbd to 8.3.0

Signed-off-by: Ante <ivoks@ubuntu.com>
---
ubuntu/drbd/BOM | 2 +-
ubuntu/drbd/Makefile | 4 +-
ubuntu/drbd/drbd_actlog.c | 138 ++--
ubuntu/drbd/drbd_bitmap.c | 818 ++++++++++++++-------
ubuntu/drbd/drbd_buildtag.c | 6 +-
ubuntu/drbd/drbd_int.h | 556 +++++++++-----
ubuntu/drbd/drbd_main.c | 992 ++++++++++++++++---------
ubuntu/drbd/drbd_nl.c | 461 +++++++++---
ubuntu/drbd/drbd_proc.c | 61 +-
ubuntu/drbd/drbd_receiver.c | 1489 +++++++++++++++++++++++++-----------
ubuntu/drbd/drbd_req.c | 148 +++--
ubuntu/drbd/drbd_req.h | 12 +-
ubuntu/drbd/drbd_strings.c | 2 +-
ubuntu/drbd/drbd_worker.c | 344 +++++++--
ubuntu/drbd/drbd_wrappers.h | 65 ++-
ubuntu/drbd/linux/drbd.h | 67 +-
ubuntu/drbd/linux/drbd_config.h | 14 +-
ubuntu/drbd/linux/drbd_limits.h | 12 +-
ubuntu/drbd/linux/drbd_nl.h | 15 +-
ubuntu/drbd/linux/drbd_tag_magic.h | 2 +-
ubuntu/drbd/lru_cache.c | 26 +-
ubuntu/drbd/lru_cache.h | 6 +-
22 files changed, 3587 insertions(+), 1653 deletions(-)

diff --git a/ubuntu/drbd/BOM b/ubuntu/drbd/BOM
index 529693f..fe895b9 100644
--- a/ubuntu/drbd/BOM
+++ b/ubuntu/drbd/BOM
@@ -1,2 +1,2 @@
Downloaded from: http://oss.linbit.com/drbd/
-Current Version: 8.2.6
+Current Version: 8.3.0
diff --git a/ubuntu/drbd/Makefile b/ubuntu/drbd/Makefile
index 90b79ab..fa81f99 100644
--- a/ubuntu/drbd/Makefile
+++ b/ubuntu/drbd/Makefile
@@ -1,7 +1,9 @@
+#CFLAGS_drbd_sizeof_sanity_check.o = -Wpadded # -Werror
+
drbd-objs := drbd_buildtag.o drbd_bitmap.o drbd_proc.o
drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
lru_cache.o drbd_main.o drbd_strings.o drbd_nl.o

EXTRA_CFLAGS += -I$(src)

-#obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o
+obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o
diff --git a/ubuntu/drbd/drbd_actlog.c b/ubuntu/drbd/drbd_actlog.c
index 7cf95bb..0283910 100644
--- a/ubuntu/drbd/drbd_actlog.c
+++ b/ubuntu/drbd/drbd_actlog.c
@@ -48,7 +48,7 @@ STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev,
md_io.error = 0;

if (rw == WRITE && !test_bit(MD_NO_BARRIER, &mdev->flags))
- rw |= (1<<BIO_RW_BARRIER);
+ rw |= (1<<BIO_RW_BARRIER);
rw |= (1 << BIO_RW_SYNC);

retry:
@@ -64,18 +64,20 @@ STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev,

dump_internal_bio("Md", mdev, bio, 0);

- if (FAULT_ACTIVE(mdev, (rw & WRITE)? DRBD_FAULT_MD_WRRBD_FAULT_MD_RD))
+ if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
bio_endio(bio, -EIO);
else
submit_bio(rw, bio);
wait_for_completion(&md_io.event);
- ok = bio_flagged(bio, BIO_UPTODATE);
+ ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0;

- /* check for unsupported barrier op */
- if (unlikely(md_io.error == -EOPNOTSUPP && bio_barrier(bio))) {
+ /* check for unsupported barrier op.
+ * would rather check on EOPNOTSUPP, but that is not reliable.
+ * don't try again for ANY return value != 0 */
+ if (unlikely(bio_barrier(bio) && !ok)) {
/* Try again with no barrier */
- DRBD_WARN("Barriers not supported on meta data device - disabling
");
- set_bit(MD_NO_BARRIER,&mdev->flags);
+ drbd_WARN("Barriers not supported on meta data device - disabling
");
+ set_bit(MD_NO_BARRIER, &mdev->flags);
rw &= ~(1 << BIO_RW_BARRIER);
bio_put(bio);
goto retry;
@@ -113,16 +115,16 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
if (!page)
return 0;

- DRBD_WARN("Meta data's bdev hardsect = %d != %d
",
+ drbd_WARN("Meta data's bdev hardsect = %d != %d
",
hardsect, MD_HARDSECT);
- DRBD_WARN("Workaround engaged (has performace impact).
");
+ drbd_WARN("Workaround engaged (has performace impact).
");

mdev->md_io_tmpp = page;
}

- mask = ( hardsect / MD_HARDSECT ) - 1;
- D_ASSERT( mask == 1 || mask == 3 || mask == 7 );
- D_ASSERT( hardsect == (mask+1) * MD_HARDSECT );
+ mask = (hardsect / MD_HARDSECT) - 1;
+ D_ASSERT(mask == 1 || mask == 3 || mask == 7);
+ D_ASSERT(hardsect == (mask+1) * MD_HARDSECT);
offset = sector & mask;
sector = sector & ~mask;
iop = mdev->md_io_tmpp;
@@ -227,9 +229,9 @@ struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr)
/*
if (!al_ext) {
if (al_flags & LC_STARVING)
- DRBD_WARN("Have to wait for LRU element (AL too small?)
");
+ drbd_WARN("Have to wait for LRU element (AL too small?)
");
if (al_flags & LC_DIRTY)
- DRBD_WARN("Ongoing AL update (AL device too slow?)
");
+ drbd_WARN("Ongoing AL update (AL device too slow?)
");
}
*/

@@ -253,7 +255,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector)
(int)BM_SECT_TO_EXT(sector));
);

- wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) );
+ wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)));

if (al_ext->lc_number != enr) {
/* drbd_al_write_transaction(mdev,al_ext,enr);
@@ -313,20 +315,20 @@ void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector)
int
w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
{
- struct update_al_work *aw = (struct update_al_work*)w;
+ struct update_al_work *aw = (struct update_al_work *)w;
struct lc_element *updated = aw->al_ext;
const unsigned int new_enr = aw->enr;
const unsigned int evicted = aw->old_enr;

- struct al_transaction* buffer;
+ struct al_transaction *buffer;
sector_t sector;
- int i,n,mx;
+ int i, n, mx;
unsigned int extent_nr;
- u32 xor_sum=0;
+ u32 xor_sum = 0;

if (!inc_local(mdev)) {
ERR("inc_local() failed in w_al_write_transaction
");
- complete(&((struct update_al_work*)w)->event);
+ complete(&((struct update_al_work *)w)->event);
return 1;
}
/* do we have to do a bitmap write, first?
@@ -414,9 +416,9 @@ STATIC int drbd_al_read_tr(struct drbd_conf *mdev,
if (!drbd_md_sync_page_io(mdev, bdev, sector, READ))
return -1;

- rv = ( be32_to_cpu(b->magic) == DRBD_MAGIC );
+ rv = (be32_to_cpu(b->magic) == DRBD_MAGIC);

- for (i = 0; i < AL_EXTENTS_PT+1; i++)
+ for (i = 0; i < AL_EXTENTS_PT + 1; i++)
xor_sum ^= be32_to_cpu(b->updates[i].extent);
rv &= (xor_sum == be32_to_cpu(b->xor_sum));

@@ -461,7 +463,6 @@ int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
return 0;
}
cnr = be32_to_cpu(buffer->tr_number);
- /* INFO("index %d valid tnr=%d
",i,cnr); */

if (cnr == -1)
overflow = 1;
@@ -477,7 +478,7 @@ int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
}

if (from == -1 || to == -1) {
- DRBD_WARN("No usable activity log found.
");
+ drbd_WARN("No usable activity log found.
");

up(&mdev->md_io_mutex);
return 1;
@@ -560,8 +561,7 @@ STATIC BIO_ENDIO_TYPE atodb_endio BIO_ENDIO_ARGS(struct bio *bio, int error)
BIO_ENDIO_FN_START;
/* strange behaviour of some lower level drivers...
* fail the request by clearing the uptodate flag,
- * but do not return any error?!
- * do we want to DRBD_WARN() on this? */
+ * but do not return any error?! */
if (!error && !uptodate)
error = -EIO;

@@ -606,7 +606,7 @@ STATIC int atodb_prepare_unless_covered(struct drbd_conf *mdev,
* the last invocation iterates over all bios,
* and finds the last NULL entry.
*/
- while ( (bio = bios[i]) ) {
+ while ((bio = bios[i])) {
if (bio->bi_sector == on_disk_sector)
return 0;
i++;
@@ -632,9 +632,9 @@ STATIC int atodb_prepare_unless_covered(struct drbd_conf *mdev,
}

offset = S2W(enr);
- drbd_bm_get_lel( mdev, offset,
- min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
- kmap(page) + page_offset );
+ drbd_bm_get_lel(mdev, offset,
+ min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+ kmap(page) + page_offset);
kunmap(page);

bio->bi_private = wc;
@@ -713,7 +713,7 @@ void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)
for (i = 0; i < nr_elements; i++) {
if (bios[i] == NULL)
break;
- if (FAULT_ACTIVE( mdev, DRBD_FAULT_MD_WR )) {
+ if (FAULT_ACTIVE(mdev, DRBD_FAULT_MD_WR)) {
bios[i]->bi_rw = WRITE;
bio_endio(bios[i], -EIO);
} else {
@@ -723,18 +723,17 @@ void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)

drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev));

+ /* always (try to) flush bitmap to stable storage */
+ drbd_md_flush(mdev);
+
/* In case we did not submit a single IO do not wait for
* them to complete. ( Because we would wait forever here. )
*
* In case we had IOs and they are already complete, there
* is not point in waiting anyways.
* Therefore this if () ... */
- if (atomic_read(&wc.count)) {
+ if (atomic_read(&wc.count))
wait_for_completion(&wc.io_done);
- /* flush bitmap to stable storage */
- if (!test_bit(MD_NO_BARRIER, &mdev->flags))
- blkdev_issue_flush(mdev->bc->md_bdev, NULL);
- }

dec_local(mdev);

@@ -751,7 +750,7 @@ void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)
kfree(bios);

submit_one_by_one:
- DRBD_WARN("Using the slow drbd_al_to_on_disk_bm()
");
+ drbd_WARN("Using the slow drbd_al_to_on_disk_bm()
");

for (i = 0; i < mdev->act_log->nr_elements; i++) {
enr = lc_entry(mdev->act_log, i)->lc_number;
@@ -759,7 +758,7 @@ void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)
continue;
/* Really slow: if we have al-extents 16..19 active,
* sector 4 will be written four times! Synchronous! */
- drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT );
+ drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT);
}

lc_unlock(mdev->act_log);
@@ -800,12 +799,13 @@ static inline int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext)

spin_lock_irq(&mdev->al_lock);
rv = (al_ext->refcnt == 0);
- if (likely(rv)) lc_del(mdev->act_log, al_ext);
+ if (likely(rv))
+ lc_del(mdev->act_log, al_ext);
spin_unlock_irq(&mdev->al_lock);

- MTRACE(TraceTypeALExts,TraceLvlMetrics,
- if(unlikely(!rv))
- INFO("Waiting for extent in drbd_al_shrink()
");
+ MTRACE(TraceTypeALExts, TraceLvlMetrics,
+ if (unlikely(!rv))
+ INFO("Waiting for extent in drbd_al_shrink()
");
);

return rv;
@@ -821,7 +821,7 @@ void drbd_al_shrink(struct drbd_conf *mdev)
struct lc_element *al_ext;
int i;

- D_ASSERT( test_bit(__LC_DIRTY, &mdev->act_log->flags) );
+ D_ASSERT(test_bit(__LC_DIRTY, &mdev->act_log->flags));

for (i = 0; i < mdev->act_log->nr_elements; i++) {
al_ext = lc_entry(mdev->act_log, i);
@@ -839,11 +839,11 @@ STATIC int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused

if (!inc_local(mdev)) {
if (DRBD_ratelimit(5*HZ, 5))
- DRBD_WARN("Can not update on disk bitmap, local IO disabled.
");
+ drbd_WARN("Can not update on disk bitmap, local IO disabled.
");
return 1;
}

- drbd_bm_write_sect(mdev, udw->enr );
+ drbd_bm_write_sect(mdev, udw->enr);
dec_local(mdev);

kfree(udw);
@@ -853,7 +853,9 @@ STATIC int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused
case SyncSource: case SyncTarget:
case PausedSyncS: case PausedSyncT:
drbd_resync_finished(mdev);
- default: /* nothing to do */;
+ default:
+ /* nothing to do */
+ break;
}
}
drbd_bcast_sync_progress(mdev);
@@ -907,18 +909,18 @@ STATIC void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector,
* since drbd_rs_begin_io() pulled it already in.
*
* But maybe an application write finished, and we set
- * something in outside the resync lru_cache in sync.
+ * something outside the resync lru_cache in sync.
*/
int rs_left = drbd_bm_e_weight(mdev, enr);
if (ext->flags != 0) {
- DRBD_WARN("changing resync lce: %d[%u;%02lx]"
+ drbd_WARN("changing resync lce: %d[%u;%02lx]"
" -> %d[%u;00]
",
ext->lce.lc_number, ext->rs_left,
ext->flags, enr, rs_left);
ext->flags = 0;
}
if (ext->rs_failed) {
- DRBD_WARN("Kicking resync_lru element enr=%u "
+ drbd_WARN("Kicking resync_lru element enr=%u "
"out with rs_failed=%d
",
ext->lce.lc_number, ext->rs_failed);
set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags);
@@ -939,7 +941,7 @@ STATIC void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector,
udw->w.cb = w_update_odbm;
drbd_queue_work_front(&mdev->data.work, &udw->w);
} else {
- DRBD_WARN("Could not kmalloc an udw
");
+ drbd_WARN("Could not kmalloc an udw
");
set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags);
}
}
@@ -974,7 +976,7 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
return;
}
nr_sectors = drbd_get_capacity(mdev->this_bdev);
- esector = sector + (size>>9) -1;
+ esector = sector + (size >> 9) - 1;

ERR_IF(sector >= nr_sectors) return;
ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
@@ -1011,9 +1013,9 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
if (jiffies - mdev->rs_mark_time > HZ*10) {
/* should be roling marks,
* but we estimate only anyways. */
- if ( mdev->rs_mark_left != drbd_bm_total_weight(mdev) &&
+ if (mdev->rs_mark_left != drbd_bm_total_weight(mdev) &&
mdev->state.conn != PausedSyncT &&
- mdev->state.conn != PausedSyncS ) {
+ mdev->state.conn != PausedSyncS) {
mdev->rs_mark_time = jiffies;
mdev->rs_mark_left = drbd_bm_total_weight(mdev);
}
@@ -1057,7 +1059,7 @@ void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size,
return; /* no disk, no metadata, no bitmap to set bits in */

nr_sectors = drbd_get_capacity(mdev->this_bdev);
- esector = sector + (size>>9) -1;
+ esector = sector + (size >> 9) - 1;

ERR_IF(sector >= nr_sectors)
goto out;
@@ -1123,7 +1125,7 @@ struct bm_extent *_bme_get(struct drbd_conf *mdev, unsigned int enr)

if (!bm_ext) {
if (rs_flags & LC_STARVING)
- DRBD_WARN("Have to wait for element"
+ drbd_WARN("Have to wait for element"
" (resync LRU too small?)
");
BUG_ON(rs_flags & LC_DIRTY);
}
@@ -1137,7 +1139,8 @@ static inline int _is_in_al(struct drbd_conf *mdev, unsigned int enr)
int rv = 0;

spin_lock_irq(&mdev->al_lock);
- if (unlikely(enr == mdev->act_log->new_number)) rv = 1;
+ if (unlikely(enr == mdev->act_log->new_number))
+ rv = 1;
else {
al_ext = lc_find(mdev->act_log, enr);
if (al_ext) {
@@ -1176,19 +1179,20 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
(unsigned long long)sector, enr);
);

- sig = wait_event_interruptible( mdev->al_wait,
- (bm_ext = _bme_get(mdev, enr)) );
+ sig = wait_event_interruptible(mdev->al_wait,
+ (bm_ext = _bme_get(mdev, enr)));
if (sig)
return 0;

- if (test_bit(BME_LOCKED, &bm_ext->flags)) return 1;
+ if (test_bit(BME_LOCKED, &bm_ext->flags))
+ return 1;

for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
- sig = wait_event_interruptible( mdev->al_wait,
- !_is_in_al(mdev, enr*AL_EXT_PER_BM_SECT+i) );
+ sig = wait_event_interruptible(mdev->al_wait,
+ !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i));
if (sig) {
spin_lock_irq(&mdev->al_lock);
- if ( lc_put(mdev->resync, &bm_ext->lce) == 0 ) {
+ if (lc_put(mdev->resync, &bm_ext->lce) == 0) {
clear_bit(BME_NO_WRITES, &bm_ext->flags);
mdev->resync_locked--;
wake_up(&mdev->al_wait);
@@ -1287,7 +1291,7 @@ int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
if (!bm_ext) {
const unsigned long rs_flags = mdev->resync->flags;
if (rs_flags & LC_STARVING)
- DRBD_WARN("Have to wait for element"
+ drbd_WARN("Have to wait for element"
" (resync LRU too small?)
");
BUG_ON(rs_flags & LC_DIRTY);
goto try_again;
@@ -1357,7 +1361,7 @@ void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector)
return;
}

- if ( lc_put(mdev->resync, (struct lc_element *)bm_ext) == 0 ) {
+ if (lc_put(mdev->resync, (struct lc_element *)bm_ext) == 0) {
clear_bit(BME_LOCKED, &bm_ext->flags);
clear_bit(BME_NO_WRITES, &bm_ext->flags);
mdev->resync_locked--;
@@ -1379,7 +1383,7 @@ void drbd_rs_cancel_all(struct drbd_conf *mdev)

spin_lock_irq(&mdev->al_lock);

- if (inc_local_if_state(mdev,Failed)) { /* Makes sure ->resync is there. */
+ if (inc_local_if_state(mdev, Failed)) { /* Makes sure ->resync is there. */
lc_reset(mdev->resync);
dec_local(mdev);
}
@@ -1413,7 +1417,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev)
if (bm_ext->lce.lc_number == LC_FREE)
continue;
if (bm_ext->lce.lc_number == mdev->resync_wenr) {
- INFO("dropping %u in drbd_rs_del_all, aparently"
+ INFO("dropping %u in drbd_rs_del_all, apparently"
" got 'synced' by application io
",
mdev->resync_wenr);
D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags));
@@ -1465,7 +1469,7 @@ void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size)
return;
}
nr_sectors = drbd_get_capacity(mdev->this_bdev);
- esector = sector + (size>>9) -1;
+ esector = sector + (size >> 9) - 1;

ERR_IF(sector >= nr_sectors) return;
ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
diff --git a/ubuntu/drbd/drbd_bitmap.c b/ubuntu/drbd/drbd_bitmap.c
index ef57d3a..0d321ba 100644
--- a/ubuntu/drbd/drbd_bitmap.c
+++ b/ubuntu/drbd/drbd_bitmap.c
@@ -40,7 +40,6 @@
* Note that since find_first_bit returns int, at the current granularity of
* the bitmap (4KB per byte), this implementation "only" supports up to
* 1<<(32+12) == 16 TB...
- * other shortcomings in the meta data area may reduce this even further.
*
* we will eventually change the implementation to not allways hold the full
* bitmap in memory, but only some 'lru_cache' of the on disk bitmap.
@@ -52,12 +51,13 @@

/*
* NOTE
- * Access to the *bm is protected by bm_lock.
+ * Access to the *bm_pages is protected by bm_lock.
* It is safe to read the other members within the lock.
*
* drbd_bm_set_bits is called from bio_endio callbacks,
* We may be called with irq already disabled,
* so we need spin_lock_irqsave().
+ * And we need the kmap_atomic.
* FIXME
* for performance reasons, when we _know_ we have irq disabled, we should
* probably introduce some _in_irq variants, so we know to only spin_lock().
@@ -76,7 +76,7 @@
* than have two resize operations interfere somewhen.
*/
struct drbd_bitmap {
- unsigned long *bm;
+ struct page **bm_pages;
spinlock_t bm_lock;
/* WARNING unsigned long bm_fo and friends:
* 32bit number of bit offset is just enough for 512 MB bitmap.
@@ -89,6 +89,7 @@ struct drbd_bitmap {
unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */
unsigned long bm_bits;
size_t bm_words;
+ size_t bm_number_of_pages;
sector_t bm_dev_capacity;
struct semaphore bm_change; /* serializes resize operations */

@@ -98,72 +99,129 @@ struct drbd_bitmap {
unsigned long bm_flags;

/* debugging aid, in case we are still racy somewhere */
- unsigned long bm_line;
- char *bm_file;
+ char *bm_why;
+ struct task_struct *bm_task;
};

/* definition of bits in bm_flags */
#define BM_LOCKED 0
#define BM_MD_IO_ERROR (BITS_PER_LONG-1) /* 31? 63? */

-void __drbd_bm_lock(struct drbd_conf *mdev, char *file, int line)
+static inline int bm_is_locked(struct drbd_bitmap *b)
{
- struct drbd_bitmap *b = mdev->bitmap;
+ return test_bit(BM_LOCKED, &b->bm_flags);
+}

- spin_lock_irq(&b->bm_lock);
- if (!__test_and_set_bit(BM_LOCKED,&b->bm_flags)) {
- b->bm_file = file;
- b->bm_line = line;
- } else if (DRBD_ratelimit(5*HZ,5)) {
- ERR("%s:%d: bitmap already locked by %s:%lu
",
- file, line, b->bm_file,b->bm_line);
- /*
- dump_stack();
- ERR("This is no oops, but debug stack trace only.
");
- ERR("If you get this often, or in reproducable situations, "
- "notify <drbd-devel@linbit.com>
");
- */
- }
- spin_unlock_irq(&b->bm_lock);
+#define bm_print_lock_info(m) __bm_print_lock_info(m, __func__)
+static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
+{
+ struct drbd_bitmap *b = mdev->bitmap;
+ if (!DRBD_ratelimit(5*HZ, 5))
+ return;
+ ERR("FIXME %s in %s, bitmap locked for '%s' by %s
",
+ current == mdev->receiver.task ? "receiver" :
+ current == mdev->asender.task ? "asender" :
+ current == mdev->worker.task ? "worker" : current->comm,
+ func, b->bm_why ?: "?",
+ b->bm_task == mdev->receiver.task ? "receiver" :
+ b->bm_task == mdev->asender.task ? "asender" :
+ b->bm_task == mdev->worker.task ? "worker" : "?");
}

-void drbd_bm_unlock(struct drbd_conf *mdev)
+void drbd_bm_lock(struct drbd_conf *mdev, char *why)
{
struct drbd_bitmap *b = mdev->bitmap;
- spin_lock_irq(&b->bm_lock);
- if (!__test_and_clear_bit(BM_LOCKED,&mdev->bitmap->bm_flags)) {
- ERR("bitmap not locked in bm_unlock
");
- } else {
- /* FIXME if we got a "is already locked" previously,
- * we unlock here even though we actually MUST NOT do so... */
- b->bm_file = NULL;
- b->bm_line = -1;
+ int trylock_failed;
+
+ if (!b) {
+ ERR("FIXME no bitmap in drbd_bm_lock!?
");
+ return;
}
- spin_unlock_irq(&b->bm_lock);
+
+ trylock_failed = down_trylock(&b->bm_change);
+
+ if (trylock_failed) {
+ DBG("%s going to '%s' but bitmap already locked for '%s' by %s
",
+ current == mdev->receiver.task ? "receiver" :
+ current == mdev->asender.task ? "asender" :
+ current == mdev->worker.task ? "worker" : "?",
+ why, b->bm_why ?: "?",
+ b->bm_task == mdev->receiver.task ? "receiver" :
+ b->bm_task == mdev->asender.task ? "asender" :
+ b->bm_task == mdev->worker.task ? "worker" : "?");
+ down(&b->bm_change);
+ }
+ if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
+ ERR("FIXME bitmap already locked in bm_lock
");
+
+ b->bm_why = why;
+ b->bm_task = current;
}

-#if DUMP_MD >= 3
-/* debugging aid */
-void bm_end_info(struct drbd_conf *mdev, const char *where)
+void drbd_bm_unlock(struct drbd_conf *mdev)
{
struct drbd_bitmap *b = mdev->bitmap;
- size_t w = (b->bm_bits-1) >> LN2_BPL;
+ if (!b) {
+ ERR("FIXME no bitmap in drbd_bm_unlock!?
");
+ return;
+ }

- INFO("%s: bm_set=%lu
", where, b->bm_set);
- INFO("bm[%d]=0x%lX
", w, b->bm[w]);
- w++;
+ if (!__test_and_clear_bit(BM_LOCKED, &mdev->bitmap->bm_flags))
+ ERR("FIXME bitmap not locked in bm_unlock
");

- if (w < b->bm_words) {
- D_ASSERT(w == b->bm_words -1);
- INFO("bm[%d]=0x%lX
", w, b->bm[w]);
- }
+ b->bm_why = NULL;
+ b->bm_task = NULL;
+ up(&b->bm_change);
}
-#else
+
#define bm_end_info(ignored...) ((void)(0))
+
+#if 0
+#define catch_oob_access_start() do {
+ do {
+ if ((bm-p_addr) >= PAGE_SIZE/sizeof(long)) {
+ printk(KERN_ALERT "drbd_bitmap.c:%u %s: p_addr:%p bm:%p %d
",
+ __LINE__ , __func__ , p_addr, bm, (bm-p_addr));
+ break;
+ }
+#define catch_oob_access_end()
+ } while (0); } while (0)
+#else
+#define catch_oob_access_start() do {
+#define catch_oob_access_end() } while (0)
#endif

+/* word offset to long pointer */
+STATIC unsigned long * bm_map_paddr(struct drbd_bitmap *b, unsigned long offset)
+{
+ struct page *page;
+ unsigned long page_nr;
+
+ /* page_nr = (word*sizeof(long)) >> PAGE_SHIFT; */
+ page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3);
+ BUG_ON(page_nr >= b->bm_number_of_pages);
+ page = b->bm_pages[page_nr];
+
+ return (unsigned long *) kmap_atomic(page, KM_IRQ1);
+}
+
+STATIC void bm_unmap(unsigned long *p_addr)
+{
+ kunmap_atomic(p_addr, KM_IRQ1);
+};
+
/* long word offset of _bitmap_ sector */
#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL))
+/* word offset from start of bitmap to word number _in_page_
+ * modulo longs per page
+#define MLPP(X) ((X) % (PAGE_SIZE/sizeof(long))
+ hm, well, Philipp thinks gcc might not optimze the % into & (... - 1)
+ so do it explicitly:
+ */
+#define MLPP(X) ((X) & ((PAGE_SIZE/sizeof(long))-1))
+
+/* Long words per page */
+#define LWPP (PAGE_SIZE/sizeof(long))

/*
* actually most functions herein should take a struct drbd_bitmap*, not a
@@ -177,6 +235,85 @@ void bm_end_info(struct drbd_conf *mdev, const char *where)
* But it is NOT strictly ok.
*/

+STATIC void bm_free_pages(struct page **pages, unsigned long number)
+{
+ unsigned long i;
+ if (!pages)
+ return;
+
+ for (i = 0; i < number; i++) {
+ if (!pages[i]) {
+ printk(KERN_ALERT "drbd: bm_free_pages tried to free "
+ "a NULL pointer; i=%lu n=%lu
",
+ i, number);
+ continue;
+ }
+ __free_page(pages[i]);
+ pages[i] = NULL;
+ }
+}
+
+/*
+ * "have" and "want" are NUMBER OF PAGES.
+ */
+STATIC struct page **bm_realloc_pages(struct page **old_pages,
+ unsigned long have,
+ unsigned long want)
+{
+ struct page** new_pages, *page;
+ unsigned int i, bytes;
+
+ BUG_ON(have == 0 && old_pages != NULL);
+ BUG_ON(have != 0 && old_pages == NULL);
+
+ if (have == want)
+ return old_pages;
+
+ /* To use kmalloc here is ok, as long as we support 4TB at max...
+ * otherwise this might become bigger than 128KB, which is
+ * the maximum for kmalloc.
+ *
+ * no, it is not: on 64bit boxes, sizeof(void*) == 8,
+ * 128MB bitmap @ 4K pages -> 256K of page pointers.
+ * ==> use vmalloc for now again.
+ * then again, we could do something like
+ * if (nr_pages > watermark) vmalloc else kmalloc :*> ...
+ * or do cascading page arrays:
+ * one page for the page array of the page array,
+ * those pages for the real bitmap pages.
+ * there we could even add some optimization members,
+ * so we won't need to kmap_atomic in bm_find_next_bit just to see
+ * that the page has no bits set ...
+ * or we can try a "huge" page ;-)
+ */
+ bytes = sizeof(struct page*)*want;
+ new_pages = vmalloc(bytes);
+ if (!new_pages)
+ return NULL;
+
+ memset(new_pages, 0, bytes);
+ if (want >= have) {
+ for (i = 0; i < have; i++)
+ new_pages[i] = old_pages[i];
+ for (; i < want; i++) {
+ if (!(page = alloc_page(GFP_HIGHUSER))) {
+ bm_free_pages(new_pages + have, i - have);
+ vfree(new_pages);
+ return NULL;
+ }
+ new_pages[i] = page;
+ }
+ } else {
+ for (i = 0; i < want; i++)
+ new_pages[i] = old_pages[i];
+ /* NOT HERE, we are outside the spinlock!
+ bm_free_pages(old_pages + want, have - want);
+ */
+ }
+
+ return new_pages;
+}
+
/*
* called on driver init only. TODO call when a device is created.
* allocates the drbd_bitmap, and stores it in mdev->bitmap.
@@ -213,7 +350,8 @@ void drbd_bm_cleanup(struct drbd_conf *mdev)
*
WARN_ON(mdev->bitmap->bm);
*/
- vfree(mdev->bitmap->bm);
+ bm_free_pages(mdev->bitmap->bm_pages, mdev->bitmap->bm_number_of_pages);
+ vfree(mdev->bitmap->bm_pages);
kfree(mdev->bitmap);
mdev->bitmap = NULL;
}
@@ -225,46 +363,75 @@ void drbd_bm_cleanup(struct drbd_conf *mdev)
*/
STATIC int bm_clear_surplus(struct drbd_bitmap *b)
{
- const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) -1;
+ const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1;
size_t w = b->bm_bits >> LN2_BPL;
int cleared = 0;
+ unsigned long *p_addr, *bm;

+ p_addr = bm_map_paddr(b, w);
+ bm = p_addr + MLPP(w);
if (w < b->bm_words) {
- cleared = hweight_long(b->bm[w] & ~mask);
- b->bm[w++] &= mask;
+ catch_oob_access_start();
+ cleared = hweight_long(*bm & ~mask);
+ *bm &= mask;
+ catch_oob_access_end();
+ w++; bm++;
}

if (w < b->bm_words) {
- cleared += hweight_long(b->bm[w]);
- b->bm[w++] = 0;
+ catch_oob_access_start();
+ cleared += hweight_long(*bm);
+ *bm = 0;
+ catch_oob_access_end();
}
-
+ bm_unmap(p_addr);
return cleared;
}

STATIC void bm_set_surplus(struct drbd_bitmap *b)
{
- const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) -1;
+ const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1;
size_t w = b->bm_bits >> LN2_BPL;
+ unsigned long *p_addr, *bm;

- if (w < b->bm_words)
- b->bm[w++] |= ~mask;
+ p_addr = bm_map_paddr(b, w);
+ bm = p_addr + MLPP(w);
+ if (w < b->bm_words) {
+ catch_oob_access_start();
+ *bm |= ~mask;
+ bm++; w++;
+ catch_oob_access_end();
+ }

- if (w < b->bm_words)
- b->bm[w++] = ~(0UL);
+ if (w < b->bm_words) {
+ catch_oob_access_start();
+ *bm = ~(0UL);
+ catch_oob_access_end();
+ }
+ bm_unmap(p_addr);
}

STATIC unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endian)
{
- unsigned long *bm = b->bm;
- unsigned long *ep = b->bm + b->bm_words;
+ unsigned long *p_addr, *bm, offset = 0;
unsigned long bits = 0;
-
- while ( bm < ep ) {
+ unsigned long i, do_now;
+
+ while (offset < b->bm_words) {
+ i = do_now = min_t(size_t, b->bm_words-offset, LWPP);
+ p_addr = bm_map_paddr(b, offset);
+ bm = p_addr + MLPP(offset);
+ while (i--) {
+ catch_oob_access_start();
#ifndef __LITTLE_ENDIAN
- if (swap_endian) *bm = lel_to_cpu(*bm);
+ if (swap_endian)
+ *bm = lel_to_cpu(*bm);
#endif
- bits += hweight_long(*bm++);
+ bits += hweight_long(*bm++);
+ catch_oob_access_end();
+ }
+ bm_unmap(p_addr);
+ offset += do_now;
}

return bits;
@@ -272,22 +439,27 @@ STATIC unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endia

static inline unsigned long bm_count_bits(struct drbd_bitmap *b)
{
- return __bm_count_bits(b,0);
+ return __bm_count_bits(b, 0);
}

static inline unsigned long bm_count_bits_swap_endian(struct drbd_bitmap *b)
{
- return __bm_count_bits(b,1);
+ return __bm_count_bits(b, 1);
}

-
-void _drbd_bm_recount_bits(struct drbd_conf *mdev, char* file, int line)
+void _drbd_bm_recount_bits(struct drbd_conf *mdev, char *file, int line)
{
struct drbd_bitmap *b = mdev->bitmap;
unsigned long flags, bits;

ERR_IF(!b) return;

+ /* IMO this should be inside drbd_bm_lock/unlock.
+ * Unfortunately it is used outside of the locks.
+ * And I'm not yet sure where we need to place the
+ * lock/unlock correctly.
+ */
+
spin_lock_irqsave(&b->bm_lock, flags);
bits = bm_count_bits(b);
if (bits != b->bm_set) {
@@ -298,8 +470,38 @@ void _drbd_bm_recount_bits(struct drbd_conf *mdev, char* file, int line)
spin_unlock_irqrestore(&b->bm_lock, flags);
}

+/* offset and len in long words.*/
+STATIC void bm_memset(struct drbd_bitmap * b, size_t offset, int c, size_t len)
+{
+ unsigned long *p_addr, *bm;
+ size_t do_now, end;
+
#define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512)

+ end = offset + len;
+
+ if (end > b->bm_words) {
+ printk(KERN_ALERT "drbd: bm_memset end > bm_words
");
+ return;
+ }
+
+ while (offset < end) {
+ do_now = min_t(size_t, ALIGN(offset + 1, LWPP), end) - offset;
+ p_addr = bm_map_paddr(b, offset);
+ bm = p_addr + MLPP(offset);
+ catch_oob_access_start();
+ if (bm+do_now > p_addr + LWPP) {
+ printk(KERN_ALERT "drbd: BUG BUG BUG! p_addr:%p bm:%p do_now:%d
",
+ p_addr, bm, (int)do_now);
+ break; /* breaks to after catch_oob_access_end() only! */
+ }
+ memset(bm, c, do_now * sizeof(long));
+ catch_oob_access_end();
+ bm_unmap(p_addr);
+ offset += do_now;
+ }
+}
+
/*
* make sure the bitmap has enough room for the attached storage,
* if neccessary, resize.
@@ -311,14 +513,14 @@ void _drbd_bm_recount_bits(struct drbd_conf *mdev, char* file, int line)
int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity)
{
struct drbd_bitmap *b = mdev->bitmap;
- unsigned long bits, bytes, words, *nbm, *obm = NULL;
+ unsigned long bits, words, owords, obits, *p_addr, *bm;
+ unsigned long want, have, onpages; /* number of pages */
+ struct page **npages, **opages = NULL;
int err = 0, growing;

ERR_IF(!b) return -ENOMEM;

- ERR_IF (down_trylock(&b->bm_change)) {
- down(&b->bm_change);
- }
+ drbd_bm_lock(mdev, "resize");

INFO("drbd_bm_resize called with capacity == %llu
",
(unsigned long long)capacity);
@@ -328,87 +530,93 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity)

if (capacity == 0) {
spin_lock_irq(&b->bm_lock);
- obm = b->bm;
- b->bm = NULL;
+ opages = b->bm_pages;
+ onpages = b->bm_number_of_pages;
+ owords = b->bm_words;
+ b->bm_pages = NULL;
+ b->bm_number_of_pages =
b->bm_fo =
b->bm_set =
b->bm_bits =
b->bm_words =
b->bm_dev_capacity = 0;
spin_unlock_irq(&b->bm_lock);
- goto free_obm;
- } else {
- bits = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECTORS_PER_BIT));
+ bm_free_pages(opages, onpages);
+ vfree(opages);
+ goto out;
+ }
+ bits = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECT_PER_BIT));
+
+ /* if we would use
+ words = ALIGN(bits,BITS_PER_LONG) >> LN2_BPL;
+ a 32bit host could present the wrong number of words
+ to a 64bit host.
+ */
+ words = ALIGN(bits, 64) >> LN2_BPL;
+
+ if (inc_local(mdev)) {
+ D_ASSERT((u64)bits <= (((u64)mdev->bc->md.md_size_sect-MD_BM_OFFSET) << 12));
+ dec_local(mdev);
+ }

- /* if we would use
- words = ALIGN(bits,BITS_PER_LONG) >> LN2_BPL;
- a 32bit host could present the wrong number of words
- to a 64bit host.
- */
- words = ALIGN(bits, 64) >> LN2_BPL;
+ /* one extra long to catch off by one errors */
+ want = ALIGN((words+1)*sizeof(long), PAGE_SIZE) >> PAGE_SHIFT;
+ have = b->bm_number_of_pages;
+ if (want == have) {
+ D_ASSERT(b->bm_pages != NULL);
+ npages = b->bm_pages;
+ } else
+ npages = bm_realloc_pages(b->bm_pages, have, want);
+
+ if (!npages) {
+ err = -ENOMEM;
+ goto out;
+ }

- if (inc_local(mdev)) {
- D_ASSERT((u64)bits <= (((u64)mdev->bc->md.md_size_sect-MD_BM_OFFSET) << 12));
- dec_local(mdev);
- }
+ spin_lock_irq(&b->bm_lock);
+ opages = b->bm_pages;
+ owords = b->bm_words;
+ obits = b->bm_bits;
+
+ growing = bits > obits;
+ if (opages)
+ bm_set_surplus(b);
+
+ b->bm_pages = npages;
+ b->bm_number_of_pages = want;
+ b->bm_bits = bits;
+ b->bm_words = words;
+ b->bm_dev_capacity = capacity;
+
+ if (growing) {
+ bm_memset(b, owords, 0xff, words-owords);
+ b->bm_set += bits - obits;
+ }

- if (words == b->bm_words) {
- /* optimize: capacity has changed,
- * but only within one long word worth of bits.
- * just update the bm_dev_capacity and bm_bits members.
- */
- spin_lock_irq(&b->bm_lock);
- b->bm_bits = bits;
- b->bm_dev_capacity = capacity;
- b->bm_set -= bm_clear_surplus(b);
- bm_end_info(mdev, __FUNCTION__ );
- spin_unlock_irq(&b->bm_lock);
- goto out;
- } else {
- /* one extra long to catch off by one errors */
- bytes = (words+1)*sizeof(long);
- nbm = vmalloc(bytes);
- if (!nbm) {
- ERR("bitmap: failed to vmalloc %lu bytes
",
- bytes);
- err = -ENOMEM;
- goto out;
- }
- }
- spin_lock_irq(&b->bm_lock);
- obm = b->bm;
- /* brgs. move several MB within spinlock...
- * FIXME this should go into userspace! */
- 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));
- }
- growing = words > b->bm_words;
- if (growing) {
- /* set all newly allocated bits
- * start at -1, just to be sure. */
- memset( nbm + (b->bm_words?:1)-1 , 0xff,
- (words - ((b->bm_words?:1)-1)) * sizeof(long) );
- b->bm_set += bits - b->bm_bits;
- }
- nbm[words] = DRBD_MAGIC;
- b->bm = nbm;
- 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
", bits, words);
+ if (want < have) {
+ /* implicit: (opages != NULL) && (opages != npages) */
+ bm_free_pages(opages + want, have - want);
}
- free_obm:
- vfree(obm); /* vfree(NULL) is noop */
+
+ p_addr = bm_map_paddr(b, words);
+ bm = p_addr + MLPP(words);
+ catch_oob_access_start();
+ *bm = DRBD_MAGIC;
+ catch_oob_access_end();
+ bm_unmap(p_addr);
+
+ (void)bm_clear_surplus(b);
+ if (!growing)
+ b->bm_set = bm_count_bits(b);
+
+ bm_end_info(mdev, __FUNCTION__);
+ spin_unlock_irq(&b->bm_lock);
+ if (opages != npages)
+ vfree(opages);
+ INFO("resync bitmap: bits=%lu words=%lu
", bits, words);
+
out:
- up(&b->bm_change);
+ drbd_bm_unlock(mdev);
return err;
}

@@ -427,6 +635,7 @@ unsigned long drbd_bm_total_weight(struct drbd_conf *mdev)
unsigned long flags;

ERR_IF(!b) return 0;
+ ERR_IF(!b->bm_pages) return 0;

spin_lock_irqsave(&b->bm_lock, flags);
s = b->bm_set;
@@ -439,6 +648,8 @@ size_t drbd_bm_words(struct drbd_conf *mdev)
{
struct drbd_bitmap *b = mdev->bitmap;
ERR_IF(!b) return 0;
+ ERR_IF(!b->bm_pages) return 0;
+
return b->bm_words;
}

@@ -450,42 +661,52 @@ unsigned long drbd_bm_bits(struct drbd_conf *mdev)
return b->bm_bits;
}

-
/* merge number words from buffer into the bitmap starting at offset.
* buffer[i] is expected to be little endian unsigned long.
+ * bitmap must be locked by drbd_bm_lock.
+ * currently only used from receive_bitmap.
*/
-void drbd_bm_merge_lel( struct drbd_conf *mdev, size_t offset, size_t number,
- unsigned long *buffer )
+void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number,
+ unsigned long *buffer)
{
struct drbd_bitmap *b = mdev->bitmap;
- unsigned long *bm;
+ unsigned long *p_addr, *bm;
unsigned long word, bits;
- size_t n = number;
+ size_t end, do_now;
+
+ end = offset + number;

+ ERR_IF(!b) return;
+ ERR_IF(!b->bm_pages) return;
if (number == 0)
return;
- ERR_IF(!b) return;
- ERR_IF(!b->bm) return;
- WARN_ON(offset >= b->bm_words);
- WARN_ON(offset+number > b->bm_words);
- WARN_ON(number > PAGE_SIZE/sizeof(long));
+ WARN_ON(offset >= b->bm_words);
+ WARN_ON(end > b->bm_words);

spin_lock_irq(&b->bm_lock);
- bm = b->bm + offset;
- while (n--) {
- bits = hweight_long(*bm);
- word = *bm | lel_to_cpu(*buffer++);
- *bm++ = word;
- b->bm_set += hweight_long(word) - bits;
+ while (offset < end) {
+ do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset;
+ p_addr = bm_map_paddr(b, offset);
+ bm = p_addr + MLPP(offset);
+ offset += do_now;
+ while (do_now--) {
+ catch_oob_access_start();
+ bits = hweight_long(*bm);
+ word = *bm | lel_to_cpu(*buffer++);
+ *bm++ = word;
+ b->bm_set += hweight_long(word) - bits;
+ catch_oob_access_end();
+ }
+ bm_unmap(p_addr);
}
/* with 32bit <-> 64bit cross-platform connect
* this is only correct for current usage,
* where we _know_ that we are 64 bit aligned,
* and know that this function is used in this way, too...
*/
- if (offset+number == b->bm_words) {
+ if (end == b->bm_words) {
b->bm_set -= bm_clear_surplus(b);
- bm_end_info(mdev, __FUNCTION__ );
+ bm_end_info(mdev, __func__);
}
spin_unlock_irq(&b->bm_lock);
}
@@ -494,30 +715,39 @@ void drbd_bm_merge_lel( struct drbd_conf *mdev, size_t offset, size_t number,
* buffer[i] will be little endian unsigned long.
*/
void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number,
- unsigned long *buffer )
+ unsigned long *buffer)
{
struct drbd_bitmap *b = mdev->bitmap;
- unsigned long *bm;
+ unsigned long *p_addr, *bm;
+ size_t end, do_now;
+
+ end = offset + number;

- if (number == 0)
- return;
ERR_IF(!b) return;
- ERR_IF(!b->bm) return;
- if ( (offset >= b->bm_words) ||
- (offset+number > b->bm_words) ||
- (number > PAGE_SIZE/sizeof(long)) ||
- (number <= 0) ) {
- /* yes, there is "%z", but that gives compiler warnings... */
+ ERR_IF(!b->bm_pages) return;
+
+ spin_lock_irq(&b->bm_lock);
+ if ((offset >= b->bm_words) ||
+ (end > b->bm_words) ||
+ (number <= 0))
ERR("offset=%lu number=%lu bm_words=%lu
",
(unsigned long) offset,
(unsigned long) number,
(unsigned long) b->bm_words);
- return;
+ else {
+ while (offset < end) {
+ do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset;
+ p_addr = bm_map_paddr(b, offset);
+ bm = p_addr + MLPP(offset);
+ offset += do_now;
+ while (do_now--) {
+ catch_oob_access_start();
+ *buffer++ = cpu_to_lel(*bm++);
+ catch_oob_access_end();
+ }
+ bm_unmap(p_addr);
+ }
}
-
- spin_lock_irq(&b->bm_lock);
- bm = b->bm + offset;
- while (number--) *buffer++ = cpu_to_lel(*bm++);
spin_unlock_irq(&b->bm_lock);
}

@@ -526,25 +756,39 @@ void drbd_bm_set_all(struct drbd_conf *mdev)
{
struct drbd_bitmap *b = mdev->bitmap;
ERR_IF(!b) return;
- ERR_IF(!b->bm) return;
+ ERR_IF(!b->bm_pages) return;

spin_lock_irq(&b->bm_lock);
- memset(b->bm, 0xff, b->bm_words*sizeof(long));
- bm_clear_surplus(b);
+ bm_memset(b, 0, 0xff, b->bm_words);
+ (void)bm_clear_surplus(b);
b->bm_set = b->bm_bits;
spin_unlock_irq(&b->bm_lock);
}

+/* clear all bits in the bitmap */
+void drbd_bm_clear_all(struct drbd_conf *mdev)
+{
+ struct drbd_bitmap *b = mdev->bitmap;
+ ERR_IF(!b) return;
+ ERR_IF(!b->bm_pages) return;
+
+ spin_lock_irq(&b->bm_lock);
+ bm_memset(b, 0, 0, b->bm_words);
+ b->bm_set = 0;
+ spin_unlock_irq(&b->bm_lock);
+}
+
static BIO_ENDIO_TYPE bm_async_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error)
{
struct drbd_bitmap *b = bio->bi_private;
int uptodate = bio_flagged(bio, BIO_UPTODATE);

BIO_ENDIO_FN_START;
+
/* strange behaviour of some lower level drivers...
* fail the request by clearing the uptodate flag,
* but do not return any error?!
- * do we want to DRBD_WARN() on this? */
+ * do we want to WARN() on this? */
if (!error && !uptodate)
error = -EIO;

@@ -566,10 +810,7 @@ static BIO_ENDIO_TYPE bm_async_io_complete BIO_ENDIO_ARGS(struct bio *bio, int e
STATIC void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int page_nr, int rw) __must_hold(local)
{
/* we are process context. we always get a bio */
- /* THINK: do we need GFP_NOIO here? */
struct bio *bio = bio_alloc(GFP_KERNEL, 1);
- struct page *page = vmalloc_to_page((char *)(b->bm)
- + (PAGE_SIZE*page_nr));
unsigned int len;
sector_t on_disk_sector =
mdev->bc->md.md_offset + mdev->bc->md.bm_offset;
@@ -585,11 +826,11 @@ STATIC void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int

bio->bi_bdev = mdev->bc->md_bdev;
bio->bi_sector = on_disk_sector;
- bio_add_page(bio, page, len, 0);
+ bio_add_page(bio, b->bm_pages[page_nr], len, 0);
bio->bi_private = b;
bio->bi_end_io = bm_async_io_complete;

- if (FAULT_ACTIVE(mdev, (rw&WRITE)?DRBD_FAULT_MD_WRRBD_FAULT_MD_RD)) {
+ if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
bio->bi_rw |= rw;
bio_endio(bio, -EIO);
} else {
@@ -607,20 +848,25 @@ void bm_cpu_to_lel(struct drbd_bitmap *b)
* this may be optimized by using
* cpu_to_lel(-1) == -1 and cpu_to_lel(0) == 0;
* the following is still not optimal, but better than nothing */
- const unsigned long *end = b->bm+b->bm_words;
- unsigned long *bm;
if (b->bm_set == 0) {
/* no page at all; avoid swap if all is 0 */
- return;
+ i = b->bm_number_of_pages;
} else if (b->bm_set == b->bm_bits) {
- /* only the last words */
- bm = end-2;
+ /* only the last page */
+ i = b->bm_number_of_pages -1;
} else {
/* all pages */
- bm = b->bm;
+ i = 0;
+ }
+ for (; i < b->bm_number_of_pages; i++) {
+ unsigned long *bm;
+ /* if you'd want to use kmap_atomic, you'd have to disable irq! */
+ p_addr = kmap(b->bm_pages[i]);
+ for (bm = p_addr; bm < p_addr + PAGE_SIZE/sizeof(long); bm++) {
+ *bm = cpu_to_lel(*bm);
+ }
+ kunmap(p_addr);
}
- for (; bm < end; bm++)
- *bm = cpu_to_lel(*bm);
}
# endif
/* lel_to_cpu == cpu_to_lel */
@@ -638,17 +884,13 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
char ppb[10];
int err = 0;

+ WARN_ON(!bm_is_locked(b));
+
+ /* no spinlock here, the drbd_bm_lock should be enough! */
+
bm_words = drbd_bm_words(mdev);
num_pages = (bm_words*sizeof(long) + PAGE_SIZE-1) >> PAGE_SHIFT;

- /* OK, I manipulate the bitmap low level,
- * and I expect to be the exclusive user.
- * If not, I am really in a bad mood...
- * to catch such bugs early, make all people who want to access the
- * bitmap while I read/write it dereference a NULL pointer :->
- */
- mdev->bitmap = NULL;
-
/* on disk bitmap is little endian */
if (rw == WRITE)
bm_cpu_to_lel(b);
@@ -663,8 +905,11 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)

drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev));
wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0);
- INFO("%s of bitmap took %lu jiffies
",
- rw == READ ? "reading" : "writing", jiffies - now);
+
+ MTRACE(TraceTypeMDIO, TraceLvlSummary,
+ INFO("%s of bitmap took %lu jiffies
",
+ rw == READ ? "reading" : "writing", jiffies - now);
+ );

if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) {
ALERT("we had at least one MD IO ERROR during bitmap IO
");
@@ -678,8 +923,7 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
/* swap back endianness */
bm_lel_to_cpu(b);
/* flush bitmap to stable storage */
- if (!test_bit(MD_NO_BARRIER,&mdev->flags))
- blkdev_issue_flush(mdev->bc->md_bdev, NULL);
+ drbd_md_flush(mdev);
} else /* rw == READ */ {
/* just read, if neccessary adjust endianness */
b->bm_set = bm_count_bits_swap_endian(b);
@@ -688,12 +932,6 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
}
now = b->bm_set;

- /* ok, done,
- * now it is visible again
- */
-
- mdev->bitmap = b;
-
INFO("%s (%lu bits) marked out-of-sync by on disk bit-map.
",
ppsize(ppb, now << (BM_BLOCK_SIZE_B-10)), now);

@@ -707,18 +945,7 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
*/
int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local)
{
- struct drbd_bitmap *b = mdev->bitmap;
- int err = 0;
-
- if (b->bm) {
- /* bitmap size > 0 */
- err = bm_rw(mdev, READ);
-
- if (err == 0)
- b->bm[b->bm_words] = DRBD_MAGIC;
- }
-
- return err;
+ return bm_rw(mdev, READ);
}

/**
@@ -755,14 +982,14 @@ int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(lo
#endif
if (num_words < S2W(1))
memset(page_address(mdev->md_io_page), 0, MD_HARDSECT);
- drbd_bm_get_lel( mdev, offset, num_words,
- page_address(mdev->md_io_page) );
+ drbd_bm_get_lel(mdev, offset, num_words,
+ page_address(mdev->md_io_page));
if (!drbd_md_sync_page_io(mdev, mdev->bc, on_disk_sector, WRITE)) {
int i;
err = -EIO;
- ERR( "IO ERROR writing bitmap sector %lu "
- "(meta-disk sector %llus)
",
- enr, (unsigned long long)on_disk_sector );
+ ERR("IO ERROR writing bitmap sector %lu "
+ "(meta-disk sector %llus)
",
+ enr, (unsigned long long)on_disk_sector);
drbd_chk_io_error(mdev, 1, TRUE);
drbd_io_error(mdev, TRUE);
for (i = 0; i < AL_EXT_PER_BM_SECT; i++)
@@ -780,6 +1007,8 @@ void drbd_bm_reset_find(struct drbd_conf *mdev)
ERR_IF(!b) return;

spin_lock_irq(&b->bm_lock);
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);
b->bm_fo = 0;
spin_unlock_irq(&b->bm_lock);

@@ -788,28 +1017,46 @@ void drbd_bm_reset_find(struct drbd_conf *mdev)
/* NOTE
* find_first_bit returns int, we return unsigned long.
* should not make much difference anyways, but ...
+ *
* this returns a bit number, NOT a sector!
*/
+#define BPP_MASK ((1UL << (PAGE_SHIFT+3)) - 1)
unsigned long drbd_bm_find_next(struct drbd_conf *mdev)
{
struct drbd_bitmap *b = mdev->bitmap;
unsigned long i = -1UL;
+ unsigned long *p_addr;
+ unsigned long bit_offset; /* bit offset of the mapped page. */

ERR_IF(!b) return i;
- ERR_IF(!b->bm) return i;
+ ERR_IF(!b->bm_pages) return i;

spin_lock_irq(&b->bm_lock);
- if (b->bm_fo < b->bm_bits)
- i = find_next_bit(b->bm, b->bm_bits, b->bm_fo);
- else if (b->bm_fo > b->bm_bits)
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);
+ if (b->bm_fo > b->bm_bits) {
ERR("bm_fo=%lu bm_bits=%lu
", b->bm_fo, b->bm_bits);
-
- if (i >= b->bm_bits) {
+ } else {
+ while (b->bm_fo < b->bm_bits) {
+ unsigned long offset;
+ bit_offset = b->bm_fo & ~BPP_MASK; /* bit offset of the page */
+ offset = bit_offset >> LN2_BPL; /* word offset of the page */
+ p_addr = bm_map_paddr(b, offset);
+ i = find_next_bit(p_addr, PAGE_SIZE*8, b->bm_fo & BPP_MASK);
+ bm_unmap(p_addr);
+ if (i < PAGE_SIZE*8) {
+ i = bit_offset + i;
+ if (i >= b->bm_bits)
+ break;
+ b->bm_fo = i+1;
+ goto found;
+ }
+ b->bm_fo = bit_offset + PAGE_SIZE*8;
+ }
i = -1UL;
/* leave b->bm_fo unchanged. */
- } else {
- b->bm_fo = i+1;
}
+ found:
spin_unlock_irq(&b->bm_lock);
return i;
}
@@ -825,10 +1072,10 @@ void drbd_bm_set_find(struct drbd_conf *mdev, unsigned long i)
spin_unlock_irq(&b->bm_lock);
}

-
int drbd_bm_rs_done(struct drbd_conf *mdev)
{
- return (mdev->bitmap->bm_fo >= mdev->bitmap->bm_bits);
+ D_ASSERT(mdev->bitmap);
+ return mdev->bitmap->bm_fo >= mdev->bitmap->bm_bits;
}

/* returns number of bits actually changed.
@@ -840,22 +1087,37 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
{
unsigned long flags;
struct drbd_bitmap *b = mdev->bitmap;
+ unsigned long *p_addr = NULL;
unsigned long bitnr;
+ unsigned long last_page_nr = -1UL;
int c = 0;
+
ERR_IF(!b) return 1;
- ERR_IF(!b->bm) return 1;
+ ERR_IF(!b->bm_pages) return 0;

- spin_lock_irqsave(&b->bm_lock,flags);
+ spin_lock_irqsave(&b->bm_lock, flags);
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);
for (bitnr = s; bitnr <= e; bitnr++) {
ERR_IF (bitnr >= b->bm_bits) {
ERR("bitnr=%lu bm_bits=%lu
", bitnr, b->bm_bits);
} else {
+ unsigned long offset = bitnr>>LN2_BPL;
+ unsigned long page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3);
+ if (page_nr != last_page_nr) {
+ if (p_addr)
+ bm_unmap(p_addr);
+ p_addr = bm_map_paddr(b, offset);
+ last_page_nr = page_nr;
+ }
if (val)
- c += (0 == __test_and_set_bit(bitnr, b->bm));
+ c += (0 == __test_and_set_bit(bitnr & BPP_MASK, p_addr));
else
- c -= (0 != __test_and_clear_bit(bitnr, b->bm));
+ c -= (0 != __test_and_clear_bit(bitnr & BPP_MASK, p_addr));
}
}
+ if (p_addr)
+ bm_unmap(p_addr);
b->bm_set += c;
spin_unlock_irqrestore(&b->bm_lock, flags);
return c;
@@ -884,13 +1146,20 @@ int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr)
{
unsigned long flags;
struct drbd_bitmap *b = mdev->bitmap;
+ unsigned long *p_addr;
int i;
+
ERR_IF(!b) return 0;
- ERR_IF(!b->bm) return 0;
+ ERR_IF(!b->bm_pages) return 0;

spin_lock_irqsave(&b->bm_lock, flags);
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);
if (bitnr < b->bm_bits) {
- i = test_bit(bitnr, b->bm) ? 1 : 0;
+ unsigned long offset = bitnr>>LN2_BPL;
+ p_addr = bm_map_paddr(b, offset);
+ i = test_bit(bitnr & BPP_MASK, p_addr) ? 1 : 0;
+ bm_unmap(p_addr);
} else if (bitnr == b->bm_bits) {
i = -1;
} else { /* (bitnr > b->bm_bits) */
@@ -907,25 +1176,36 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
{
unsigned long flags;
struct drbd_bitmap *b = mdev->bitmap;
+ unsigned long *p_addr = NULL, page_nr = -1;
unsigned long bitnr;
int c = 0;
+ size_t w;

/* If this is called without a bitmap, that is a bug. But just to be
* robust in case we screwed up elsewhere, in that case pretend there
* was one dirty bit in the requested area, so we won't try to do a
* local read there (no bitmap probably implies no disk) */
ERR_IF(!b) return 1;
- ERR_IF(!b->bm) return 1;
+ ERR_IF(!b->bm_pages) return 1;

- spin_lock_irqsave(&b->bm_lock,flags);
- for (bitnr = s; bitnr <=e; bitnr++) {
+ spin_lock_irqsave(&b->bm_lock, flags);
+ for (bitnr = s; bitnr <= e; bitnr++) {
+ w = bitnr >> LN2_BPL;
+ if (page_nr != w >> (PAGE_SHIFT - LN2_BPL + 3)) {
+ page_nr = w >> (PAGE_SHIFT - LN2_BPL + 3);
+ if (p_addr)
+ bm_unmap(p_addr);
+ p_addr = bm_map_paddr(b, w);
+ }
ERR_IF (bitnr >= b->bm_bits) {
- ERR("bitnr=%lu bm_bits=%lu
",bitnr, b->bm_bits);
+ ERR("bitnr=%lu bm_bits=%lu
", bitnr, b->bm_bits);
} else {
- c += (0 != test_bit(bitnr, b->bm));
+ c += (0 != test_bit(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr));
}
}
- spin_unlock_irqrestore(&b->bm_lock,flags);
+ if (p_addr)
+ bm_unmap(p_addr);
+ spin_unlock_irqrestore(&b->bm_lock, flags);
return c;
}

@@ -949,18 +1229,28 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr)
struct drbd_bitmap *b = mdev->bitmap;
int count, s, e;
unsigned long flags;
+ unsigned long *p_addr, *bm;

ERR_IF(!b) return 0;
- ERR_IF(!b->bm) return 0;
+ ERR_IF(!b->bm_pages) return 0;
+
spin_lock_irqsave(&b->bm_lock, flags);
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);

s = S2W(enr);
e = min((size_t)S2W(enr+1), b->bm_words);
count = 0;
if (s < b->bm_words) {
- const unsigned long *w = b->bm+s;
int n = e-s;
- while (n--) count += hweight_long(*w++);
+ p_addr = bm_map_paddr(b, s);
+ bm = p_addr + MLPP(s);
+ while (n--) {
+ catch_oob_access_start();
+ count += hweight_long(*bm++);
+ catch_oob_access_end();
+ }
+ bm_unmap(p_addr);
} else {
ERR("start offset (%d) too large in drbd_bm_e_weight
", s);
}
@@ -975,24 +1265,36 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr)
unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr)
{
struct drbd_bitmap *b = mdev->bitmap;
+ unsigned long *p_addr, *bm;
unsigned long weight;
- int count, s, e;
+ int count, s, e, i, do_now;
ERR_IF(!b) return 0;
- ERR_IF(!b->bm) return 0;
+ ERR_IF(!b->bm_pages) return 0;

spin_lock_irq(&b->bm_lock);
+ if (bm_is_locked(b))
+ bm_print_lock_info(mdev);
weight = b->bm_set;

s = al_enr * BM_WORDS_PER_AL_EXT;
e = min_t(size_t, s + BM_WORDS_PER_AL_EXT, b->bm_words);
+ /* assert that s and e are on the same page */
+ D_ASSERT((e-1) >> (PAGE_SHIFT - LN2_BPL + 3)
+ == s >> (PAGE_SHIFT - LN2_BPL + 3));
count = 0;
if (s < b->bm_words) {
- const unsigned long *w = b->bm+s;
- int n = e-s;
- while (n--) count += hweight_long(*w++);
- n = e-s;
- memset(b->bm+s, -1, n*sizeof(long));
- b->bm_set += n*BITS_PER_LONG - count;
+ i = do_now = e-s;
+ p_addr = bm_map_paddr(b, s);
+ bm = p_addr + MLPP(s);
+ while (i--) {
+ catch_oob_access_start();
+ count += hweight_long(*bm);
+ *bm = -1UL;
+ catch_oob_access_end();
+ bm++;
+ }
+ bm_unmap(p_addr);
+ b->bm_set += do_now*BITS_PER_LONG - count;
if (e == b->bm_words)
b->bm_set -= bm_clear_surplus(b);
} else {
diff --git a/ubuntu/drbd/drbd_buildtag.c b/ubuntu/drbd/drbd_buildtag.c
index f7000b8..2021c1c 100644
--- a/ubuntu/drbd/drbd_buildtag.c
+++ b/ubuntu/drbd/drbd_buildtag.c
@@ -1,7 +1,7 @@
/* automatically generated. DO NOT EDIT. */
#include <linux/drbd_config.h>
-const char * drbd_buildtag(void)
+const char *drbd_buildtag(void)
{
- return "GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4"
- " build by phil@fat-tyre, 2008-05-30 12:59:17";
+ return "GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829"
+ " build by ivoks@ubuntu, 2009-01-17 07:49:56";
}
diff --git a/ubuntu/drbd/drbd_int.h b/ubuntu/drbd/drbd_int.h
index 5cf453f..7231cb4 100644
--- a/ubuntu/drbd/drbd_int.h
+++ b/ubuntu/drbd/drbd_int.h
@@ -57,23 +57,24 @@
/* Compatibility for older kernels */
#ifndef __acquires
# ifdef __CHECKER__
-# define __acquires(x) __attribute__((context(x,0,1)))
-# define __releases(x) __attribute__((context(x,1,0)))
-# define __acquire(x) __context__(x,1)
-# define __release(x) __context__(x,-1)
-# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
+# define __acquires(x) __attribute__((context(x,0,1)))
+# define __releases(x) __attribute__((context(x,1,0)))
+# define __acquire(x) __context__(x,1)
+# define __release(x) __context__(x,-1)
+# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
# else
# define __acquires(x)
# define __releases(x)
-# define __acquire(x) (void)0
-# define __release(x) (void)0
+# define __acquire(x) (void)0
+# define __release(x) (void)0
# define __cond_lock(x,c) (c)
# endif
#endif

/* module parameter, defined in drbd_main.c */
-extern int minor_count;
+extern unsigned int minor_count;
extern int allow_oos;
+extern unsigned int cn_idx;

#ifdef DRBD_ENABLE_FAULTS
extern int enable_faults;
@@ -91,7 +92,7 @@ extern char usermode_helper[];
#include <linux/blkdev.h>
#include <linux/bio.h>

-// XXX do we need this?
+/* XXX do we need this? */
#ifndef TRUE
#define TRUE 1
#endif
@@ -146,11 +147,11 @@ struct drbd_conf;
*************************/

/* handy macro: DUMPP(somepointer) */
-#define DUMPP(A) ERR( #A " = %p in %s:%d
", (A), __FILE__, __LINE__);
-#define DUMPLU(A) ERR( #A " = %lu in %s:%d
", (unsigned long)(A), __FILE__, __LINE__);
-#define DUMPLLU(A) ERR( #A " = %llu in %s:%d
", (unsigned long long)(A), __FILE__, __LINE__);
-#define DUMPLX(A) ERR( #A " = %lx in %s:%d
", (A), __FILE__, __LINE__);
-#define DUMPI(A) ERR( #A " = %d in %s:%d
", (int)(A), __FILE__, __LINE__);
+#define DUMPP(A) ERR(#A " = %p in %s:%d
", (A), __FILE__, __LINE__);
+#define DUMPLU(A) ERR(#A " = %lu in %s:%d
", (unsigned long)(A), __FILE__, __LINE__);
+#define DUMPLLU(A) ERR(#A " = %llu in %s:%d
", (unsigned long long)(A), __FILE__, __LINE__);
+#define DUMPLX(A) ERR(#A " = %lx in %s:%d
", (A), __FILE__, __LINE__);
+#define DUMPI(A) ERR(#A " = %d in %s:%d
", (int)(A), __FILE__, __LINE__);

#define DUMPST(A) DUMPLLU((unsigned long long)(A))

@@ -168,15 +169,14 @@ struct drbd_conf;
#define D_DUMPI(A)
#endif

-/* Info: do not remove the spaces around the "," before ##
- * Otherwise this is not portable from gcc-2.95 to gcc-3.3 */
#define PRINTK(level, fmt, args...)
printk(level "drbd%d: " fmt,
mdev->minor , ##args)

#define ALERT(fmt, args...) PRINTK(KERN_ALERT, fmt , ##args)
#define ERR(fmt, args...) PRINTK(KERN_ERR, fmt , ##args)
-#define DRBD_WARN(fmt, args...) PRINTK(KERN_WARNING, fmt , ##args)
+/* nowadays, WARN() is defined as BUG() without crash in bug.h */
+#define drbd_WARN(fmt, args...) PRINTK(KERN_WARNING, fmt , ##args)
#define INFO(fmt, args...) PRINTK(KERN_INFO, fmt , ##args)
#define DBG(fmt, args...) PRINTK(KERN_DEBUG, fmt , ##args)

@@ -201,8 +201,8 @@ struct drbd_conf;
missed = 0;
toks -= ratelimit_jiffies;
if (lost)
- DRBD_WARN("%d messages suppressed in %s:%d.
",
- lost , __FILE__ , __LINE__ );
+ drbd_WARN("%d messages suppressed in %s:%d.
",
+ lost, __FILE__, __LINE__);
__ret = 1;
} else {
missed++;
@@ -213,7 +213,7 @@ struct drbd_conf;


#ifdef DBG_ASSERTS
-extern void drbd_assert_breakpoint(struct drbd_conf *, char *, char *, int );
+extern void drbd_assert_breakpoint(struct drbd_conf *, char *, char *, int);
# define D_ASSERT(exp) if (!(exp))
drbd_assert_breakpoint(mdev, #exp, __FILE__, __LINE__)
#else
@@ -221,9 +221,9 @@ extern void drbd_assert_breakpoint(struct drbd_conf *, char *, char *, int );
ERR("ASSERT( " #exp " ) in %s:%d
", __FILE__, __LINE__)
#endif
#define ERR_IF(exp) if (({
- int _b = (exp)!=0;
+ int _b = (exp) != 0;
if (_b) ERR("%s: (%s) in %s:%d
",
- __func__, #exp, __FILE__,__LINE__);
+ __func__, #exp, __FILE__, __LINE__);
_b;
}))

@@ -236,6 +236,7 @@ enum {
DRBD_FAULT_DT_WR, /* data */
DRBD_FAULT_DT_RD,
DRBD_FAULT_DT_RA, /* data read ahead */
+ DRBD_FAULT_AL_EE, /* alloc ee */

DRBD_FAULT_MAX,
};
@@ -245,9 +246,9 @@ extern unsigned int
_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type);
static inline int
drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
- return (fault_rate &&
+ return fault_rate &&
(enable_faults & (1<<type)) &&
- _drbd_insert_fault(mdev, type));
+ _drbd_insert_fault(mdev, type);
}
#define FAULT_ACTIVE(_m, _t) (drbd_insert_fault((_m), (_t)))

@@ -257,9 +258,9 @@ drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {

#include <linux/stringify.h>
/* integer division, round _UP_ to the next integer */
-#define div_ceil(A, B) ( (A)/(B) + ((A)%(B) ? 1 : 0) )
+#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
/* usual integer division */
-#define div_floor(A, B) ( (A)/(B) )
+#define div_floor(A, B) ((A)/(B))

/*
* Compatibility Section
@@ -270,7 +271,7 @@ drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
#define RECALC_SIGPENDING() recalc_sigpending();

#if defined(DBG_SPINLOCKS) && defined(__SMP__)
-# define MUST_HOLD(lock) if (!spin_is_locked(lock)) { ERR("Not holding lock! in %s
", __FUNCTION__ ); }
+# define MUST_HOLD(lock) if (!spin_is_locked(lock)) ERR("Not holding lock! in %s
", __func__);
#else
# define MUST_HOLD(lock)
#endif
@@ -281,6 +282,17 @@ drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
# define HAVE_KERNEL_SENDMSG 0
#endif

+#ifndef uninitialized_var
+/* in upstream since 9490991482a2091a828d997adbc088e24c310a4d
+ * Date: Sun May 6 14:49:17 2007 -0700 */
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
+#endif
+
+

/*
* our structs
@@ -290,8 +302,8 @@ drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
({ typecheck(struct drbd_conf*, x);
(x)->magic = (long)(x) ^ DRBD_MAGIC; })
#define IS_VALID_MDEV(x)
- ( typecheck(struct drbd_conf*, x) &&
- ((x) ? (((x)->magic ^ DRBD_MAGIC) == (long)(x)):0))
+ (typecheck(struct drbd_conf*, x) &&
+ ((x) ? (((x)->magic ^ DRBD_MAGIC) == (long)(x)) : 0))

/* drbd_meta-data.c (still in drbd_main.c) */
/* 4th incarnation of the disk layout. */
@@ -304,55 +316,59 @@ extern struct drbd_conf **minor_table;
************************************************** *******************/

enum Drbd_Packet_Cmd {
- Data,
- DataReply, /* Response to DataRequest */
- RSDataReply, /* Response to RSDataRequest */
- Barrier,
- ReportBitMap,
- BecomeSyncTarget,
- BecomeSyncSource,
- UnplugRemote, /* Used at various times to hint the peer */
- DataRequest, /* Used to ask for a data block */
- RSDataRequest, /* Used to ask for a data block for resync */
- SyncParam,
- ReportProtocol,
- ReportUUIDs,
- ReportSizes,
- ReportState,
- ReportSyncUUID,
- AuthChallenge,
- AuthResponse,
- StateChgRequest,
-
- FIRST_ASENDER_CMD,
- Ping = FIRST_ASENDER_CMD,
- PingAck,
- RecvAck, /* Used in protocol B */
- WriteAck, /* Used in protocol C */
- RSWriteAck, /* Is a WriteAck, additionally call set_in_sync(). */
- DiscardAck, /* Used in proto C, two-primaries conflict detection */
- NegAck, /* Sent if local disk is unusable */
- NegDReply, /* Local disk is broken... */
- NegRSDReply, /* Local disk is broken... */
- BarrierAck,
- StateChgReply,
- LAST_ASENDER_CMD = StateChgReply,
-
- OVRequest,
- OVReply,
- OVResult, // Exception to the FIRST/LAST ASENDER_CMD
-
- MAX_CMD,
- MayIgnore = 0x100, /* Flag to test if (cmd > MayIgnore) ... */
- MAX_OPT_CMD,
-
- /* FIXME
- * to get a more useful error message with drbd-8 <-> drbd 0.7.x,
- * these could be reimplemented as special case of HandShake. */
- HandShakeM = 0xfff1, /* First Packet on the MetaSock */
- HandShakeS = 0xfff2, /* First Packet on the Socket */
-
- HandShake = 0xfffe /* FIXED for the next century! */
+ /* receiver (data socket) */
+ Data = 0x00,
+ DataReply = 0x01, /* Response to DataRequest */
+ RSDataReply = 0x02, /* Response to RSDataRequest */
+ Barrier = 0x03,
+ ReportBitMap = 0x04,
+ BecomeSyncTarget = 0x05,
+ BecomeSyncSource = 0x06,
+ UnplugRemote = 0x07, /* Used at various times to hint the peer */
+ DataRequest = 0x08, /* Used to ask for a data block */
+ RSDataRequest = 0x09, /* Used to ask for a data block for resync */
+ SyncParam = 0x0a,
+ ReportProtocol = 0x0b,
+ ReportUUIDs = 0x0c,
+ ReportSizes = 0x0d,
+ ReportState = 0x0e,
+ ReportSyncUUID = 0x0f,
+ AuthChallenge = 0x10,
+ AuthResponse = 0x11,
+ StateChgRequest = 0x12,
+
+ /* asender (meta socket */
+ Ping = 0x13,
+ PingAck = 0x14,
+ RecvAck = 0x15, /* Used in protocol B */
+ WriteAck = 0x16, /* Used in protocol C */
+ RSWriteAck = 0x17, /* Is a WriteAck, additionally call set_in_sync(). */
+ DiscardAck = 0x18, /* Used in proto C, two-primaries conflict detection */
+ NegAck = 0x19, /* Sent if local disk is unusable */
+ NegDReply = 0x1a, /* Local disk is broken... */
+ NegRSDReply = 0x1b, /* Local disk is broken... */
+ BarrierAck = 0x1c,
+ StateChgReply = 0x1d,
+
+ /* "new" commands, no longer fitting into the ordering scheme above */
+
+ OVRequest = 0x1e, /* data socket */
+ OVReply = 0x1f,
+ OVResult = 0x20, /* meta socket */
+ CsumRSRequest = 0x21, /* data socket */
+ RSIsInSync = 0x22, /* meta socket */
+ SyncParam89 = 0x23, /* data socket, protocol version 89 replacement for SyncParam */
+
+ MAX_CMD = 0x24,
+ MayIgnore = 0x100, /* Flag to test if (cmd > MayIgnore) ... */
+ MAX_OPT_CMD = 0x101,
+
+ /* special command ids for handshake */
+
+ HandShakeM = 0xfff1, /* First Packet on the MetaSock */
+ HandShakeS = 0xfff2, /* First Packet on the Socket */
+
+ HandShake = 0xfffe /* FIXED for the next century! */
};

static inline const char *cmdname(enum Drbd_Packet_Cmd cmd)
@@ -372,6 +388,7 @@ static inline const char *cmdname(enum Drbd_Packet_Cmd cmd)
[DataRequest] = "DataRequest",
[RSDataRequest] = "RSDataRequest",
[SyncParam] = "SyncParam",
+ [SyncParam89] = "SyncParam89",
[ReportProtocol] = "ReportProtocol",
[ReportUUIDs] = "ReportUUIDs",
[ReportSizes] = "ReportSizes",
@@ -394,24 +411,19 @@ stati
 

Thread Tools




All times are GMT. The time now is 03:57 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org