From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alessio Igor Bogani Subject: [PATCH] ufs: Check if page has buffers before calling page_buffers() Date: Tue, 1 Feb 2011 22:23:38 +0100 Message-ID: <1296595418-2457-1-git-send-email-abogani@kernel.org> Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Tim Bird , Alessio Igor Bogani To: Evgeniy Dushistov Return-path: Received: from mail-wy0-f174.google.com ([74.125.82.174]:60269 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751966Ab1BAVYC (ORCPT ); Tue, 1 Feb 2011 16:24:02 -0500 Sender: linux-fsdevel-owner@vger.kernel.org List-ID: 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 --- 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