Merge ../linux-2.6
[pandora-kernel.git] / fs / ufs / inode.c
index 259bd19..30c6e8a 100644 (file)
@@ -98,7 +98,9 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag)
        u64 temp = 0L;
 
        UFSD(": frag = %llu  depth = %d\n", (unsigned long long)frag, depth);
-       UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask);
+       UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",
+               uspi->s_fpbshift, uspi->s_apbmask,
+               (unsigned long long)mask);
 
        if (depth == 0)
                return 0;
@@ -167,18 +169,20 @@ static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh)
 
 static struct buffer_head *
 ufs_clear_frags(struct inode *inode, sector_t beg,
-               unsigned int n)
+               unsigned int n, sector_t want)
 {
-       struct buffer_head *res, *bh;
+       struct buffer_head *res = NULL, *bh;
        sector_t end = beg + n;
 
-       res = sb_getblk(inode->i_sb, beg);
-       ufs_clear_frag(inode, res);
-       for (++beg; beg < end; ++beg) {
+       for (; beg < end; ++beg) {
                bh = sb_getblk(inode->i_sb, beg);
                ufs_clear_frag(inode, bh);
-               brelse(bh);
+               if (want != beg)
+                       brelse(bh);
+               else
+                       res = bh;
        }
+       BUG_ON(!res);
        return res;
 }
 
@@ -263,7 +267,9 @@ repeat:
                        lastfrag = ufsi->i_lastfrag;
                        
                }
-               goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb;
+               tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]);
+               if (tmp)
+                       goal = tmp + uspi->s_fpb;
                tmp = ufs_new_fragments (inode, p, fragment - blockoff, 
                                         goal, required + blockoff,
                                         err, locked_page);
@@ -275,13 +281,15 @@ repeat:
                tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff),
                                        fs32_to_cpu(sb, *p), required +  (blockoff - lastblockoff),
                                        err, locked_page);
-       }
+       } else /* (lastblock > block) */ {
        /*
         * We will allocate new block before last allocated block
         */
-       else /* (lastblock > block) */ {
-               if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1])))
-                       goal = tmp + uspi->s_fpb;
+               if (block) {
+                       tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[block-1]);
+                       if (tmp)
+                               goal = tmp + uspi->s_fpb;
+               }
                tmp = ufs_new_fragments(inode, p, fragment - blockoff,
                                        goal, uspi->s_fpb, err, locked_page);
        }
@@ -294,7 +302,7 @@ repeat:
        }
 
        if (!phys) {
-               result = ufs_clear_frags(inode, tmp + blockoff, required);
+               result = ufs_clear_frags(inode, tmp, required, tmp + blockoff);
        } else {
                *phys = tmp + blockoff;
                result = NULL;
@@ -381,7 +389,7 @@ repeat:
                }
        }
 
-       if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]) + uspi->s_fpb))
+       if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1])))
                goal = tmp + uspi->s_fpb;
        else
                goal = bh->b_blocknr + uspi->s_fpb;
@@ -395,7 +403,8 @@ repeat:
 
 
        if (!phys) {
-               result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb);
+               result = ufs_clear_frags(inode, tmp, uspi->s_fpb,
+                                        tmp + blockoff);
        } else {
                *phys = tmp + blockoff;
                *new = 1;
@@ -429,7 +438,7 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
        
        if (!create) {
                phys64 = ufs_frag_map(inode, fragment);
-               UFSD("phys64 = %llu \n",phys64);
+               UFSD("phys64 = %llu\n", (unsigned long long)phys64);
                if (phys64)
                        map_bh(bh_result, sb, phys64);
                return 0;
@@ -574,7 +583,7 @@ static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
 {
        return generic_block_bmap(mapping,block,ufs_getfrag_block);
 }
-struct address_space_operations ufs_aops = {
+const struct address_space_operations ufs_aops = {
        .readpage = ufs_readpage,
        .writepage = ufs_writepage,
        .sync_page = block_sync_page,
@@ -841,14 +850,17 @@ int ufs_sync_inode (struct inode *inode)
 
 void ufs_delete_inode (struct inode * inode)
 {
+       loff_t old_i_size;
+
        truncate_inode_pages(&inode->i_data, 0);
        /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
        lock_kernel();
        mark_inode_dirty(inode);
        ufs_update_inode(inode, IS_SYNC(inode));
+       old_i_size = inode->i_size;
        inode->i_size = 0;
-       if (inode->i_blocks)
-               ufs_truncate (inode);
+       if (inode->i_blocks && ufs_truncate(inode, old_i_size))
+               ufs_warning(inode->i_sb, __FUNCTION__, "ufs_truncate failed\n");
        ufs_free_inode (inode);
        unlock_kernel();
 }