[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1296595418-2457-1-git-send-email-abogani@kernel.org>
Date: Tue, 1 Feb 2011 22:23:38 +0100
From: Alessio Igor Bogani <abogani@...nel.org>
To: Evgeniy Dushistov <dushistov@...l.ru>
Cc: linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
Tim Bird <tim.bird@...sony.com>,
Alessio Igor Bogani <abogani@...nel.org>
Subject: [PATCH] ufs: Check if page has buffers before calling page_buffers()
In ufs_change_blocknr() we have called page_buffers() without checking if the
page actually had pages attached to it and this could cause a BUG oops.
This work was supported by a hardware donation from the CE Linux Forum.
Signed-off-by: Alessio Igor Bogani <abogani@...nel.org>
---
fs/ufs/balloc.c | 62 +++++++++++++++++++++++++++---------------------------
1 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 46f7a80..8155ccd 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -276,46 +276,46 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg,
} else
page = locked_page;
- head = page_buffers(page);
- bh = head;
- pos = i & mask;
- for (j = 0; j < pos; ++j)
- bh = bh->b_this_page;
-
-
if (unlikely(index == last_index))
lblock = end & mask;
else
lblock = blks_per_page;
- do {
- if (j >= lblock)
- break;
- pos = (i - beg) + j;
+ if (page_has_buffers(page)) {
+ bh = head = page_buffers(page);
+ pos = i & mask;
+ for (j = 0; j < pos; ++j)
+ bh = bh->b_this_page;
- if (!buffer_mapped(bh))
- map_bh(bh, inode->i_sb, oldb + pos);
- if (!buffer_uptodate(bh)) {
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh)) {
- ufs_error(inode->i_sb, __func__,
- "read of block failed\n");
+ do {
+ if (j >= lblock)
break;
+ pos = (i - beg) + j;
+
+ if (!buffer_mapped(bh))
+ map_bh(bh, inode->i_sb, oldb + pos);
+ if (!buffer_uptodate(bh)) {
+ ll_rw_block(READ, 1, &bh);
+ wait_on_buffer(bh);
+ if (!buffer_uptodate(bh)) {
+ ufs_error(inode->i_sb, __func__,
+ "read of block failed\n");
+ break;
+ }
}
- }
- UFSD(" change from %llu to %llu, pos %u\n",
- (unsigned long long)(pos + oldb),
- (unsigned long long)(pos + newb), pos);
-
- bh->b_blocknr = newb + pos;
- unmap_underlying_metadata(bh->b_bdev,
- bh->b_blocknr);
- mark_buffer_dirty(bh);
- ++j;
- bh = bh->b_this_page;
- } while (bh != head);
+ UFSD(" change from %llu to %llu, pos %u\n",
+ (unsigned long long)(pos + oldb),
+ (unsigned long long)(pos + newb), pos);
+
+ bh->b_blocknr = newb + pos;
+ unmap_underlying_metadata(bh->b_bdev,
+ bh->b_blocknr);
+ mark_buffer_dirty(bh);
+ ++j;
+ bh = bh->b_this_page;
+ } while (bh != head);
+ }
if (likely(cur_index != index))
ufs_put_locked_page(page);
--
1.7.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists