drbd: Fixed removal of volumes/devices from connected resources
authorPhilipp Reisner <philipp.reisner@linbit.com>
Wed, 6 Jul 2011 21:04:44 +0000 (23:04 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 8 Nov 2012 15:57:51 +0000 (16:57 +0100)
When removing a volume/device we need to switch the connection
status of the peer back into WFReportParams.

  Before this fix it was left in Connected state. That means that
  the peer device continued to inform us about state changes, etc...
  But we deleted that minor -> protocol error.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_state.c

index b39f5dc0f47bfcdec0cc1d6ade87c52d468481b8..4e1beb7ee83f80ad49fe67e19298818f243d026d 100644 (file)
@@ -3061,6 +3061,8 @@ static enum drbd_ret_code adm_delete_minor(struct drbd_conf *mdev)
             * we may want to delete a minor from a live replication group.
             */
            mdev->state.role == R_SECONDARY) {
+               _drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS),
+                                   CS_VERBOSE + CS_WAIT_COMPLETE);
                idr_remove(&mdev->tconn->volumes, mdev->vnr);
                idr_remove(&minors, mdev_to_minor(mdev));
                del_gendisk(mdev->vdisk);
index 3a7e54b8f4187d54cb92ebd05e09aa9fc1871be9..d4e677c9c764e75ef39d2a49fefb97c6c2e308ae 100644 (file)
@@ -3628,6 +3628,7 @@ static union drbd_state convert_state(union drbd_state ps)
        union drbd_state ms;
 
        static enum drbd_conns c_tab[] = {
+               [C_WF_REPORT_PARAMS] = C_WF_REPORT_PARAMS,
                [C_CONNECTED] = C_CONNECTED,
 
                [C_STARTING_SYNC_S] = C_STARTING_SYNC_T,
index c4d0d96d7906228b0bea0ed646445e64b3da5fd2..633b52c724448d58ae2124c0e6f1f5632ab8e44e 100644 (file)
@@ -201,7 +201,8 @@ static int cl_wide_st_chg(struct drbd_conf *mdev,
                  (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S) ||
                  (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))) ||
                (os.conn >= C_CONNECTED && ns.conn == C_DISCONNECTING) ||
-               (os.conn == C_CONNECTED && ns.conn == C_VERIFY_S);
+               (os.conn == C_CONNECTED && ns.conn == C_VERIFY_S) ||
+               (os.conn == C_CONNECTED && ns.conn == C_WF_REPORT_PARAMS);
 }
 
 static union drbd_state
@@ -1202,7 +1203,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
        }
 
        /* Do not change the order of the if above and the two below... */
-       if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) {      /* attach on the peer */
+       if (os.pdsk == D_DISKLESS &&
+           ns.pdsk > D_DISKLESS && ns.pdsk != D_UNKNOWN) {      /* attach on the peer */
                drbd_send_uuids(mdev);
                drbd_send_state(mdev);
        }