Skip to content

Commit

Permalink
[PATCH] ufs: alloc metadata null page fix
Browse files Browse the repository at this point in the history
These series of patches result of UFS1 write support stress testing, like
running fsx-linux, untar and build linux kernel etc

We pass from ufs::get_block_t to levels below: pointer to the current page, to
make possible things like reallocation of blocks on the fly, and we also uses
this pointer for indication, what actually we allocate data block or meta data
block, but currently we make decision about what we allocate on the wrong
level, this may and cause oops if we allocate blocks in some special order.

Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Evgeniy Dushistov authored and Linus Torvalds committed Jan 30, 2007
1 parent ff79544 commit a685e26
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
5 changes: 4 additions & 1 deletion fs/ufs/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,16 +233,19 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
{
unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits);
struct address_space *mapping = inode->i_mapping;
pgoff_t index, cur_index = locked_page->index;
pgoff_t index, cur_index;
unsigned int i, j;
struct page *page;
struct buffer_head *head, *bh;

UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
inode->i_ino, count, oldb, newb);

BUG_ON(!locked_page);
BUG_ON(!PageLocked(locked_page));

cur_index = locked_page->index;

for (i = 0; i < count; i += blk_per_page) {
index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits);

Expand Down
14 changes: 9 additions & 5 deletions fs/ufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,16 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment,
goal = tmp + uspi->s_fpb;
tmp = ufs_new_fragments (inode, p, fragment - blockoff,
goal, required + blockoff,
err, locked_page);
err,
phys != NULL ? locked_page : NULL);
}
/*
* We will extend last allocated block
*/
else if (lastblock == block) {
tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff),
fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff),
err, locked_page);
err, phys != NULL ? locked_page : NULL);
} else /* (lastblock > block) */ {
/*
* We will allocate new block before last allocated block
Expand All @@ -261,7 +262,8 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment,
goal = tmp + uspi->s_fpb;
}
tmp = ufs_new_fragments(inode, p, fragment - blockoff,
goal, uspi->s_fpb, err, locked_page);
goal, uspi->s_fpb, err,
phys != NULL ? locked_page : NULL);
}
if (!tmp) {
if ((!blockoff && *p) ||
Expand Down Expand Up @@ -438,9 +440,11 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
* it much more readable:
*/
#define GET_INODE_DATABLOCK(x) \
ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page)
ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new,\
bh_result->b_page)
#define GET_INODE_PTR(x) \
ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, NULL)
ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL,\
bh_result->b_page)
#define GET_INDIRECT_DATABLOCK(x) \
ufs_inode_getblock(inode, bh, x, fragment, \
&err, &phys, &new, bh_result->b_page)
Expand Down

0 comments on commit a685e26

Please sign in to comment.