]> err.no Git - linux-2.6/blobdiff - fs/ext4/extents.c
PCI: powerpc: use generic pci_enable_resources()
[linux-2.6] / fs / ext4 / extents.c
index 995ac16102a982572c1c43e825c785429a62900e..9ae6e67090cdfad1bd52a7e7169ba725dea19c82 100644 (file)
@@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
        ext4_fsblk_t bg_start;
+       ext4_fsblk_t last_block;
        ext4_grpblk_t colour;
        int depth;
 
@@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
        /* OK. use inode's group */
        bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) +
                le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block);
-       colour = (current->pid % 16) *
+       last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
+
+       if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
+               colour = (current->pid % 16) *
                        (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+       else
+               colour = (current->pid % 16) * ((last_block - bg_start) / 16);
        return bg_start + colour + block;
 }
 
@@ -2168,6 +2174,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
        newblock = iblock - ee_block + ext_pblock(ex);
        ex2 = ex;
 
+       err = ext4_ext_get_access(handle, inode, path + depth);
+       if (err)
+               goto out;
+
        /* ex1: ee_block to iblock - 1 : uninitialized */
        if (iblock > ee_block) {
                ex1 = ex;
@@ -2210,6 +2220,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                        ex = path[depth].p_ext;
                        if (ex2 != &newex)
                                ex2 = ex;
+
+                       err = ext4_ext_get_access(handle, inode, path + depth);
+                       if (err)
+                               goto out;
                }
                allocated = max_blocks;
        }
@@ -2230,9 +2244,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
        ex2->ee_len = cpu_to_le16(allocated);
        if (ex2 != ex)
                goto insert;
-       err = ext4_ext_get_access(handle, inode, path + depth);
-       if (err)
-               goto out;
        /*
         * New (initialized) extent starts from the first block
         * in the current extent. i.e., ex2 == ex
@@ -2276,9 +2287,22 @@ out:
 }
 
 /*
+ * Block allocation/map/preallocation routine for extents based files
+ *
+ *
  * Need to be called with
  * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
  * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
+ *
+ * return > 0, number of of blocks already mapped/allocated
+ *          if create == 0 and these are pre-allocated blocks
+ *             buffer head is unmapped
+ *          otherwise blocks are mapped
+ *
+ * return = 0, if plain look up failed (blocks have not been allocated)
+ *          buffer head is unmapped
+ *
+ * return < 0, error case.
  */
 int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                        ext4_lblk_t iblock,
@@ -2637,13 +2661,14 @@ retry:
                ret = ext4_get_blocks_wrap(handle, inode, block,
                                          max_blocks, &map_bh,
                                          EXT4_CREATE_UNINITIALIZED_EXT, 0);
-               WARN_ON(ret <= 0);
                if (ret <= 0) {
-                       ext4_error(inode->i_sb, "ext4_fallocate",
-                                   "ext4_ext_get_blocks returned error: "
-                                   "inode#%lu, block=%u, max_blocks=%lu",
+#ifdef EXT4FS_DEBUG
+                       WARN_ON(ret <= 0);
+                       printk(KERN_ERR "%s: ext4_ext_get_blocks "
+                                   "returned error inode#%lu, block=%u, "
+                                   "max_blocks=%lu", __func__,
                                    inode->i_ino, block, max_blocks);
-                       ret = -EIO;
+#endif
                        ext4_mark_inode_dirty(handle, inode);
                        ret2 = ext4_journal_stop(handle);
                        break;