aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2013-10-23 04:59:16 -0400
committerJens Axboe <axboe@kernel.dk>2013-11-08 11:10:28 -0500
commitb874d231e115af9b2c4a7ed1a4c5ae2db8a21aaf (patch)
treed1af0ee989ce07385e59a8f4c9848ec3505a8517 /drivers/block
parent69babf05cbe909a9a520b39772655f88b407f257 (diff)
drbd: Fix an connection drop issue after enabling allow-two-primaries
Since drbd-8.4.0 it is possible to change the allow-two-primaries network option while the connection is established. The sequence code used to partially order packets from the data socket with packets from the meta-data socket, still assued that the allow-two-primaries option is constant while the connection is established. I.e. On a node that has the RESOLVE_CONFLICTS bits set, after enabling allow-two-primaries, when receiving the next data packet it timed out while waiting for the necessary packets on the data socket to arrive (wait_for_and_update_peer_seq() function). Fixed that by always tracking the sequence number, but only waiting for it if allow-two-primaries is set. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_receiver.c39
1 files changed, 16 insertions, 23 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cc29cd3bf78b..12c59eb3b127 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1890,29 +1890,11 @@ static u32 seq_max(u32 a, u32 b)
1890 return seq_greater(a, b) ? a : b; 1890 return seq_greater(a, b) ? a : b;
1891} 1891}
1892 1892
1893static bool need_peer_seq(struct drbd_conf *mdev)
1894{
1895 struct drbd_tconn *tconn = mdev->tconn;
1896 int tp;
1897
1898 /*
1899 * We only need to keep track of the last packet_seq number of our peer
1900 * if we are in dual-primary mode and we have the resolve-conflicts flag set; see
1901 * handle_write_conflicts().
1902 */
1903
1904 rcu_read_lock();
1905 tp = rcu_dereference(mdev->tconn->net_conf)->two_primaries;
1906 rcu_read_unlock();
1907
1908 return tp && test_bit(RESOLVE_CONFLICTS, &tconn->flags);
1909}
1910
1911static void update_peer_seq(struct drbd_conf *mdev, unsigned int peer_seq) 1893static void update_peer_seq(struct drbd_conf *mdev, unsigned int peer_seq)
1912{ 1894{
1913 unsigned int newest_peer_seq; 1895 unsigned int newest_peer_seq;
1914 1896
1915 if (need_peer_seq(mdev)) { 1897 if (test_bit(RESOLVE_CONFLICTS, &mdev->tconn->flags)) {
1916 spin_lock(&mdev->peer_seq_lock); 1898 spin_lock(&mdev->peer_seq_lock);
1917 newest_peer_seq = seq_max(mdev->peer_seq, peer_seq); 1899 newest_peer_seq = seq_max(mdev->peer_seq, peer_seq);
1918 mdev->peer_seq = newest_peer_seq; 1900 mdev->peer_seq = newest_peer_seq;
@@ -1972,22 +1954,31 @@ static int wait_for_and_update_peer_seq(struct drbd_conf *mdev, const u32 peer_s
1972{ 1954{
1973 DEFINE_WAIT(wait); 1955 DEFINE_WAIT(wait);
1974 long timeout; 1956 long timeout;
1975 int ret; 1957 int ret = 0, tp;
1976 1958
1977 if (!need_peer_seq(mdev)) 1959 if (!test_bit(RESOLVE_CONFLICTS, &mdev->tconn->flags))
1978 return 0; 1960 return 0;
1979 1961
1980 spin_lock(&mdev->peer_seq_lock); 1962 spin_lock(&mdev->peer_seq_lock);
1981 for (;;) { 1963 for (;;) {
1982 if (!seq_greater(peer_seq - 1, mdev->peer_seq)) { 1964 if (!seq_greater(peer_seq - 1, mdev->peer_seq)) {
1983 mdev->peer_seq = seq_max(mdev->peer_seq, peer_seq); 1965 mdev->peer_seq = seq_max(mdev->peer_seq, peer_seq);
1984 ret = 0;
1985 break; 1966 break;
1986 } 1967 }
1968
1987 if (signal_pending(current)) { 1969 if (signal_pending(current)) {
1988 ret = -ERESTARTSYS; 1970 ret = -ERESTARTSYS;
1989 break; 1971 break;
1990 } 1972 }
1973
1974 rcu_read_lock();
1975 tp = rcu_dereference(mdev->tconn->net_conf)->two_primaries;
1976 rcu_read_unlock();
1977
1978 if (!tp)
1979 break;
1980
1981 /* Only need to wait if two_primaries is enabled */
1991 prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE); 1982 prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE);
1992 spin_unlock(&mdev->peer_seq_lock); 1983 spin_unlock(&mdev->peer_seq_lock);
1993 rcu_read_lock(); 1984 rcu_read_lock();
@@ -2228,8 +2219,10 @@ static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi)
2228 } 2219 }
2229 goto out_interrupted; 2220 goto out_interrupted;
2230 } 2221 }
2231 } else 2222 } else {
2223 update_peer_seq(mdev, peer_seq);
2232 spin_lock_irq(&mdev->tconn->req_lock); 2224 spin_lock_irq(&mdev->tconn->req_lock);
2225 }
2233 list_add(&peer_req->w.list, &mdev->active_ee); 2226 list_add(&peer_req->w.list, &mdev->active_ee);
2234 spin_unlock_irq(&mdev->tconn->req_lock); 2227 spin_unlock_irq(&mdev->tconn->req_lock);
2235 2228