Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213100
b: refs/heads/master
c: 265be2d
h: refs/heads/master
v: v3
  • Loading branch information
Philipp Reisner committed Oct 14, 2010
1 parent b896811 commit 503d1a6
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 905cd7d8ac9b18e1f122b90dbebe1246b1c364fd
refs/heads/master: 265be2d09853d425ad14a61cda0ca63345613d0c
1 change: 1 addition & 0 deletions trunk/drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,7 @@ extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int);
extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int);
extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int);
extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int);
extern int w_restart_disk_io(struct drbd_conf *, struct drbd_work *, int);

extern void resync_timer_fn(unsigned long data);

Expand Down
26 changes: 25 additions & 1 deletion trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
if (fp == FP_STONITH &&
(ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
!(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
ns.susp = 1;
ns.susp = 1; /* Suspend IO while fence-peer handler runs (peer lost) */

if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
(ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
!(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
ns.susp = 1; /* Suspend IO while no data available (no accessible data available) */

if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
if (ns.conn == C_SYNC_SOURCE)
Expand Down Expand Up @@ -1236,6 +1241,25 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
/* Here we have the actions that are performed after a
state change. This function might sleep */

if (os.susp && ns.susp && mdev->sync_conf.on_no_data == OND_SUSPEND_IO) {
if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
if (ns.conn == C_CONNECTED) {
spin_lock_irq(&mdev->req_lock);
_tl_restart(mdev, resend);
_drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
spin_unlock_irq(&mdev->req_lock);
} else /* ns.conn > C_CONNECTED */
dev_err(DEV, "Unexpected Resynd going on!\n");
}

if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING) {
spin_lock_irq(&mdev->req_lock);
_tl_restart(mdev, restart_frozen_disk_io);
_drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
spin_unlock_irq(&mdev->req_lock);
}
}

if (fp == FP_STONITH && ns.susp) {
/* case1: The outdate peer handler is successful:
* case2: The connection was established again: */
Expand Down
13 changes: 13 additions & 0 deletions trunk/drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/blkpg.h>
#include <linux/cpumask.h>
#include "drbd_int.h"
#include "drbd_req.h"
#include "drbd_wrappers.h"
#include <asm/unaligned.h>
#include <linux/drbd_tag_magic.h>
Expand Down Expand Up @@ -494,6 +495,8 @@ char *ppsize(char *buf, unsigned long long size)
void drbd_suspend_io(struct drbd_conf *mdev)
{
set_bit(SUSPEND_IO, &mdev->flags);
if (mdev->state.susp)
return;
wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
}

Expand Down Expand Up @@ -1557,6 +1560,7 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
sc.rate = DRBD_RATE_DEF;
sc.after = DRBD_AFTER_DEF;
sc.al_extents = DRBD_AL_EXTENTS_DEF;
sc.on_no_data = DRBD_ON_NO_DATA_DEF;
} else
memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf));

Expand Down Expand Up @@ -1765,7 +1769,16 @@ static int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
drbd_suspend_io(mdev);
reply->ret_code = drbd_request_state(mdev, NS(susp, 0));
if (reply->ret_code == SS_SUCCESS) {
if (mdev->state.conn < C_CONNECTED)
tl_clear(mdev);
if (mdev->state.disk == D_DISKLESS || mdev->state.disk == D_FAILED)
tl_restart(mdev, fail_frozen_disk_io);
}
drbd_resume_io(mdev);

return 0;
}

Expand Down
24 changes: 24 additions & 0 deletions trunk/drivers/block/drbd/drbd_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
return;
if (s & RQ_LOCAL_PENDING)
return;
if (mdev->state.susp)
return;

if (req->master_bio) {
/* this is data_received (remote read)
Expand Down Expand Up @@ -634,6 +636,28 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
/* else: done by handed_over_to_network */
break;

case fail_frozen_disk_io:
if (!(req->rq_state & RQ_LOCAL_COMPLETED))
break;

_req_may_be_done(req, m);
break;

case restart_frozen_disk_io:
if (!(req->rq_state & RQ_LOCAL_COMPLETED))
break;

req->rq_state &= ~RQ_LOCAL_COMPLETED;

rv = MR_READ;
if (bio_data_dir(req->master_bio) == WRITE)
rv = MR_WRITE;

get_ldev(mdev);
req->w.cb = w_restart_disk_io;
drbd_queue_work(&mdev->data.work, &req->w);
break;

case resend:
/* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK
before the connection loss; only P_BARRIER_ACK was missing.
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/block/drbd/drbd_req.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ enum drbd_req_event {
write_completed_with_error,
completed_ok,
resend,
fail_frozen_disk_io,
restart_frozen_disk_io,
nothing, /* for tracing only */
};

Expand Down
18 changes: 18 additions & 0 deletions trunk/drivers/block/drbd/drbd_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,24 @@ int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
return ok;
}

int w_restart_disk_io(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
{
struct drbd_request *req = container_of(w, struct drbd_request, w);

if (bio_data_dir(req->master_bio) == WRITE)
drbd_al_begin_io(mdev, req->sector);
/* Calling drbd_al_begin_io() out of the worker might deadlocks
theoretically. Practically it can not deadlock, since this is
only used when unfreezing IOs. All the extents of the requests
that made it into the TL are already active */

drbd_req_make_private_bio(req, req->master_bio);
req->private_bio->bi_bdev = mdev->ldev->backing_bdev;
generic_make_request(req->private_bio);

return 1;
}

static int _drbd_may_sync_now(struct drbd_conf *mdev)
{
struct drbd_conf *odev = mdev;
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/drbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ enum drbd_after_sb_p {
ASB_VIOLENTLY
};

enum drbd_on_no_data {
OND_IO_ERROR,
OND_SUSPEND_IO
};

/* KEEP the order, do not delete or insert. Only append. */
enum drbd_ret_codes {
ERR_CODE_BASE = 100,
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/drbd_limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
#define DRBD_AFTER_SB_1P_DEF ASB_DISCONNECT
#define DRBD_AFTER_SB_2P_DEF ASB_DISCONNECT
#define DRBD_RR_CONFLICT_DEF ASB_DISCONNECT
#define DRBD_ON_NO_DATA_DEF OND_IO_ERROR

#define DRBD_MAX_BIO_BVECS_MIN 0
#define DRBD_MAX_BIO_BVECS_MAX 128
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/drbd_nl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ NL_PACKET(syncer_conf, 8,
NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32)
NL_STRING( 64, T_MAY_IGNORE, csums_alg, SHARED_SECRET_MAX)
NL_BIT( 65, T_MAY_IGNORE, use_rle)
NL_INTEGER( 75, T_MAY_IGNORE, on_no_data)
)

NL_PACKET(invalidate, 9, )
Expand Down

0 comments on commit 503d1a6

Please sign in to comment.