Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a685e26fff387db350966f88eaad515bf41c4705
Commit:     a685e26fff387db350966f88eaad515bf41c4705
Parent:     ff79544754631cf3d237ff47b7d0e7ab2d211fcf
Author:     Evgeniy Dushistov <[EMAIL PROTECTED]>
AuthorDate: Mon Jan 29 13:19:54 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Jan 30 08:26:45 2007 -0800

    [PATCH] ufs: alloc metadata null page fix
    
    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 <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/ufs/balloc.c |    5 ++++-
 fs/ufs/inode.c  |   14 +++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 2e0021e..96ca845 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -233,7 +233,7 @@ 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;
@@ -241,8 +241,11 @@ static void ufs_change_blocknr(struct inode *inode, 
unsigned int baseblk,
        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);
 
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 2fbab0a..4295ca9 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -242,7 +242,8 @@ repeat:
                        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
@@ -250,7 +251,7 @@ repeat:
        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
@@ -261,7 +262,8 @@ repeat:
                                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) || 
@@ -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)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to