lkml.org 
[lkml]   [2011]   [Feb]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] ufs: Check if page has buffers before calling page_buffers()
Date
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@kernel.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


\
 
 \ /
  Last update: 2011-02-01 22:27    [W:0.027 / U:3.872 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site