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

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
...@@ -858,6 +858,8 @@ struct drbd_tconn { /* is a resource from the config file */ ...@@ -858,6 +858,8 @@ struct drbd_tconn { /* is a resource from the config file */
void *int_dig_in; void *int_dig_in;
void *int_dig_vv; void *int_dig_vv;
enum write_ordering_e write_ordering;
struct drbd_thread receiver; struct drbd_thread receiver;
struct drbd_thread worker; struct drbd_thread worker;
struct drbd_thread asender; struct drbd_thread asender;
...@@ -962,7 +964,7 @@ struct drbd_conf { ...@@ -962,7 +964,7 @@ struct drbd_conf {
struct drbd_epoch *current_epoch; struct drbd_epoch *current_epoch;
spinlock_t epoch_lock; spinlock_t epoch_lock;
unsigned int epochs; 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 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 sync_ee; /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
struct list_head done_ee; /* need to send P_WRITE_ACK */ struct list_head done_ee; /* need to send P_WRITE_ACK */
...@@ -1539,7 +1541,7 @@ static inline void drbd_tcp_quickack(struct socket *sock) ...@@ -1539,7 +1541,7 @@ static inline void drbd_tcp_quickack(struct socket *sock)
(char*)&val, sizeof(val)); (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 */ /* drbd_proc.c */
extern struct proc_dir_entry *drbd_proc; extern struct proc_dir_entry *drbd_proc;
......
...@@ -2130,7 +2130,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) ...@@ -2130,7 +2130,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
init_waitqueue_head(&mdev->al_wait); init_waitqueue_head(&mdev->al_wait);
init_waitqueue_head(&mdev->seq_wait); init_waitqueue_head(&mdev->seq_wait);
mdev->write_ordering = WO_bdev_flush;
mdev->resync_wenr = LC_FREE; mdev->resync_wenr = LC_FREE;
mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE; mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
mdev->local_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) ...@@ -2625,6 +2624,8 @@ struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts)
if (!tl_init(tconn)) if (!tl_init(tconn))
goto fail; goto fail;
tconn->write_ordering = WO_bdev_flush;
tconn->cstate = C_STANDALONE; tconn->cstate = C_STANDALONE;
mutex_init(&tconn->cstate_mutex); mutex_init(&tconn->cstate_mutex);
spin_lock_init(&tconn->req_lock); spin_lock_init(&tconn->req_lock);
......
...@@ -1497,8 +1497,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) ...@@ -1497,8 +1497,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
new_disk_conf = NULL; new_disk_conf = NULL;
new_plan = NULL; new_plan = NULL;
mdev->write_ordering = WO_bdev_flush; drbd_bump_write_ordering(mdev->tconn, WO_bdev_flush);
drbd_bump_write_ordering(mdev, WO_bdev_flush);
if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY)) if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY))
set_bit(CRASHED_PRIMARY, &mdev->flags); set_bit(CRASHED_PRIMARY, &mdev->flags);
......
...@@ -272,7 +272,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) ...@@ -272,7 +272,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
atomic_read(&mdev->unacked_cnt), atomic_read(&mdev->unacked_cnt),
atomic_read(&mdev->ap_bio_cnt), atomic_read(&mdev->ap_bio_cnt),
mdev->epochs, mdev->epochs,
write_ordering_chars[mdev->write_ordering] write_ordering_chars[mdev->tconn->write_ordering]
); );
seq_printf(seq, " oos:%llu\n", seq_printf(seq, " oos:%llu\n",
Bit2KB((unsigned long long) Bit2KB((unsigned long long)
......
...@@ -1089,21 +1089,29 @@ static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -1089,21 +1089,29 @@ static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
return err; return err;
} }
static void drbd_flush(struct drbd_conf *mdev) static void drbd_flush(struct drbd_tconn *tconn)
{ {
int rv; int rv;
struct drbd_conf *mdev;
int vnr;
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 (mdev->write_ordering >= WO_bdev_flush && get_ldev(mdev)) { if (rv) {
rv = blkdev_issue_flush(mdev->ldev->backing_bdev, GFP_KERNEL, dev_info(DEV, "local disk flush failed with status %d\n", rv);
NULL); /* would rather check on EOPNOTSUPP, but that is not reliable.
if (rv) { * don't try again for ANY return value != 0
dev_info(DEV, "local disk flush failed with status %d\n", rv); * if (rv == -EOPNOTSUPP) */
/* would rather check on EOPNOTSUPP, but that is not reliable. drbd_bump_write_ordering(tconn, WO_drain_io);
* don't try again for ANY return value != 0 break;
* if (rv == -EOPNOTSUPP) */ }
drbd_bump_write_ordering(mdev, WO_drain_io); }
} }
put_ldev(mdev);
} }
} }
...@@ -1182,32 +1190,39 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *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 * drbd_bump_write_ordering() - Fall back to an other write ordering method
* @mdev: DRBD device. * @tconn: DRBD connection.
* @wo: Write ordering method to try. * @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 disk_conf *dc;
struct drbd_conf *mdev;
enum write_ordering_e pwo; enum write_ordering_e pwo;
int vnr;
static char *write_ordering_str[] = { static char *write_ordering_str[] = {
[WO_none] = "none", [WO_none] = "none",
[WO_drain_io] = "drain", [WO_drain_io] = "drain",
[WO_bdev_flush] = "flush", [WO_bdev_flush] = "flush",
}; };
pwo = mdev->write_ordering; pwo = tconn->write_ordering;
wo = min(pwo, wo); wo = min(pwo, wo);
rcu_read_lock(); rcu_read_lock();
dc = rcu_dereference(mdev->ldev->disk_conf); 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) if (wo == WO_bdev_flush && !dc->disk_flushes)
wo = WO_drain_io; wo = WO_drain_io;
if (wo == WO_drain_io && !dc->disk_drain) if (wo == WO_drain_io && !dc->disk_drain)
wo = WO_none; wo = WO_none;
put_ldev(mdev);
}
rcu_read_unlock(); rcu_read_unlock();
mdev->write_ordering = wo; tconn->write_ordering = wo;
if (pwo != mdev->write_ordering || wo == WO_bdev_flush) if (pwo != tconn->write_ordering || wo == WO_bdev_flush)
dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); 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) ...@@ -1341,7 +1356,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
* R_PRIMARY crashes now. * R_PRIMARY crashes now.
* Therefore we must send the barrier_ack after the barrier request was * Therefore we must send the barrier_ack after the barrier request was
* completed. */ * completed. */
switch (mdev->write_ordering) { switch (tconn->write_ordering) {
case WO_none: case WO_none:
if (rv == FE_RECYCLED) if (rv == FE_RECYCLED)
return 0; return 0;
...@@ -1358,7 +1373,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -1358,7 +1373,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
case WO_bdev_flush: case WO_bdev_flush:
case WO_drain_io: case WO_drain_io:
drbd_wait_ee_list_empty(mdev, &mdev->active_ee); drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
drbd_flush(mdev); drbd_flush(tconn);
if (atomic_read(&mdev->current_epoch->epoch_size)) { if (atomic_read(&mdev->current_epoch->epoch_size)) {
epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
...@@ -1374,7 +1389,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -1374,7 +1389,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
return 0; return 0;
default: 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; return -EIO;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment