Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b0007c0 authored by Philipp Reisner's avatar Philipp Reisner
Browse files

drbd: Move write_ordering from mdev to tconn



This is necessary in order to prepare the move of the (receiver side)
epoch list from the device (mdev) to the connection (tconn) objects.

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 6936fcb4
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -858,6 +858,8 @@ struct drbd_tconn { /* is a resource from the config file */
	void *int_dig_in;
	void *int_dig_vv;

	enum write_ordering_e write_ordering;

	struct drbd_thread receiver;
	struct drbd_thread worker;
	struct drbd_thread asender;
@@ -962,7 +964,7 @@ struct drbd_conf {
	struct drbd_epoch *current_epoch;
	spinlock_t epoch_lock;
	unsigned int epochs;
	enum write_ordering_e write_ordering;

	struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */
	struct list_head sync_ee;   /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
	struct list_head done_ee;   /* need to send P_WRITE_ACK */
@@ -1539,7 +1541,7 @@ static inline void drbd_tcp_quickack(struct socket *sock)
			(char*)&val, sizeof(val));
}

void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo);
void drbd_bump_write_ordering(struct drbd_tconn *tconn, enum write_ordering_e wo);

/* drbd_proc.c */
extern struct proc_dir_entry *drbd_proc;
+2 −1
Original line number Diff line number Diff line
@@ -2130,7 +2130,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
	init_waitqueue_head(&mdev->al_wait);
	init_waitqueue_head(&mdev->seq_wait);

	mdev->write_ordering = WO_bdev_flush;
	mdev->resync_wenr = LC_FREE;
	mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
	mdev->local_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
@@ -2625,6 +2624,8 @@ struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts)
	if (!tl_init(tconn))
		goto fail;

	tconn->write_ordering = WO_bdev_flush;

	tconn->cstate = C_STANDALONE;
	mutex_init(&tconn->cstate_mutex);
	spin_lock_init(&tconn->req_lock);
+1 −2
Original line number Diff line number Diff line
@@ -1497,8 +1497,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
	new_disk_conf = NULL;
	new_plan = NULL;

	mdev->write_ordering = WO_bdev_flush;
	drbd_bump_write_ordering(mdev, WO_bdev_flush);
	drbd_bump_write_ordering(mdev->tconn, WO_bdev_flush);

	if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY))
		set_bit(CRASHED_PRIMARY, &mdev->flags);
+1 −1
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
			   atomic_read(&mdev->unacked_cnt),
			   atomic_read(&mdev->ap_bio_cnt),
			   mdev->epochs,
			   write_ordering_chars[mdev->write_ordering]
			   write_ordering_chars[mdev->tconn->write_ordering]
			);
			seq_printf(seq, " oos:%llu\n",
				   Bit2KB((unsigned long long)
+40 −25
Original line number Diff line number Diff line
@@ -1089,21 +1089,29 @@ static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
	return err;
}

static void drbd_flush(struct drbd_conf *mdev)
static void drbd_flush(struct drbd_tconn *tconn)
{
	int rv;
	struct drbd_conf *mdev;
	int vnr;

	if (mdev->write_ordering >= WO_bdev_flush && get_ldev(mdev)) {
	if (tconn->write_ordering >= WO_bdev_flush) {
		idr_for_each_entry(&tconn->volumes, mdev, vnr) {
			if (get_ldev(mdev)) {
				rv = blkdev_issue_flush(mdev->ldev->backing_bdev, GFP_KERNEL,
							NULL);
				put_ldev(mdev);

				if (rv) {
					dev_info(DEV, "local disk flush failed with status %d\n", rv);
					/* would rather check on EOPNOTSUPP, but that is not reliable.
					 * don't try again for ANY return value != 0
					 * if (rv == -EOPNOTSUPP) */
			drbd_bump_write_ordering(mdev, WO_drain_io);
					drbd_bump_write_ordering(tconn, WO_drain_io);
					break;
				}
			}
		}
		put_ldev(mdev);
	}
}

@@ -1182,32 +1190,39 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,

/**
 * drbd_bump_write_ordering() - Fall back to an other write ordering method
 * @mdev:	DRBD device.
 * @tconn:	DRBD connection.
 * @wo:		Write ordering method to try.
 */
void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) __must_hold(local)
void drbd_bump_write_ordering(struct drbd_tconn *tconn, enum write_ordering_e wo)
{
	struct disk_conf *dc;
	struct drbd_conf *mdev;
	enum write_ordering_e pwo;
	int vnr;
	static char *write_ordering_str[] = {
		[WO_none] = "none",
		[WO_drain_io] = "drain",
		[WO_bdev_flush] = "flush",
	};

	pwo = mdev->write_ordering;
	pwo = tconn->write_ordering;
	wo = min(pwo, wo);
	rcu_read_lock();
	idr_for_each_entry(&tconn->volumes, mdev, vnr) {
		if (!get_ldev(mdev))
			continue;
		dc = rcu_dereference(mdev->ldev->disk_conf);

		if (wo == WO_bdev_flush && !dc->disk_flushes)
			wo = WO_drain_io;
		if (wo == WO_drain_io && !dc->disk_drain)
			wo = WO_none;
		put_ldev(mdev);
	}
	rcu_read_unlock();
	mdev->write_ordering = wo;
	if (pwo != mdev->write_ordering || wo == WO_bdev_flush)
		dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]);
	tconn->write_ordering = wo;
	if (pwo != tconn->write_ordering || wo == WO_bdev_flush)
		conn_info(tconn, "Method to ensure write ordering: %s\n", write_ordering_str[tconn->write_ordering]);
}

/**
@@ -1341,7 +1356,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
	 * R_PRIMARY crashes now.
	 * Therefore we must send the barrier_ack after the barrier request was
	 * completed. */
	switch (mdev->write_ordering) {
	switch (tconn->write_ordering) {
	case WO_none:
		if (rv == FE_RECYCLED)
			return 0;
@@ -1358,7 +1373,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
	case WO_bdev_flush:
	case WO_drain_io:
		drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
		drbd_flush(mdev);
		drbd_flush(tconn);

		if (atomic_read(&mdev->current_epoch->epoch_size)) {
			epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
@@ -1374,7 +1389,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)

		return 0;
	default:
		dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering);
		dev_err(DEV, "Strangeness in tconn->write_ordering %d\n", tconn->write_ordering);
		return -EIO;
	}