drbd: ignore volume number for drbd barrier packet exchange
Transfer log epochs, and therefore P_BARRIER packets, are per resource, not per volume. We must not associate them with "some random volume". Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
parent
648e46b531
commit
9ed57dcbda
3 changed files with 31 additions and 36 deletions
|
@ -584,7 +584,7 @@ struct drbd_tl_epoch {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drbd_epoch {
|
struct drbd_epoch {
|
||||||
struct drbd_conf *mdev;
|
struct drbd_tconn *tconn;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
unsigned int barrier_nr;
|
unsigned int barrier_nr;
|
||||||
atomic_t epoch_size; /* increased on every request added. */
|
atomic_t epoch_size; /* increased on every request added. */
|
||||||
|
@ -1060,7 +1060,7 @@ extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_f
|
||||||
extern int drbd_send_state(struct drbd_conf *mdev, union drbd_state s);
|
extern int drbd_send_state(struct drbd_conf *mdev, union drbd_state s);
|
||||||
extern int drbd_send_current_state(struct drbd_conf *mdev);
|
extern int drbd_send_current_state(struct drbd_conf *mdev);
|
||||||
extern int drbd_send_sync_param(struct drbd_conf *mdev);
|
extern int drbd_send_sync_param(struct drbd_conf *mdev);
|
||||||
extern void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
|
extern void drbd_send_b_ack(struct drbd_tconn *tconn, u32 barrier_nr,
|
||||||
u32 set_size);
|
u32 set_size);
|
||||||
extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet,
|
extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet,
|
||||||
struct drbd_peer_request *);
|
struct drbd_peer_request *);
|
||||||
|
|
|
@ -1463,21 +1463,21 @@ int drbd_send_bitmap(struct drbd_conf *mdev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
|
void drbd_send_b_ack(struct drbd_tconn *tconn, u32 barrier_nr, u32 set_size)
|
||||||
{
|
{
|
||||||
struct drbd_socket *sock;
|
struct drbd_socket *sock;
|
||||||
struct p_barrier_ack *p;
|
struct p_barrier_ack *p;
|
||||||
|
|
||||||
if (mdev->state.conn < C_CONNECTED)
|
if (tconn->cstate < C_WF_REPORT_PARAMS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sock = &mdev->tconn->meta;
|
sock = &tconn->meta;
|
||||||
p = drbd_prepare_command(mdev, sock);
|
p = conn_prepare_command(tconn, sock);
|
||||||
if (!p)
|
if (!p)
|
||||||
return;
|
return;
|
||||||
p->barrier = barrier_nr;
|
p->barrier = barrier_nr;
|
||||||
p->set_size = cpu_to_be32(set_size);
|
p->set_size = cpu_to_be32(set_size);
|
||||||
drbd_send_command(mdev, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0);
|
conn_send_command(tconn, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1169,11 +1169,15 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_tconn *tconn,
|
||||||
(test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) || ev & EV_CLEANUP)) {
|
(test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) || ev & EV_CLEANUP)) {
|
||||||
if (!(ev & EV_CLEANUP)) {
|
if (!(ev & EV_CLEANUP)) {
|
||||||
spin_unlock(&tconn->epoch_lock);
|
spin_unlock(&tconn->epoch_lock);
|
||||||
drbd_send_b_ack(epoch->mdev, epoch->barrier_nr, epoch_size);
|
drbd_send_b_ack(epoch->tconn, epoch->barrier_nr, epoch_size);
|
||||||
spin_lock(&tconn->epoch_lock);
|
spin_lock(&tconn->epoch_lock);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/* FIXME: dec unacked on connection, once we have
|
||||||
|
* something to count pending connection packets in. */
|
||||||
if (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags))
|
if (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags))
|
||||||
dec_unacked(epoch->mdev);
|
dec_unacked(epoch->tconn);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tconn->current_epoch != epoch) {
|
if (tconn->current_epoch != epoch) {
|
||||||
next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list);
|
next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list);
|
||||||
|
@ -1369,19 +1373,15 @@ void conn_wait_active_ee_empty(struct drbd_tconn *tconn)
|
||||||
|
|
||||||
static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
|
static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
|
||||||
{
|
{
|
||||||
struct drbd_conf *mdev;
|
|
||||||
int rv;
|
int rv;
|
||||||
struct p_barrier *p = pi->data;
|
struct p_barrier *p = pi->data;
|
||||||
struct drbd_epoch *epoch;
|
struct drbd_epoch *epoch;
|
||||||
|
|
||||||
mdev = vnr_to_mdev(tconn, pi->vnr);
|
/* FIXME these are unacked on connection,
|
||||||
if (!mdev)
|
* not a specific (peer)device.
|
||||||
return -EIO;
|
*/
|
||||||
|
|
||||||
inc_unacked(mdev);
|
|
||||||
|
|
||||||
tconn->current_epoch->barrier_nr = p->barrier;
|
tconn->current_epoch->barrier_nr = p->barrier;
|
||||||
tconn->current_epoch->mdev = mdev;
|
tconn->current_epoch->tconn = tconn;
|
||||||
rv = drbd_may_finish_epoch(tconn, tconn->current_epoch, EV_GOT_BARRIER_NR);
|
rv = drbd_may_finish_epoch(tconn, tconn->current_epoch, EV_GOT_BARRIER_NR);
|
||||||
|
|
||||||
/* P_BARRIER_ACK may imply that the corresponding extent is dropped from
|
/* P_BARRIER_ACK may imply that the corresponding extent is dropped from
|
||||||
|
@ -1400,7 +1400,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
|
||||||
if (epoch)
|
if (epoch)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
dev_warn(DEV, "Allocation of an epoch failed, slowing down\n");
|
conn_warn(tconn, "Allocation of an epoch failed, slowing down\n");
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case WO_bdev_flush:
|
case WO_bdev_flush:
|
||||||
|
@ -1414,15 +1414,9 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
epoch = tconn->current_epoch;
|
|
||||||
wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0);
|
|
||||||
|
|
||||||
D_ASSERT(atomic_read(&epoch->active) == 0);
|
|
||||||
D_ASSERT(epoch->flags == 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
dev_err(DEV, "Strangeness in tconn->write_ordering %d\n", tconn->write_ordering);
|
conn_err(tconn, "Strangeness in tconn->write_ordering %d\n", tconn->write_ordering);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5049,21 +5043,22 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi)
|
||||||
|
|
||||||
static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi)
|
static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi)
|
||||||
{
|
{
|
||||||
struct drbd_conf *mdev;
|
|
||||||
struct p_barrier_ack *p = pi->data;
|
struct p_barrier_ack *p = pi->data;
|
||||||
|
struct drbd_conf *mdev;
|
||||||
|
int vnr;
|
||||||
|
|
||||||
mdev = vnr_to_mdev(tconn, pi->vnr);
|
tl_release(tconn, p->barrier, be32_to_cpu(p->set_size));
|
||||||
if (!mdev)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size));
|
rcu_read_lock();
|
||||||
|
idr_for_each_entry(&tconn->volumes, mdev, vnr) {
|
||||||
if (mdev->state.conn == C_AHEAD &&
|
if (mdev->state.conn == C_AHEAD &&
|
||||||
atomic_read(&mdev->ap_in_flight) == 0 &&
|
atomic_read(&mdev->ap_in_flight) == 0 &&
|
||||||
!test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->flags)) {
|
!test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->flags)) {
|
||||||
mdev->start_resync_timer.expires = jiffies + HZ;
|
mdev->start_resync_timer.expires = jiffies + HZ;
|
||||||
add_timer(&mdev->start_resync_timer);
|
add_timer(&mdev->start_resync_timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue