[DRBD-cvs] svn commit by phil - r2272 - trunk/drbd - * Moved releasing of backing device stuff into after_st

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Wed Jul 12 11:51:27 CEST 2006


Author: phil
Date: 2006-07-12 11:51:26 +0200 (Wed, 12 Jul 2006)
New Revision: 2272

Modified:
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
Log:
* Moved releasing of backing device stuff into after_state_ch()
* Moved stuff of the disconnect_ioctl code into after_state_ch()
* Made drbd_rs_cancel_all() more robust, it does not crash if
  there is no backing storage currently.
* Fixed the drbd_io_error() to also rely on the release-backing
  -device stuff in the after_state_ch() function.
    
Now a detach followed by disconnect no longer crashes ;)    


Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2006-07-12 08:08:55 UTC (rev 2271)
+++ trunk/drbd/drbd_actlog.c	2006-07-12 09:51:26 UTC (rev 2272)
@@ -939,14 +939,17 @@
 
 	spin_lock_irq(&mdev->al_lock);
 
-	for(i=0;i<mdev->resync->nr_elements;i++) {
-		bm_ext = (struct bm_extent*) lc_entry(mdev->resync,i);
-		if(bm_ext->lce.lc_number == LC_FREE) continue;
-		bm_ext->lce.refcnt = 0; // Rude but ok.
-		bm_ext->rs_left = 0;
-		clear_bit(BME_LOCKED,&bm_ext->flags);
-		clear_bit(BME_NO_WRITES,&bm_ext->flags);
-		lc_del(mdev->resync,&bm_ext->lce);
+	if(inc_md_only(mdev,Failed)) { // Makes sure mdev->resync is there.
+		for(i=0;i<mdev->resync->nr_elements;i++) {
+			bm_ext = (struct bm_extent*) lc_entry(mdev->resync,i);
+			if(bm_ext->lce.lc_number == LC_FREE) continue;
+			bm_ext->lce.refcnt = 0; // Rude but ok.
+			bm_ext->rs_left = 0;
+			clear_bit(BME_LOCKED,&bm_ext->flags);
+			clear_bit(BME_NO_WRITES,&bm_ext->flags);
+			lc_del(mdev->resync,&bm_ext->lce);
+		}
+		dec_local(mdev);
 	}
 	atomic_set(&mdev->resync_locked,0);
 	spin_unlock_irq(&mdev->al_lock);

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2006-07-12 08:08:55 UTC (rev 2271)
+++ trunk/drbd/drbd_fs.c	2006-07-12 09:51:26 UTC (rev 2272)
@@ -1079,17 +1079,6 @@
 		return -ENETRESET;
 	}
 
-	drbd_sync_me(mdev);
-
-	/* since inc_local() only works as long as disk >= Inconsistent,
-	   and it is Diskless here, local_cnt can only go down, it can
-	   not increase... It will reach zero */
-	wait_event(mdev->cstate_wait, !atomic_read(&mdev->local_cnt));
-
-	drbd_free_bc(mdev->bc);	mdev->bc = NULL;
-	lc_free(mdev->resync);  mdev->resync = NULL;
-	lc_free(mdev->act_log); mdev->act_log = NULL;
-
 	return 0;
 }
 
@@ -1152,16 +1141,9 @@
 
 STATIC int drbd_ioctl_unconfig_net(struct Drbd_Conf *mdev)
 {
-	drbd_state_t os,ns;
 	int r;
 
-	// Request state silently:
-	spin_lock_irq(&mdev->req_lock);
-	os = mdev->state;
-	r = _drbd_set_state(mdev, _NS(conn,StandAlone), 0);
-	ns = mdev->state;
-	spin_unlock_irq(&mdev->req_lock);
-	after_state_ch(mdev,os,ns,0);
+	r = _drbd_request_state(mdev,NS(conn,StandAlone),0);	// silently.
 
 	if ( r == SS_NothingToDo )  return 0;
 	if ( r == SS_PrimaryNOP ) {
@@ -1181,9 +1163,6 @@
 		mdev->cram_hmac_tfm = NULL;
 	}
 
-	drbd_sync_me(mdev); /* FIXME what if fsync returns error */
-	drbd_thread_stop(&mdev->receiver);
-
 	return 0;
 }
 

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-07-12 08:08:55 UTC (rev 2271)
+++ trunk/drbd/drbd_int.h	2006-07-12 09:51:26 UTC (rev 2272)
@@ -645,7 +645,6 @@
 	STOP_SYNC_TIMER,	// tell timer to cancel itself
 	UNPLUG_QUEUED,		// only relevant with kernel 2.4
 	UNPLUG_REMOTE,		// whether sending a "UnplugRemote" makes sense
-	PROCESS_EE_RUNNING,	// eek!
 	MD_DIRTY,		// current gen counts and flags not yet on disk
 	SYNC_STARTED,		// Needed to agree on the exact point in time..
 	UNIQUE,                 // Set on one node, cleared on the peer!
@@ -1237,11 +1236,12 @@
 			ERR("Ignoring local IO error!\n");
 			break;
 		case Panic:
-			_drbd_set_state(mdev,_NS(disk,Failed),1);
+			_drbd_set_state(mdev,_NS(disk,Failed),ChgStateHard);
 			drbd_panic("IO error on backing device!\n");
 			break;
 		case Detach:
-			if (_drbd_set_state(mdev,_NS(disk,Failed),1) == 1) {
+			if (_drbd_set_state(mdev,_NS(disk,Failed),ChgStateHard) 
+			    == SS_Success) {
 				ERR("Local IO failed. Detaching...\n");
 			}
 			break;

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-07-12 08:08:55 UTC (rev 2271)
+++ trunk/drbd/drbd_main.c	2006-07-12 09:51:26 UTC (rev 2272)
@@ -496,7 +496,8 @@
 
 	spin_lock_irqsave(&mdev->req_lock,flags);
 	if( (send = (mdev->state.disk == Failed)) ) {
-		_drbd_set_state(mdev,_NS(disk,Diskless),ChgStateHard);
+		_drbd_set_state(mdev,_NS(disk,Diskless),
+				ChgStateHard|ScheduleAfter);
 	}
 	D_ASSERT(mdev->state.disk <= Failed);
 	spin_unlock_irqrestore(&mdev->req_lock,flags);
@@ -510,21 +511,7 @@
 	D_ASSERT(!drbd_md_test_flag(mdev->bc,MDF_Consistent));
 	drbd_md_sync(mdev);
 
-	if ( wait_event_interruptible_timeout(mdev->cstate_wait,
-		     atomic_read(&mdev->local_cnt) == 0 , HZ ) <= 0) {
-		WARN("Not releasing backing storage device.\n");
-		/* FIXME if there *are* still references,
-		 * we should be here again soon enough.
-		 * but what if not?
-		 * we still should free our ll and md devices */
-	} else {
-		/* no race. since the DISKLESS bit is set first,
-		 * further references to local_cnt are shortlived,
-		 * and no real references on the device. */
-		WARN("Releasing backing storage device.\n");
-		drbd_free_bc(mdev->bc);
-		mdev->bc=NULL;
-	}
+	/* Releasing the backing device is done in after_state_ch() */
 
 	return ok;
 }
@@ -1079,6 +1066,19 @@
 		drbd_bm_unlock(mdev);		
 	}
 
+	if ( os.disk > Diskless && ns.disk == Diskless ) {
+		drbd_sync_me(mdev);
+
+		/* since inc_local() only works as long as disk>=Inconsistent,
+		   and it is Diskless here, local_cnt can only go down, it can
+		   not increase... It will reach zero */
+		wait_event(mdev->cstate_wait, !atomic_read(&mdev->local_cnt));
+
+		drbd_free_bc(mdev->bc);	mdev->bc = NULL;
+		lc_free(mdev->resync);  mdev->resync = NULL;
+		lc_free(mdev->act_log); mdev->act_log = NULL;
+	}
+
 	/* it feels better to have the module_put last ... */
 	if ( (os.disk > Diskless || os.conn > StandAlone) &&
 	     ns.disk == Diskless && ns.conn == StandAlone ) {
@@ -1173,7 +1173,6 @@
 	     current->comm, current->pid,
 	     thi->task ? thi->task->comm : "NULL", thi->t_state, ns, wait); */
 
-
 	if (thi->t_state == None) {
 		spin_unlock(&thi->t_lock);
 		return;
@@ -1202,6 +1201,7 @@
 	spin_unlock(&thi->t_lock);
 
 	if (wait) {
+		if (thi->task == current) return;
 		D_ASSERT(thi->t_state == Exiting);
 		wait_for_completion(&thi->startstop);
 		spin_lock(&thi->t_lock);
@@ -2158,6 +2158,7 @@
 	 * oldest_barrier
 	 */
 
+	drbd_thread_stop(&mdev->receiver);
 	drbd_thread_stop(&mdev->worker);
 
 	/* no need to lock it, I'm the only thread alive */
@@ -2710,8 +2711,11 @@
 	if (!test_and_clear_bit(MD_DIRTY,&mdev->flags)) return;
 	del_timer(&mdev->md_sync_timer);
 	INFO("Writing meta data super block now.\n");
-	ERR_IF(!inc_md_only(mdev,Attaching)) return;
 
+	// We use here Failed and not Attaching because we try to write
+	// metadata even if we detach due to a disk failure!
+	ERR_IF(!inc_md_only(mdev,Failed)) return;
+
 	down(&mdev->md_io_mutex);
 	buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
 	memset(buffer,0,512);



More information about the drbd-cvs mailing list