[DRBD-cvs] svn commit by phil - r2173 - in branches/drbd-0.7/drbd: . linux - Better handling of IO errors while reading the activity

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Tue Apr 25 11:45:04 CEST 2006


Author: phil
Date: 2006-04-25 11:45:03 +0200 (Tue, 25 Apr 2006)
New Revision: 2173

Modified:
   branches/drbd-0.7/drbd/drbd_actlog.c
   branches/drbd-0.7/drbd/drbd_fs.c
   branches/drbd-0.7/drbd/drbd_int.h
   branches/drbd-0.7/drbd/linux/drbd.h
   branches/drbd-0.7/drbd/linux/drbd_config.h
Log:
Better handling of IO errors while reading the activity log. (attach)


Modified: branches/drbd-0.7/drbd/drbd_actlog.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_actlog.c	2006-04-24 12:40:29 UTC (rev 2172)
+++ branches/drbd-0.7/drbd/drbd_actlog.c	2006-04-25 09:45:03 UTC (rev 2173)
@@ -368,6 +368,12 @@
 	return 1;
 }
 
+/**
+ * drbd_al_read_tr: Reads a single transaction record form the 
+ * on disk activity log.
+ * Returns -1 on IO error, 0 on checksum error and 1 if it is a valid
+ * record.
+ */
 STATIC int drbd_al_read_tr(struct Drbd_Conf *mdev,
 			   struct al_transaction* b,
 			   int index)
@@ -381,7 +387,7 @@
 	if(!drbd_md_sync_page_io(mdev,sector,READ)) {
 		drbd_chk_io_error(mdev, 1);
 		drbd_io_error(mdev);
-		return 0;
+		return -1;
 	}
 
 	rv = ( be32_to_cpu(b->magic) == DRBD_MAGIC );
@@ -394,7 +400,12 @@
 	return rv;
 }
 
-void drbd_al_read_log(struct Drbd_Conf *mdev)
+/**
+ * drbd_al_read_log: Restores the activity log from its on disk
+ * representation. Returns 1 on success, returns 0 when 
+ * reading the log failed due to IO errors.
+ */
+int drbd_al_read_log(struct Drbd_Conf *mdev)
 {
 	struct al_transaction* buffer;
 	int from=-1,to=-1,i,cnr, overflow=0,rv;
@@ -413,7 +424,12 @@
 
 	// Find the valid transaction in the log
 	for(i=0;i<=mx;i++) {
-		if(!drbd_al_read_tr(mdev,buffer,i)) continue;
+		rv = drbd_al_read_tr(mdev,buffer,i);
+		if(rv == 0) continue;
+		if(rv == -1) {
+			up(&mdev->md_io_mutex);
+			return 0;
+		}
 		cnr = be32_to_cpu(buffer->tr_number);
 		// INFO("index %d valid tnr=%d\n",i,cnr);
 
@@ -433,7 +449,7 @@
 		WARN("No usable activity log found.\n");
 
 		up(&mdev->md_io_mutex);
-		return;
+		return 1;
 	}
 
 	// Read the valid transactions.
@@ -448,7 +464,11 @@
 		unsigned int trn;
 
 		rv = drbd_al_read_tr(mdev,buffer,i);
-		ERR_IF(!rv) goto cancel;
+		ERR_IF(rv == 0) goto cancel;
+		if(rv == -1) {
+			up(&mdev->md_io_mutex);
+			return 0;
+		}
 
 		trn=be32_to_cpu(buffer->tr_number);
 
@@ -489,6 +509,8 @@
 
 	INFO("Found %d transactions (%d active extents) in activity log.\n",
 	     transactions,active_extents);
+
+	return 1;
 }
 
 /**

Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-04-24 12:40:29 UTC (rev 2172)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-04-25 09:45:03 UTC (rev 2173)
@@ -567,11 +567,20 @@
 	}
 
 	if (md_gc_valid > 0) {
-		drbd_al_read_log(mdev);
-		if (apply_al) {
+		i = drbd_al_read_log(mdev);
+		if (apply_al && i) {
 			drbd_al_apply_to_bm(mdev);
 			drbd_al_to_on_disk_bm(mdev);
 		}
+		if(!i) {
+			ERR("IO error on meta device while reading AL\n");
+			drbd_free_ll_dev(mdev);
+			set_cstate(mdev,Unconfigured);
+			retcode = MDIOError;
+			module_put(THIS_MODULE);
+			if (put_user(retcode, &arg->ret_code)) return -EFAULT;
+			return -EINVAL;
+		}
 	} /* else {
 	     FIXME wipe out on disk al!
 	} */

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2006-04-24 12:40:29 UTC (rev 2172)
+++ branches/drbd-0.7/drbd/drbd_int.h	2006-04-25 09:45:03 UTC (rev 2173)
@@ -1090,7 +1090,7 @@
 extern void drbd_rs_complete_io(struct Drbd_Conf *mdev, sector_t sector);
 extern int drbd_rs_begin_io(struct Drbd_Conf *mdev, sector_t sector);
 extern void drbd_rs_cancel_all(drbd_dev* mdev);
-extern void drbd_al_read_log(struct Drbd_Conf *mdev);
+extern int drbd_al_read_log(struct Drbd_Conf *mdev);
 extern void __drbd_set_in_sync(drbd_dev* mdev, sector_t sector, int size, const char* file, const unsigned int line);
 #define drbd_set_in_sync(mdev,sector,size) \
 	__drbd_set_in_sync(mdev,sector,size, __FILE__, __LINE__ )

Modified: branches/drbd-0.7/drbd/linux/drbd.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd.h	2006-04-24 12:40:29 UTC (rev 2172)
+++ branches/drbd-0.7/drbd/linux/drbd.h	2006-04-25 09:45:03 UTC (rev 2173)
@@ -128,6 +128,7 @@
 	MDMounted,
 	LDMDInvalid,
 	LDDeviceTooLarge,
+	MDIOError
 };
 
 struct ioctl_disk_config {

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2006-04-24 12:40:29 UTC (rev 2172)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2006-04-25 09:45:03 UTC (rev 2173)
@@ -23,7 +23,7 @@
 extern const char * drbd_buildtag(void);
 
 #define REL_VERSION "0.7.17"
-#define API_VERSION 77
+#define API_VERSION 78
 #define PRO_VERSION 74
 
 //#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces



More information about the drbd-cvs mailing list