[DRBD-cvs] svn commit by phil - r2640 - in trunk: drbd drbd/linux user - * Removed the race between Primary->Secondary and open(

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Thu Dec 21 16:49:29 CET 2006


Author: phil
Date: 2006-12-21 16:49:27 +0100 (Thu, 21 Dec 2006)
New Revision: 2640

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
   trunk/user/drbdsetup.c
Log:

* Removed the race between Primary->Secondary and open(2)
* Removed the now unused bit WRITER_PRESENT



Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/drbd/drbd_int.h	2006-12-21 15:49:27 UTC (rev 2640)
@@ -673,7 +673,6 @@
 	SEND_PING,		// whether asender should send a ping asap
 	WRITE_ACK_PENDING,	// so BarrierAck won't overtake WriteAck
 	WORK_PENDING,		// completion flag for drbd_disconnect
-	WRITER_PRESENT,		// somebody opened us with write intent
 	STOP_SYNC_TIMER,	// tell timer to cancel itself
 	UNPLUG_QUEUED,		// only relevant with kernel 2.4
 	UNPLUG_REMOTE,		// whether sending a "UnplugRemote" makes sense

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/drbd/drbd_main.c	2006-12-21 15:49:27 UTC (rev 2640)
@@ -542,6 +542,9 @@
 	}
 
 	if( rv <= 0 ) /* already found a reason to abort */;
+	else if( ns.role == Secondary && mdev->open_cnt ) 
+		rv=SS_DeviceInUse;
+
 	else if( ns.role == Primary && ns.conn < Connected &&
 		 ns.disk < UpToDate ) rv=SS_NoUpToDateDisk;
 
@@ -1835,28 +1838,25 @@
 STATIC int drbd_open(struct inode *inode, struct file *file)
 {
 	drbd_dev *mdev;
+	unsigned long flags;
+	int rv=0;
 
 	mdev = minor_to_mdev(MINOR(inode->i_rdev));
 	if(!mdev) return -ENODEV;
 
-	/* we might allow read-only open on non-Primary */
+	spin_lock_irqsave(&mdev->req_lock,flags);
+	/* The have a stable mdev->state.role and no race with updating open_cnt */
+
 	if( mdev->state.role != Primary && !allow_oos) {
-		return -EMEDIUMTYPE;
+		rv = -EMEDIUMTYPE;
+	} else if (file->f_mode & FMODE_WRITE && mdev->state.role != Primary) {
+		rv = -EROFS;
 	}
-	/* but we cannot allow writes on non-Primary */
-	if (file->f_mode & FMODE_WRITE) {
-		if( mdev->state.role != Primary) {
-			return -EROFS;
-		}
-		set_bit(WRITER_PRESENT, &mdev->flags);
-	}
 
-	/* FIXME race with Primary -> Secondary
-	 * state change */
+	if(!rv) mdev->open_cnt++;
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
 
-	mdev->open_cnt++;
-
-	return 0;
+	return rv;
 }
 
 STATIC int drbd_close(struct inode *inode, struct file *file)
@@ -1873,9 +1873,7 @@
 	       inode->i_writecount);
 	*/
 
-	if (--mdev->open_cnt == 0) {
-		clear_bit(WRITER_PRESENT, &mdev->flags);
-	}
+	mdev->open_cnt--;
 
 	return 0;
 }

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/drbd/drbd_nl.c	2006-12-21 15:49:27 UTC (rev 2640)
@@ -237,20 +237,6 @@
 	drbd_state_t mask, val;
 	drbd_disks_t nps;
 
-	if ( new_role == Secondary ) {
-		/* If I got here, I am Primary.
-		 * I cannot become Secondary as long as someone has an open
-		 * file descriptor on me. */
-
-		/* FIXME Race here.  we need to lock out openers while we are
-		 * deciding whether we can become Secondary or not, so open_cnt
-		 * cannot increase while we are still Primary just before we
-		 * become Secondary below. */
-
-		if (mdev->open_cnt)
-			return DeviceInUse;
-	}
-
 	if ( new_role == Primary ) {
 		request_ping(mdev); // Detect a dead peer ASAP
 	}

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/drbd/drbd_strings.c	2006-12-21 15:49:27 UTC (rev 2640)
@@ -74,7 +74,8 @@
 	[-SS_ResyncRunning] = "Can not start resync since it is already active",
 	[-SS_AlreadyStandAlone] = "Can not disconnect a StandAlone device",
 	[-SS_CW_FailedByPeer] = "State changed was refused by peer node",
-	[-SS_CanNotOutdateDL] = "Can not outdate a diskless device"
+	[-SS_CanNotOutdateDL] = "Can not outdate a diskless device",
+	[-SS_DeviceInUse] = "Device is help open by someone"
 };
 
 const char* conns_to_name(drbd_conns_t s) {

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/drbd/linux/drbd.h	2006-12-21 15:49:27 UTC (rev 2640)
@@ -105,7 +105,6 @@
 	PauseFlagAlreadySet,
 	PauseFlagAlreadyClear,
 	DiskLowerThanOutdated,
-	DeviceInUse,
 	UnknownNetLinkPacket,
 	HaveNoDiskConfig,
 	ProtocolCRequired,
@@ -203,7 +202,8 @@
 	SS_ResyncRunning=-8,
 	SS_AlreadyStandAlone=-9,
 	SS_CW_FailedByPeer=-10,
-	SS_CanNotOutdateDL=-11
+	SS_CanNotOutdateDL=-11,
+	SS_DeviceInUse=-12
 } set_st_err_t;
 
 /* from drbd_strings.c */

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-12-21 14:31:33 UTC (rev 2639)
+++ trunk/user/drbdsetup.c	2006-12-21 15:49:27 UTC (rev 2640)
@@ -377,7 +377,6 @@
 	EM(PauseFlagAlreadySet) = "PauseFlagAlreadySet",
 	EM(PauseFlagAlreadyClear) = "PauseFlagAlreadyClear",
 	EM(DiskLowerThanOutdated) = "DiskLowerThanOutdated",
-	EM(DeviceInUse) = "DeviceInUse",
 	EM(HaveNoDiskConfig) = "HaveNoDiskConfig",
 	EM(ProtocolCRequired) = "ProtocolCRequired"
 };



More information about the drbd-cvs mailing list