[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