]> err.no Git - linux-2.6/blobdiff - fs/ext4/extents.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / fs / ext4 / extents.c
index 612c3d2c38240ff59a643bcbf405c2229443a848..b24d3c53f20cd20407d5d5373c79b725d308cc45 100644 (file)
@@ -1747,54 +1747,61 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
 }
 
 /*
- * ext4_ext_calc_credits_for_insert:
- * This routine returns max. credits that the extent tree can consume.
- * It should be OK for low-performance paths like ->writepage()
- * To allow many writing processes to fit into a single transaction,
- * the caller should calculate credits under i_data_sem and
- * pass the actual path.
+ * ext4_ext_calc_credits_for_single_extent:
+ * This routine returns max. credits that needed to insert an extent
+ * to the extent tree.
+ * When pass the actual path, the caller should calculate credits
+ * under i_data_sem.
  */
-int ext4_ext_calc_credits_for_insert(struct inode *inode,
+int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
                                                struct ext4_ext_path *path)
 {
-       int depth, needed;
-
        if (path) {
+               int depth = ext_depth(inode);
+               int ret = 0;
+
                /* probably there is space in leaf? */
-               depth = ext_depth(inode);
                if (le16_to_cpu(path[depth].p_hdr->eh_entries)
-                               < le16_to_cpu(path[depth].p_hdr->eh_max))
-                       return 1;
-       }
+                               < le16_to_cpu(path[depth].p_hdr->eh_max)) {
 
-       /*
-        * given 32-bit logical block (4294967296 blocks), max. tree
-        * can be 4 levels in depth -- 4 * 340^4 == 53453440000.
-        * Let's also add one more level for imbalance.
-        */
-       depth = 5;
-
-       /* allocation of new data block(s) */
-       needed = 2;
+                       /*
+                        *  There are some space in the leaf tree, no
+                        *  need to account for leaf block credit
+                        *
+                        *  bitmaps and block group descriptor blocks
+                        *  and other metadat blocks still need to be
+                        *  accounted.
+                        */
+                       /* 1 bitmap, 1 block group descriptor */
+                       ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb);
+               }
+       }
 
-       /*
-        * tree can be full, so it would need to grow in depth:
-        * we need one credit to modify old root, credits for
-        * new root will be added in split accounting
-        */
-       needed += 1;
+       return ext4_chunk_trans_blocks(inode, nrblocks);
+}
 
-       /*
-        * Index split can happen, we would need:
-        *    allocate intermediate indexes (bitmap + group)
-        *  + change two blocks at each level, but root (already included)
-        */
-       needed += (depth * 2) + (depth * 2);
+/*
+ * How many index/leaf blocks need to change/allocate to modify nrblocks?
+ *
+ * if nrblocks are fit in a single extent (chunk flag is 1), then
+ * in the worse case, each tree level index/leaf need to be changed
+ * if the tree split due to insert a new extent, then the old tree
+ * index/leaf need to be updated too
+ *
+ * If the nrblocks are discontiguous, they could cause
+ * the whole tree split more than once, but this is really rare.
+ */
+int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+{
+       int index;
+       int depth = ext_depth(inode);
 
-       /* any allocation modifies superblock */
-       needed += 1;
+       if (chunk)
+               index = depth * 2;
+       else
+               index = depth * 3;
 
-       return needed;
+       return index;
 }
 
 static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
@@ -1921,9 +1928,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                        correct_index = 1;
                        credits += (ext_depth(inode)) + 1;
                }
-#ifdef CONFIG_QUOTA
                credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
-#endif
 
                err = ext4_ext_journal_restart(handle, credits);
                if (err)
@@ -2805,7 +2810,7 @@ void ext4_ext_truncate(struct inode *inode)
        /*
         * probably first extent we're gonna free will be last in block
         */
-       err = ext4_writepage_trans_blocks(inode) + 3;
+       err = ext4_writepage_trans_blocks(inode);
        handle = ext4_journal_start(inode, err);
        if (IS_ERR(handle))
                return;
@@ -2819,7 +2824,7 @@ void ext4_ext_truncate(struct inode *inode)
        down_write(&EXT4_I(inode)->i_data_sem);
        ext4_ext_invalidate_cache(inode);
 
-       ext4_mb_discard_inode_preallocations(inode);
+       ext4_discard_reservation(inode);
 
        /*
         * TODO: optimization is possible here.
@@ -2858,27 +2863,6 @@ out_stop:
        ext4_journal_stop(handle);
 }
 
-/*
- * ext4_ext_writepage_trans_blocks:
- * calculate max number of blocks we could modify
- * in order to allocate new block for an inode
- */
-int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
-{
-       int needed;
-
-       needed = ext4_ext_calc_credits_for_insert(inode, NULL);
-
-       /* caller wants to allocate num blocks, but note it includes sb */
-       needed = needed * num - (num - 1);
-
-#ifdef CONFIG_QUOTA
-       needed += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
-#endif
-
-       return needed;
-}
-
 static void ext4_falloc_update_inode(struct inode *inode,
                                int mode, loff_t new_size, int update_ctime)
 {
@@ -2939,10 +2923,9 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
        max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
                                                        - block;
        /*
-        * credits to insert 1 extent into extent tree + buffers to be able to
-        * modify 1 super block, 1 block bitmap and 1 group descriptor.
+        * credits to insert 1 extent into extent tree
         */
-       credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
+       credits = ext4_chunk_trans_blocks(inode, max_blocks);
        mutex_lock(&inode->i_mutex);
 retry:
        while (ret >= 0 && ret < max_blocks) {