From 9719ae69f67d23821bef265c4f056697428e9aef Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Wed, 15 Feb 2012 17:22:06 +0100 Subject: [PATCH 77/84] lsbd: fix potential lose of data in rewrite/write In some rare cases the old version can be overwritten before new version is written. Signed-off-by: Krzysztof Mazur --- drivers/block/lsbd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/block/lsbd.c b/drivers/block/lsbd.c index 3117c9f..2248688 100644 --- a/drivers/block/lsbd.c +++ b/drivers/block/lsbd.c @@ -1626,7 +1626,6 @@ static int lsbd_queue_bh(struct lsbd *p, struct buffer_head *bh, r->bh = bh; r->sector = sector; r->move = move; - r->queue = prio; spin_lock_irqsave(&p->wqueue_lock, flags); list_for_each_entry(r2, &p->wqueue_hash[hash], hash_list) { @@ -1638,6 +1637,16 @@ static int lsbd_queue_bh(struct lsbd *p, struct buffer_head *bh, * just drop this rewrite request */ p->queue_move_skip++; + + /* + * to avoid losing both versions of this + * sector we need to use higher priority + * to pending write request + */ + list_del(&r2->list); + r2->queue = LSBD_QUEUE_MOVE; + list_add_tail(&r2->list, + &p->wqueue[r2->queue]); kfree(r); goto out_unlock; } else { @@ -1651,10 +1660,18 @@ static int lsbd_queue_bh(struct lsbd *p, struct buffer_head *bh, lsbd_put_buffer(p, r2->bh); r2->bh = NULL; kfree(r2); + + /* + * to avoid losing both versions of this + * sector we need to use higher priority + * to pending write request + */ + prio = LSBD_QUEUE_MOVE; break; } } } + r->queue = prio; list_add_tail(&r->list, &p->wqueue[prio]); list_add_tail(&r->hash_list, &p->wqueue_hash[hash]); /* TODO */ -- 1.8.4.652.g0d6e0ce