Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346117
b: refs/heads/master
c: 1b7ab15
h: refs/heads/master
i:
  346115: 12a602d
v: v3
  • Loading branch information
Philipp Reisner committed Nov 8, 2012
1 parent 9bcc96d commit 9916ef7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 30 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: 9b743da96c8640dbfc864cb5d79c51547c3fadb4
refs/heads/master: 1b7ab15b11716d075b3dca34cf41e8d7aba3cba2
70 changes: 45 additions & 25 deletions trunk/drivers/block/drbd/drbd_actlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct drbd_atodb_wait {
};


static int w_al_write_transaction(struct drbd_work *, int);
static int al_write_transaction(struct drbd_conf *mdev);

void *drbd_md_get_buffer(struct drbd_conf *mdev)
{
Expand Down Expand Up @@ -272,18 +272,13 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
/* Double check: it may have been committed by someone else,
* while we have been waiting for the lock. */
if (mdev->act_log->pending_changes) {
struct update_al_work al_work;
init_completion(&al_work.event);
al_work.w.cb = w_al_write_transaction;
al_work.w.mdev = mdev;
drbd_queue_work_front(&mdev->tconn->data.work, &al_work.w);
wait_for_completion(&al_work.event);

int err;
err = al_write_transaction(mdev);
mdev->al_writ_cnt++;

spin_lock_irq(&mdev->al_lock);
/* FIXME
if (al_work.err)
if (err)
we need an "lc_cancel" here;
*/
lc_committed(mdev->act_log);
Expand Down Expand Up @@ -348,43 +343,36 @@ static unsigned int rs_extent_to_bm_page(unsigned int rs_enr)
}

static int
w_al_write_transaction(struct drbd_work *w, int unused)
_al_write_transaction(struct drbd_conf *mdev)
{
struct update_al_work *aw = container_of(w, struct update_al_work, w);
struct drbd_conf *mdev = w->mdev;
struct al_transaction_on_disk *buffer;
struct lc_element *e;
sector_t sector;
int i, mx;
unsigned extent_nr;
unsigned crc = 0;
int err = 0;

if (!get_ldev(mdev)) {
dev_err(DEV, "disk is %s, cannot start al transaction\n",
drbd_disk_str(mdev->state.disk));
aw->err = -EIO;
complete(&((struct update_al_work *)w)->event);
return 0;
return -EIO;
}

/* The bitmap write may have failed, causing a state change. */
if (mdev->state.disk < D_INCONSISTENT) {
dev_err(DEV,
"disk is %s, cannot write al transaction\n",
drbd_disk_str(mdev->state.disk));
aw->err = -EIO;
complete(&((struct update_al_work *)w)->event);
put_ldev(mdev);
return 0;
return -EIO;
}

buffer = drbd_md_get_buffer(mdev); /* protects md_io_buffer, al_tr_cycle, ... */
if (!buffer) {
dev_err(DEV, "disk failed while waiting for md_io buffer\n");
aw->err = -EIO;
complete(&((struct update_al_work *)w)->event);
put_ldev(mdev);
return 1;
return -ENODEV;
}

memset(buffer, 0, sizeof(*buffer));
Expand Down Expand Up @@ -444,10 +432,10 @@ w_al_write_transaction(struct drbd_work *w, int unused)
buffer->crc32c = cpu_to_be32(crc);

if (drbd_bm_write_hinted(mdev))
aw->err = -EIO;
err = -EIO;
/* drbd_chk_io_error done already */
else if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
aw->err = -EIO;
err = -EIO;
drbd_chk_io_error(mdev, 1, true);
} else {
/* advance ringbuffer position and transaction counter */
Expand All @@ -456,10 +444,42 @@ w_al_write_transaction(struct drbd_work *w, int unused)
}

drbd_md_put_buffer(mdev);
complete(&((struct update_al_work *)w)->event);
put_ldev(mdev);

return 0;
return err;
}


static int w_al_write_transaction(struct drbd_work *w, int unused)
{
struct update_al_work *aw = container_of(w, struct update_al_work, w);
struct drbd_conf *mdev = w->mdev;
int err;

err = _al_write_transaction(mdev);
aw->err = err;
complete(&aw->event);

return err != -EIO ? err : 0;
}

/* Calls from worker context (see w_restart_disk_io()) need to write the
transaction directly. Others came through generic_make_request(),
those need to delegate it to the worker. */
static int al_write_transaction(struct drbd_conf *mdev)
{
struct update_al_work al_work;

if (current == mdev->tconn->worker.task)
return _al_write_transaction(mdev);

init_completion(&al_work.event);
al_work.w.cb = w_al_write_transaction;
al_work.w.mdev = mdev;
drbd_queue_work_front(&mdev->tconn->data.work, &al_work.w);
wait_for_completion(&al_work.event);

return al_work.err;
}

static int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext)
Expand Down
4 changes: 0 additions & 4 deletions trunk/drivers/block/drbd/drbd_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,10 +1333,6 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)

if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
drbd_al_begin_io(mdev, &req->i);
/* 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;
Expand Down

0 comments on commit 9916ef7

Please sign in to comment.