vfs: pagecache usage optimization for pagesize!=blocksize
[safe/jmp/linux-2.6] / fs / ext2 / inode.c
index b1ab32a..991d6df 100644 (file)
@@ -239,7 +239,7 @@ no_block:
  *     @inode: owner
  *     @ind: descriptor of indirect block.
  *
- *     This function returns the prefered place for block allocation.
+ *     This function returns the preferred place for block allocation.
  *     It is used when heuristic for sequential allocation fails.
  *     Rules are:
  *       + if there is a block to the left of our position - allocate near it.
@@ -254,13 +254,13 @@ no_block:
  *     Caller must make sure that @ind is valid and will stay that way.
  */
 
-static unsigned long ext2_find_near(struct inode *inode, Indirect *ind)
+static ext2_fsblk_t ext2_find_near(struct inode *inode, Indirect *ind)
 {
        struct ext2_inode_info *ei = EXT2_I(inode);
        __le32 *start = ind->bh ? (__le32 *) ind->bh->b_data : ei->i_data;
        __le32 *p;
-       unsigned long bg_start;
-       unsigned long colour;
+       ext2_fsblk_t bg_start;
+       ext2_fsblk_t colour;
 
        /* Try to find previous block */
        for (p = ind->p - 1; p >= start; p--)
@@ -275,27 +275,23 @@ static unsigned long ext2_find_near(struct inode *inode, Indirect *ind)
         * It is going to be refered from inode itself? OK, just put it into
         * the same cylinder group then.
         */
-       bg_start = (ei->i_block_group * EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
-               le32_to_cpu(EXT2_SB(inode->i_sb)->s_es->s_first_data_block);
+       bg_start = ext2_group_first_block_no(inode->i_sb, ei->i_block_group);
        colour = (current->pid % 16) *
                        (EXT2_BLOCKS_PER_GROUP(inode->i_sb) / 16);
        return bg_start + colour;
 }
 
 /**
- *     ext2_find_goal - find a prefered place for allocation.
+ *     ext2_find_goal - find a preferred place for allocation.
  *     @inode: owner
  *     @block:  block we want
- *     @chain:  chain of indirect blocks
  *     @partial: pointer to the last triple within a chain
  *
  *     Returns preferred place for a block (the goal).
  */
 
-static inline int ext2_find_goal(struct inode *inode,
-                                long block,
-                                Indirect chain[4],
-                                Indirect *partial)
+static inline ext2_fsblk_t ext2_find_goal(struct inode *inode, long block,
+                                         Indirect *partial)
 {
        struct ext2_block_alloc_info *block_i;
 
@@ -569,7 +565,6 @@ static void ext2_splice_branch(struct inode *inode,
  *
  * `handle' can be NULL if create == 0.
  *
- * The BKL may not be held on entry here.  Be sure to take it early.
  * return > 0, # of blocks mapped or allocated.
  * return = 0, if plain lookup failed.
  * return < 0, error case.
@@ -639,7 +634,7 @@ reread:
        if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info))
                ext2_init_block_alloc_info(inode);
 
-       goal = ext2_find_goal(inode, iblock, chain, partial);
+       goal = ext2_find_goal(inode, iblock, partial);
 
        /* the number of blocks need to allocate for [d,t]indirect blocks */
        indirect_blks = (chain + depth) - partial - 1;
@@ -796,11 +791,12 @@ const struct address_space_operations ext2_aops = {
        .direct_IO              = ext2_direct_IO,
        .writepages             = ext2_writepages,
        .migratepage            = buffer_migrate_page,
+       .is_partially_uptodate  = block_is_partially_uptodate,
 };
 
 const struct address_space_operations ext2_aops_xip = {
        .bmap                   = ext2_bmap,
-       .get_xip_page           = ext2_get_xip_page,
+       .get_xip_mem            = ext2_get_xip_mem,
 };
 
 const struct address_space_operations ext2_nobh_aops = {
@@ -1185,22 +1181,33 @@ void ext2_get_inode_flags(struct ext2_inode_info *ei)
                ei->i_flags |= EXT2_DIRSYNC_FL;
 }
 
-void ext2_read_inode (struct inode * inode)
+struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
 {
-       struct ext2_inode_info *ei = EXT2_I(inode);
-       ino_t ino = inode->i_ino;
+       struct ext2_inode_info *ei;
        struct buffer_head * bh;
-       struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
+       struct ext2_inode *raw_inode;
+       struct inode *inode;
+       long ret = -EIO;
        int n;
 
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       ei = EXT2_I(inode);
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
        ei->i_acl = EXT2_ACL_NOT_CACHED;
        ei->i_default_acl = EXT2_ACL_NOT_CACHED;
 #endif
        ei->i_block_alloc_info = NULL;
 
-       if (IS_ERR(raw_inode))
+       raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
+       if (IS_ERR(raw_inode)) {
+               ret = PTR_ERR(raw_inode);
                goto bad_inode;
+       }
 
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
        inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
@@ -1224,6 +1231,7 @@ void ext2_read_inode (struct inode * inode)
        if (inode->i_nlink == 0 && (inode->i_mode == 0 || ei->i_dtime)) {
                /* this inode is deleted */
                brelse (bh);
+               ret = -ESTALE;
                goto bad_inode;
        }
        inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
@@ -1290,11 +1298,12 @@ void ext2_read_inode (struct inode * inode)
        }
        brelse (bh);
        ext2_set_inode_flags(inode);
-       return;
+       unlock_new_inode(inode);
+       return inode;
        
 bad_inode:
-       make_bad_inode(inode);
-       return;
+       iget_failed(inode);
+       return ERR_PTR(ret);
 }
 
 static int ext2_update_inode(struct inode * inode, int do_sync)