diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2012-07-11 14:27:13 +0200 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2012-07-20 10:49:25 +0200 |
commit | 537632e0a54a5355cdd0330911d18c3b773f9cf7 (patch) | |
tree | 7b4440d84c4dffa50c81a0c8bbb86f8da93748ca /fs/exofs | |
parent | ore: Remove support of partial IO request (NFS crash) (diff) | |
download | linux-537632e0a54a5355cdd0330911d18c3b773f9cf7.tar.xz linux-537632e0a54a5355cdd0330911d18c3b773f9cf7.zip |
ore: Unlock r4w pages in exact reverse order of locking
The read-4-write pages are locked in address ascending order.
But where unlocked in a way easiest for coding. Fix that,
locks should be released in opposite order of locking, .i.e
descending address order.
I have not hit this dead-lock. It was found by inspecting the
dbug print-outs. I suspect there is an higher lock at caller that
protects us, but fix it regardless.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs')
-rw-r--r-- | fs/exofs/ore_raid.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c index fff2070c6751..5f376d14fdcc 100644 --- a/fs/exofs/ore_raid.c +++ b/fs/exofs/ore_raid.c @@ -144,26 +144,26 @@ static void _sp2d_reset(struct __stripe_pages_2d *sp2d, { unsigned data_devs = sp2d->data_devs; unsigned group_width = data_devs + sp2d->parity; - unsigned p; + int p, c; if (!sp2d->needed) return; - for (p = 0; p < sp2d->pages_in_unit; p++) { - struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; - - if (_1ps->write_count < group_width) { - unsigned c; + for (c = data_devs - 1; c >= 0; --c) + for (p = sp2d->pages_in_unit - 1; p >= 0; --p) { + struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; - for (c = 0; c < data_devs; c++) - if (_1ps->page_is_read[c]) { - struct page *page = _1ps->pages[c]; + if (_1ps->page_is_read[c]) { + struct page *page = _1ps->pages[c]; - r4w->put_page(priv, page); - _1ps->page_is_read[c] = false; - } + r4w->put_page(priv, page); + _1ps->page_is_read[c] = false; + } } + for (p = 0; p < sp2d->pages_in_unit; p++) { + struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; + memset(_1ps->pages, 0, group_width * sizeof(*_1ps->pages)); _1ps->write_count = 0; _1ps->tx = NULL; |