[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