[DRBD-cvs] drbd by phil; * Removed the uggly (and probabely buggy...

drbd-user@lists.linbit.com drbd-user@lists.linbit.com
Wed, 30 Jun 2004 16:59:29 +0200 (CEST)


DRBD CVS committal

Author  : phil
Module  : drbd

Dir     : drbd/drbd


Modified Files:
      Tag: rel-0_7-branch
	drbd_actlog.c drbd_compat_wrappers.h drbd_int.h drbd_main.c 


Log Message:
* Removed the uggly (and probabely buggy s390 hack, that defined the
  MD_HARDSECT as 4k in case we compile on the s390.
* Added real support for block devices with hardsect_size != 512 byte.
  [Probabely only relevant for the s390]

===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_actlog.c,v
retrieving revision 1.1.2.111
retrieving revision 1.1.2.112
diff -u -3 -r1.1.2.111 -r1.1.2.112
--- drbd_actlog.c	25 Jun 2004 13:19:50 -0000	1.1.2.111
+++ drbd_actlog.c	30 Jun 2004 14:59:24 -0000	1.1.2.112
@@ -34,79 +34,46 @@
  * this is mostly from drivers/md/md.c
  */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-int drbd_md_sync_page_io(drbd_dev *mdev, sector_t sector, int rw)
+STATIC int _drbd_md_sync_page_io(drbd_dev *mdev, struct page *page, 
+				 sector_t sector, int rw, int size)
 {
 	struct buffer_head bh;
 	struct completion event;
-	int ok = 0;
-
-	D_ASSERT(semaphore_is_locked(&mdev->md_io_mutex));
+	int ok;
 
-	if (!mdev->md_bdev) {
-		if (DRBD_ratelimit(5*HZ,5)) {
-			ERR("mdev->md_bdev==NULL\n");
-			dump_stack();
-		}
-		return 0;
-	}
-#ifdef PARANOIA
-	if (rw != WRITE) {
-		void *b = page_address(mdev->md_io_page);
-		memset(b,0,PAGE_SIZE);
-	}
-#endif
 	init_completion(&event);
 	init_buffer(&bh, drbd_md_io_complete, &event);
 	bh.b_rdev = mdev->md_bdev;
 	bh.b_rsector = sector;
 	bh.b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock);
-	bh.b_size = MD_HARDSECT; 
-	bh.b_page = mdev->md_io_page;
+	bh.b_size = size; 
+	bh.b_page = page;
 	bh.b_reqnext = NULL;
-	bh.b_data = page_address(mdev->md_io_page);
+	bh.b_data = page_address(page);
 	generic_make_request(rw, &bh);
 
 	run_task_queue(&tq_disk);
 	wait_for_completion(&event);
 
 	ok = test_bit(BH_Uptodate, &bh.b_state);
-	if (unlikely(!ok)) {
-		ERR("drbd_md_sync_page_io(,%lu,%d) failed!\n",
-				(unsigned long)sector,rw);
-	}
 
 	return ok;
 }
 #else
-int drbd_md_sync_page_io(drbd_dev *mdev, sector_t sector, int rw)
+STATIC int _drbd_md_sync_page_io(drbd_dev *mdev, struct page *page, 
+				 sector_t sector, int rw, int size)
 {
 	struct bio bio;
 	struct bio_vec vec;
 	struct completion event;
-	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
-	int ok = 0;
-
-	D_ASSERT(semaphore_is_locked(&mdev->md_io_mutex));
+	int ok;
 
-	if (!mdev->md_bdev) {
-		if (DRBD_ratelimit(5*HZ,5)) {
-			ERR("mdev->md_bdev==NULL\n");
-			dump_stack();
-		}
-		return 0;
-	}
-#ifdef PARANOIA
-	if (rw != WRITE) {
-		void *b = page_address(mdev->md_io_page);
-		memset(b,0,PAGE_SIZE);
-	}
-#endif
 	bio_init(&bio);
 	bio.bi_io_vec = &vec;
-	vec.bv_page = mdev->md_io_page;
+	vec.bv_page = page;
 	vec.bv_offset = 0;
 	vec.bv_len =
-	bio.bi_size = MD_HARDSECT;
+	bio.bi_size = size;
 	bio.bi_vcnt = 1;
 	bio.bi_idx = 0;
 	bio.bi_bdev = mdev->md_bdev;
@@ -115,6 +82,72 @@
 	bio.bi_private = &event;
 	bio.bi_end_io = drbd_md_io_complete;
 
+#ifdef BIO_RW_SYNC
+	submit_bio(rw | (1 << BIO_RW_SYNC), &bio);
+#else
+	submit_bio(rw, &bio);
+	drbd_blk_run_queue(bdev_get_queue(mdev->md_bdev));
+#endif
+	wait_for_completion(&event);
+
+	ok = test_bit(BIO_UPTODATE, &bio.bi_flags);
+
+	return ok;
+}
+#endif
+
+int drbd_md_sync_page_io(drbd_dev *mdev, sector_t sector, int rw)
+{
+	int hardsect,mask,ok,offset=0;
+	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
+	struct page *iop = mdev->md_io_page;
+
+	D_ASSERT(semaphore_is_locked(&mdev->md_io_mutex));
+
+	if (!mdev->md_bdev) {
+		if (DRBD_ratelimit(5*HZ,5)) {
+			ERR("mdev->md_bdev==NULL\n");
+			dump_stack();
+		}
+		return 0;
+	}
+
+
+	hardsect = drbd_get_hardsect(mdev->md_bdev);
+
+	// in case hardsect != 512 [ s390 only? ]
+	if( hardsect != MD_HARDSECT ) {
+		if(!mdev->md_io_tmpp) {
+			struct page *page = alloc_page(GFP_KERNEL);
+			if(!page) return 0;
+
+			WARN("Meta data's bdev hardsect_size != %d\n",
+			     MD_HARDSECT);
+			WARN("Workaround engaged (has performace impact).\n");
+
+			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 );
+		offset = sector & mask;
+		sector = sector & ~mask;
+		iop = mdev->md_io_tmpp;
+
+		if (rw == WRITE) {
+			void *p = page_address(mdev->md_io_page);
+			void *hp = page_address(mdev->md_io_tmpp);
+
+			ok = _drbd_md_sync_page_io(mdev,iop,
+						   sector,READ,hardsect);
+
+			if (unlikely(!ok)) return 0;
+
+			memcpy(hp + offset*MD_HARDSECT , p, MD_HARDSECT);
+		}
+	}
+
 #if DUMP_MD >= 3
 	INFO("%s [%d]:%s(,%ld,%s)\n",
 	     current->comm, current->pid, __func__,
@@ -127,23 +160,23 @@
 		     current->comm, current->pid, __func__,
 		     (long)sector, rw ? "WRITE" : "READ");
 	}
-#ifdef BIO_RW_SYNC
-	submit_bio(rw | (1 << BIO_RW_SYNC), &bio);
-#else
-	submit_bio(rw, &bio);
-	drbd_blk_run_queue(bdev_get_queue(mdev->md_bdev));
-#endif
-	wait_for_completion(&event);
 
-	ok = test_bit(BIO_UPTODATE, &bio.bi_flags);
+	ok = _drbd_md_sync_page_io(mdev,iop,sector,rw,hardsect);
 	if (unlikely(!ok)) {
 		ERR("drbd_md_sync_page_io(,%lu,%s) failed!\n",
-				(unsigned long)sector,rw ? "WRITE" : "READ");
+		    (unsigned long)sector,rw ? "WRITE" : "READ");
+	}
+
+	if( hardsect != MD_HARDSECT && rw == READ ) {
+		void *p = page_address(mdev->md_io_page);
+		void *hp = page_address(mdev->md_io_tmpp);
+
+		memcpy(p, hp + offset*MD_HARDSECT, MD_HARDSECT);
 	}
 
 	return ok;
 }
-#endif
+
 
 struct __attribute__((packed)) al_transaction {
 	u32       magic;
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_compat_wrappers.h,v
retrieving revision 1.1.2.48
retrieving revision 1.1.2.49
diff -u -3 -r1.1.2.48 -r1.1.2.49
--- drbd_compat_wrappers.h	30 Jun 2004 09:12:20 -0000	1.1.2.48
+++ drbd_compat_wrappers.h	30 Jun 2004 14:59:24 -0000	1.1.2.49
@@ -19,6 +19,11 @@
  * appropriate.
  */
 
+static inline sector_t drbd_get_hardsect(kdev_t dev)
+{
+	return hardsect_size[MAJOR(dev)][MINOR(dev)];
+}
+
 /* Returns the number of 512 byte sectors of the device */
 static inline sector_t drbd_get_capacity(kdev_t dev)
 {
@@ -319,6 +324,11 @@
 extern int drbd_dio_end_sec        (struct bio *bio, unsigned int bytes_done, int error);
 extern int drbd_dio_end            (struct bio *bio, unsigned int bytes_done, int error);
 extern int drbd_read_bi_end_io     (struct bio *bio, unsigned int bytes_done, int error);
+
+static inline sector_t drbd_get_hardsect(struct block_device *bdev)
+{
+	return bdev->bd_disk->queue->hardsect_size;
+}
 
 /* Returns the number of 512 byte sectors of the device */
 static inline sector_t drbd_get_capacity(struct block_device *bdev)
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.179
retrieving revision 1.58.2.180
diff -u -3 -r1.58.2.179 -r1.58.2.180
--- drbd_int.h	30 Jun 2004 09:12:21 -0000	1.58.2.179
+++ drbd_int.h	30 Jun 2004 14:59:24 -0000	1.58.2.180
@@ -738,6 +738,7 @@
 	struct list_head busy_blocks;
 	NOT_IN_26(struct tq_struct write_hint_tq;)
 	struct page *md_io_page;      // one page buffer for md_io
+	struct page *md_io_tmpp;     // in case hardsect != 512 [ s390 only? ]
 	struct semaphore md_io_mutex; // protects the md_io_buffer
 	spinlock_t al_lock;
 	wait_queue_head_t al_wait;
@@ -809,12 +810,7 @@
 #define MD_AL_MAX_SIZE 64   // = 32 kb LOG  ~ 3776 extents ~ 14 GB Storage
 #define MD_BM_OFFSET (MD_AL_OFFSET + MD_AL_MAX_SIZE) //Allows up to about 3.8TB
 
-// All metadata IO is done in units of MD_HARDSECT
-#if defined(CONFIG_ARCH_S390) | defined(CONFIG_ARCH_S390X)
-#define MD_HARDSECT_B    12     // Necessary for s390
-#else
-#define MD_HARDSECT_B    9      // Nice for "small" hardware.
-#endif
+#define MD_HARDSECT_B    9     // Since the smalles IO unit is usually 512 byte
 #define MD_HARDSECT      (1<<MD_HARDSECT_B)
 
 // activity log
@@ -835,7 +831,7 @@
 #endif
 
 // resync bitmap
-// 16MB sized 'bitmap extent' to track syncer usage [128MB on the x390]
+// 16MB sized 'bitmap extent' to track syncer usage
 struct bm_extent {
 	struct lc_element lce;
 	int rs_left; //number of bits set (out of sync) in this extent.
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_main.c,v
retrieving revision 1.73.2.193
retrieving revision 1.73.2.194
diff -u -3 -r1.73.2.193 -r1.73.2.194
--- drbd_main.c	30 Jun 2004 09:12:21 -0000	1.73.2.193
+++ drbd_main.c	30 Jun 2004 14:59:24 -0000	1.73.2.194
@@ -1544,6 +1544,9 @@
 			if (mdev->md_io_page)
 				__free_page(mdev->md_io_page);
 
+			if (mdev->md_io_tmpp)
+				__free_page(mdev->md_io_tmpp);
+
 			if (mdev->act_log) lc_free(mdev->act_log);
 		}
 		drbd_destroy_mempools();