]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/ext4/inode.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / ext4 / inode.c
index e659597b690b508e1325182de702031a73843f4d..9f7f9e49914fa775709d5c99e805440fd4ff0f9f 100644 (file)
@@ -39,7 +39,9 @@
 #include <linux/bio.h>
 #include <linux/workqueue.h>
 #include <linux/kernel.h>
+#include <linux/printk.h>
 #include <linux/slab.h>
+#include <linux/ratelimit.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -54,10 +56,17 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode,
                                              loff_t new_size)
 {
        trace_ext4_begin_ordered_truncate(inode, new_size);
-       return jbd2_journal_begin_ordered_truncate(
-                                       EXT4_SB(inode->i_sb)->s_journal,
-                                       &EXT4_I(inode)->jinode,
-                                       new_size);
+       /*
+        * If jinode is zero, then we never opened the file for
+        * writing, so there's no need to call
+        * jbd2_journal_begin_ordered_truncate() since there's no
+        * outstanding writes we need to flush.
+        */
+       if (!EXT4_I(inode)->jinode)
+               return 0;
+       return jbd2_journal_begin_ordered_truncate(EXT4_JOURNAL(inode),
+                                                  EXT4_I(inode)->jinode,
+                                                  new_size);
 }
 
 static void ext4_invalidatepage(struct page *page, unsigned long offset);
@@ -552,7 +561,7 @@ static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
 }
 
 /**
- *     ext4_blks_to_allocate: Look up the block map and count the number
+ *     ext4_blks_to_allocate - Look up the block map and count the number
  *     of direct blocks need to be allocated for the given branch.
  *
  *     @branch: chain of indirect blocks
@@ -591,13 +600,19 @@ static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned int blks,
 
 /**
  *     ext4_alloc_blocks: multiple allocate blocks needed for a branch
+ *     @handle: handle for this transaction
+ *     @inode: inode which needs allocated blocks
+ *     @iblock: the logical block to start allocated at
+ *     @goal: preferred physical block of allocation
  *     @indirect_blks: the number of blocks need to allocate for indirect
  *                     blocks
- *
+ *     @blks: number of desired blocks
  *     @new_blocks: on return it will store the new block numbers for
  *     the indirect blocks(if needed) and the first direct block,
- *     @blks:  on return it will store the total number of allocated
- *             direct blocks
+ *     @err: on return it will store the error code
+ *
+ *     This function will return the number of blocks allocated as
+ *     requested by the passed-in parameters.
  */
 static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
                             ext4_lblk_t iblock, ext4_fsblk_t goal,
@@ -711,9 +726,11 @@ failed_out:
 
 /**
  *     ext4_alloc_branch - allocate and set up a chain of blocks.
+ *     @handle: handle for this transaction
  *     @inode: owner
  *     @indirect_blks: number of allocated indirect blocks
  *     @blks: number of allocated direct blocks
+ *     @goal: preferred place for allocation
  *     @offsets: offsets (in the blocks) to store the pointers to next.
  *     @branch: place to store the chain in.
  *
@@ -826,6 +843,7 @@ failed:
 
 /**
  * ext4_splice_branch - splice the allocated branch onto inode.
+ * @handle: handle for this transaction
  * @inode: owner
  * @block: (logical) number of block we are adding
  * @chain: chain of indirect blocks (with a missing link - see
@@ -1081,7 +1099,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
  * Calculate the number of metadata blocks need to reserve
  * to allocate a block located at @lblock
  */
-static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock)
+static int ext4_calc_metadata_amount(struct inode *inode, ext4_lblk_t lblock)
 {
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
                return ext4_ext_calc_metadata_amount(inode, lblock);
@@ -1320,7 +1338,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
         * avoid double accounting
         */
        if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
-               EXT4_I(inode)->i_delalloc_reserved_flag = 1;
+               ext4_set_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED);
        /*
         * We need to check for EXT4 here because migrate
         * could have changed the inode type in between
@@ -1350,7 +1368,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                        ext4_da_update_reserve_space(inode, retval, 1);
        }
        if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
-               EXT4_I(inode)->i_delalloc_reserved_flag = 0;
+               ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED);
 
        up_write((&EXT4_I(inode)->i_data_sem));
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
@@ -1878,7 +1896,7 @@ static int ext4_journalled_write_end(struct file *file,
 /*
  * Reserve a single block located at lblock
  */
-static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
+static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)
 {
        int retries = 0;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -2239,7 +2257,7 @@ static void mpage_da_map_and_submit(struct mpage_da_data *mpd)
         * affects functions in many different parts of the allocation
         * call path.  This flag exists primarily because we don't
         * want to change *many* call functions, so ext4_map_blocks()
-        * will set the magic i_delalloc_reserved_flag once the
+        * will set the EXT4_STATE_DELALLOC_RESERVED flag once the
         * inode's allocation semaphore is taken.
         *
         * If the blocks in questions were delalloc blocks, set
@@ -3362,7 +3380,7 @@ int ext4_alloc_da_blocks(struct inode *inode)
         * doing I/O at all.
         *
         * We could call write_cache_pages(), and then redirty all of
-        * the pages by calling redirty_page_for_writeback() but that
+        * the pages by calling redirty_page_for_writepage() but that
         * would be ugly in the extreme.  So instead we would need to
         * replicate parts of the code in the above functions,
         * simplifying them becuase we wouldn't actually intend to
@@ -3720,8 +3738,7 @@ static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
 retry:
        io_end = ext4_init_io_end(inode, GFP_ATOMIC);
        if (!io_end) {
-               if (printk_ratelimit())
-                       printk(KERN_WARNING "%s: allocation fail\n", __func__);
+               pr_warn_ratelimited("%s: allocation fail\n", __func__);
                schedule();
                goto retry;
        }
@@ -3745,9 +3762,9 @@ retry:
  * preallocated extents, and those write extend the file, no need to
  * fall back to buffered IO.
  *
- * For holes, we fallocate those blocks, mark them as unintialized
+ * For holes, we fallocate those blocks, mark them as uninitialized
  * If those blocks were preallocated, we mark sure they are splited, but
- * still keep the range to write as unintialized.
+ * still keep the range to write as uninitialized.
  *
  * The unwrritten extents will be converted to written when DIO is completed.
  * For async direct IO, since the IO may still pending when return, we
@@ -4045,7 +4062,7 @@ int ext4_block_truncate_page(handle_t *handle,
        if (ext4_should_journal_data(inode)) {
                err = ext4_handle_dirty_metadata(handle, inode, bh);
        } else {
-               if (ext4_should_order_data(inode))
+               if (ext4_should_order_data(inode) && EXT4_I(inode)->jinode)
                        err = ext4_jbd2_file_inode(handle, inode);
                mark_buffer_dirty(bh);
        }
@@ -4169,6 +4186,7 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
 {
        __le32 *p;
        int     flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED;
+       int     err;
 
        if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
                flags |= EXT4_FREE_BLOCKS_METADATA;
@@ -4184,11 +4202,23 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
        if (try_to_extend_transaction(handle, inode)) {
                if (bh) {
                        BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
-                       ext4_handle_dirty_metadata(handle, inode, bh);
+                       err = ext4_handle_dirty_metadata(handle, inode, bh);
+                       if (unlikely(err)) {
+                               ext4_std_error(inode->i_sb, err);
+                               return 1;
+                       }
+               }
+               err = ext4_mark_inode_dirty(handle, inode);
+               if (unlikely(err)) {
+                       ext4_std_error(inode->i_sb, err);
+                       return 1;
+               }
+               err = ext4_truncate_restart_trans(handle, inode,
+                                                 blocks_for_truncate(inode));
+               if (unlikely(err)) {
+                       ext4_std_error(inode->i_sb, err);
+                       return 1;
                }
-               ext4_mark_inode_dirty(handle, inode);
-               ext4_truncate_restart_trans(handle, inode,
-                                           blocks_for_truncate(inode));
                if (bh) {
                        BUFFER_TRACE(bh, "retaking write access");
                        ext4_journal_get_write_access(handle, bh);
@@ -4349,6 +4379,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
                                        (__le32 *) bh->b_data,
                                        (__le32 *) bh->b_data + addr_per_block,
                                        depth);
+                       brelse(bh);
 
                        /*
                         * Everything below this this pointer has been
@@ -4859,7 +4890,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        }
        inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
 
-       ei->i_state_flags = 0;
+       ext4_clear_state_flags(ei);     /* Only relevant on 32-bit archs */
        ei->i_dir_start_lookup = 0;
        ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
        /* We now have enough fields to check if the inode was active or not.
@@ -5118,7 +5149,7 @@ static int ext4_do_update_inode(handle_t *handle,
        if (ext4_inode_blocks_set(handle, raw_inode, ei))
                goto out_brelse;
        raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
-       raw_inode->i_flags = cpu_to_le32(ei->i_flags);
+       raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF);
        if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
            cpu_to_le32(EXT4_OS_HURD))
                raw_inode->i_file_acl_high =