[DRBD-cvs] drbd by phil; An excellent patch by LGE * A generic fi...
drbd-user@lists.linbit.com
drbd-user@lists.linbit.com
Thu, 8 Jul 2004 10:04:54 +0200 (CEST)
DRBD CVS committal
Author : phil
Module : drbd
Dir : drbd/drbd
Modified Files:
Tag: rel-0_7-branch
drbd_bitmap.c drbd_compat_types.h
Log Message:
An excellent patch by LGE
* A generic find_next_bit() for linux-2.4.x compatibility on exotic
architectures.
* Additional debugging code for drbd_bitmap.c (only enabled if DUMP_MD>3)
* An additional option to drbd_config.h to disable find_next_bit() on
Linux-2.4.x (probabely vendor kernels have it already...)
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_bitmap.c,v
retrieving revision 1.1.2.15
retrieving revision 1.1.2.16
diff -u -3 -r1.1.2.15 -r1.1.2.16
--- drbd_bitmap.c 7 Jul 2004 14:54:09 -0000 1.1.2.15
+++ drbd_bitmap.c 8 Jul 2004 08:04:49 -0000 1.1.2.16
@@ -170,21 +170,25 @@
#endif
// }
-/* debugging aid
-STATIC void bm_end_info(drbd_dev *mdev)
+#if DUMP_MD >= 3
+/* debugging aid */
+STATIC void bm_end_info(drbd_dev *mdev, const char* where)
{
struct drbd_bitmap *b = mdev->bitmap;
- size_t w = b->bm_bits >> LN2_BPL;
+ size_t w = (b->bm_bits-1) >> LN2_BPL;
- INFO("bm_set=%lu\n",b->bm_set);
- INFO("bm[%d]=0x%lX\n",w,b->bm[w]);
+ INFO("%s: bm_set=%lu\n", where, b->bm_set);
+ INFO("bm[%d]=0x%lX\n", w, b->bm[w]);
w++;
if ( w < b->bm_words ) {
+ D_ASSERT(w == b->bm_words -1);
INFO("bm[%d]=0x%lX\n",w,b->bm[w]);
}
}
-*/
+#else
+#define bm_end_info(ignored...) ((void)(0))
+#endif
/* long word offset of _bitmap_ sector */
#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL))
@@ -317,6 +321,7 @@
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 {
@@ -345,6 +350,7 @@
b->bm_words = words;
b->bm_dev_capacity = capacity;
bm_clear_surplus(b);
+ bm_end_info(mdev, __FUNCTION__ );
spin_unlock_irq(&b->bm_lock);
INFO("resync bitmap: bits=%lu words=%lu\n",bits,words);
}
@@ -426,6 +432,7 @@
*/
if (offset+number == b->bm_words) {
b->bm_set -= bm_clear_surplus(b);
+ bm_end_info(mdev, __FUNCTION__ );
}
spin_unlock_irq(&b->bm_lock);
}
@@ -464,6 +471,7 @@
*/
if (offset+number == b->bm_words) {
b->bm_set -= bm_clear_surplus(b);
+ bm_end_info(mdev, __FUNCTION__ );
}
spin_unlock_irq(&b->bm_lock);
}
@@ -533,7 +541,7 @@
offset = S2W(enr); // word offset into bitmap
num_words = min(S2W(1), bm_words - offset);
#if DUMP_MD >= 3
- INFO("write_sect: sector=%lu offset=%u num_words=%u\n",
+ INFO("read_sect: sector=%lu offset=%u num_words=%u\n",
enr, offset, num_words);
#endif
drbd_bm_set_lel( mdev, offset, num_words,
@@ -598,6 +606,9 @@
INFO("write_sect: sector=%lu offset=%u num_words=%u\n",
enr, offset, num_words);
#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) );
if (!drbd_md_sync_page_io(mdev,on_disk_sector,WRITE)) {
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_compat_types.h,v
retrieving revision 1.1.2.9
retrieving revision 1.1.2.10
diff -u -3 -r1.1.2.9 -r1.1.2.10
--- drbd_compat_types.h 3 Jul 2004 11:38:11 -0000 1.1.2.9
+++ drbd_compat_types.h 8 Jul 2004 08:04:49 -0000 1.1.2.10
@@ -42,6 +42,13 @@
#include <linux/completion.h>
#endif
+/* note that if you use some verndor kernels like SuSE,
+ * their 2.4.X variant probably already contain equivalent definitions.
+ * you then have to disable this compat again...
+ */
+
+#ifndef HAVE_FIND_NEXT_BIT /* { */
+
#if defined(__i386__) || defined(__arch_um__)
/**
* find_first_bit - find the first set bit in a memory region
@@ -171,9 +178,70 @@
found_middle:
return result + __ffs(tmp);
}
+#elif defined(USE_GENERIC_FIND_NEXT_BIT)
+
+#if BITS_PER_LONG == 32
+#define _xFFFF 31ul
+#define _x10000 32
+#define _xSHIFT 5
+#elif BITS_PER_LONG == 64
+#define _xFFFF 63ul
+#define _x10000 64
+#define _xSHIFT 6
+#else
+#error "Unexpected BITS_PER_LONG"
+#endif
+
+/* slightly large to be inlined, but anyways... */
+static inline unsigned long
+find_next_bit(void * addr, unsigned long size, unsigned long offset)
+{
+ unsigned long * p = ((unsigned long *) addr) + (offset >> _xSHIFT);
+ unsigned long result = offset & ~_xFFFF;
+ unsigned long tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= _xFFFF;
+ if (offset) {
+ tmp = *(p++);
+ tmp &= ~0UL << offset;
+ if (size < _x10000)
+ goto found_first;
+ if (tmp)
+ goto found_middle;
+ size -= _x10000;
+ result += _x10000;
+ }
+ while (size & ~_xFFFF) {
+ if ((tmp = *(p++)))
+ goto found_middle;
+ result += _x10000;
+ size -= _x10000;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+ found_first:
+ tmp &= ~0UL >> (_x10000 - size);
+ if (!tmp)
+ return result + size;
+ found_middle: /* if this is reached, we know that (tmp != 0) */
+ return result + generic_ffs(tmp)-1;
+}
+
+#undef _xFFFF
+#undef _x10000
+#undef _xSHIFT
+
#else
#warning "You probabely need to copy find_next_bit() from a 2.6.x kernel."
+#warning "Or enable low performance generic C-code"
+#warning "(USE_GENERIC_FIND_NEXT_BIT in drbd_config.h)"
#endif
+
+#endif /* HAVE_FIND_NEXT_BIT } */
#ifndef ALIGN
#define ALIGN(x,a) ( ((x) + (a)-1) &~ ((a)-1) )