]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ext4/inode.c
write_inode_now(): avoid unnecessary synchronous write
[linux-2.6-omap-h63xx.git] / fs / ext4 / inode.c
index 05c4145dd27d3e03b634d7525aea9fe472012a58..f4e3874522465cb52324fa7d317dbc2a11e83fb4 100644 (file)
@@ -429,16 +429,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
  *     ext4_find_goal - find a prefered place for allocation.
  *     @inode: owner
  *     @block:  block we want
- *     @chain:  chain of indirect blocks
  *     @partial: pointer to the last triple within a chain
- *     @goal:  place to store the result.
  *
  *     Normally this function find the prefered place for block allocation,
- *     stores it in *@goal and returns zero.
+ *     returns it.
  */
-
 static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
-               Indirect chain[4], Indirect *partial)
+               Indirect *partial)
 {
        struct ext4_block_alloc_info *block_i;
 
@@ -839,7 +836,7 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
        if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info))
                ext4_init_block_alloc_info(inode);
 
-       goal = ext4_find_goal(inode, iblock, chain, partial);
+       goal = ext4_find_goal(inode, iblock, partial);
 
        /* the number of blocks need to allocate for [d,t]indirect blocks */
        indirect_blks = (chain + depth) - partial - 1;
@@ -2683,21 +2680,31 @@ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
        }
 }
 
-void ext4_read_inode(struct inode * inode)
+struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 {
        struct ext4_iloc iloc;
        struct ext4_inode *raw_inode;
-       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct ext4_inode_info *ei;
        struct buffer_head *bh;
+       struct inode *inode;
+       long ret;
        int block;
 
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       ei = EXT4_I(inode);
 #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
        ei->i_acl = EXT4_ACL_NOT_CACHED;
        ei->i_default_acl = EXT4_ACL_NOT_CACHED;
 #endif
        ei->i_block_alloc_info = NULL;
 
-       if (__ext4_get_inode_loc(inode, &iloc, 0))
+       ret = __ext4_get_inode_loc(inode, &iloc, 0);
+       if (ret < 0)
                goto bad_inode;
        bh = iloc.bh;
        raw_inode = ext4_raw_inode(&iloc);
@@ -2723,6 +2730,7 @@ void ext4_read_inode(struct inode * inode)
                    !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
                        /* this inode is deleted */
                        brelse (bh);
+                       ret = -ESTALE;
                        goto bad_inode;
                }
                /* The only unlinked inodes we let through here have
@@ -2761,6 +2769,7 @@ void ext4_read_inode(struct inode * inode)
                if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
                    EXT4_INODE_SIZE(inode->i_sb)) {
                        brelse (bh);
+                       ret = -EIO;
                        goto bad_inode;
                }
                if (ei->i_extra_isize == 0) {
@@ -2814,11 +2823,12 @@ void ext4_read_inode(struct inode * inode)
        }
        brelse (iloc.bh);
        ext4_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 ext4_inode_blocks_set(handle_t *handle,