diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-08-27 22:17:07 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-08-27 22:17:07 -0400 |
commit | b30a72a7edfc64c8929104d5c2178aca489aa559 (patch) | |
tree | 2b26c155c318d08d946bd2d70cf815dcdb29a243 /fs/ext4/extents.c | |
parent | f1c5d30e1d79bbfb60eaf189db862d3cb2bcac92 (diff) | |
parent | c1b362e3b4d331a63915b268a33207311a439d60 (diff) |
Merge branch 'x86/urgent' into x86/cpu
Conflicts:
arch/x86/kernel/cpu/cyrix.c
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 113 |
1 files changed, 48 insertions, 65 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 612c3d2c3824..b24d3c53f20c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1747,54 +1747,61 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | /* | 1749 | /* |
1750 | * ext4_ext_calc_credits_for_insert: | 1750 | * ext4_ext_calc_credits_for_single_extent: |
1751 | * This routine returns max. credits that the extent tree can consume. | 1751 | * This routine returns max. credits that needed to insert an extent |
1752 | * It should be OK for low-performance paths like ->writepage() | 1752 | * to the extent tree. |
1753 | * To allow many writing processes to fit into a single transaction, | 1753 | * When pass the actual path, the caller should calculate credits |
1754 | * the caller should calculate credits under i_data_sem and | 1754 | * under i_data_sem. |
1755 | * pass the actual path. | ||
1756 | */ | 1755 | */ |
1757 | int ext4_ext_calc_credits_for_insert(struct inode *inode, | 1756 | int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks, |
1758 | struct ext4_ext_path *path) | 1757 | struct ext4_ext_path *path) |
1759 | { | 1758 | { |
1760 | int depth, needed; | ||
1761 | |||
1762 | if (path) { | 1759 | if (path) { |
1760 | int depth = ext_depth(inode); | ||
1761 | int ret = 0; | ||
1762 | |||
1763 | /* probably there is space in leaf? */ | 1763 | /* probably there is space in leaf? */ |
1764 | depth = ext_depth(inode); | ||
1765 | if (le16_to_cpu(path[depth].p_hdr->eh_entries) | 1764 | if (le16_to_cpu(path[depth].p_hdr->eh_entries) |
1766 | < le16_to_cpu(path[depth].p_hdr->eh_max)) | 1765 | < le16_to_cpu(path[depth].p_hdr->eh_max)) { |
1767 | return 1; | ||
1768 | } | ||
1769 | 1766 | ||
1770 | /* | 1767 | /* |
1771 | * given 32-bit logical block (4294967296 blocks), max. tree | 1768 | * There are some space in the leaf tree, no |
1772 | * can be 4 levels in depth -- 4 * 340^4 == 53453440000. | 1769 | * need to account for leaf block credit |
1773 | * Let's also add one more level for imbalance. | 1770 | * |
1774 | */ | 1771 | * bitmaps and block group descriptor blocks |
1775 | depth = 5; | 1772 | * and other metadat blocks still need to be |
1776 | 1773 | * accounted. | |
1777 | /* allocation of new data block(s) */ | 1774 | */ |
1778 | needed = 2; | 1775 | /* 1 bitmap, 1 block group descriptor */ |
1776 | ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb); | ||
1777 | } | ||
1778 | } | ||
1779 | 1779 | ||
1780 | /* | 1780 | return ext4_chunk_trans_blocks(inode, nrblocks); |
1781 | * tree can be full, so it would need to grow in depth: | 1781 | } |
1782 | * we need one credit to modify old root, credits for | ||
1783 | * new root will be added in split accounting | ||
1784 | */ | ||
1785 | needed += 1; | ||
1786 | 1782 | ||
1787 | /* | 1783 | /* |
1788 | * Index split can happen, we would need: | 1784 | * How many index/leaf blocks need to change/allocate to modify nrblocks? |
1789 | * allocate intermediate indexes (bitmap + group) | 1785 | * |
1790 | * + change two blocks at each level, but root (already included) | 1786 | * if nrblocks are fit in a single extent (chunk flag is 1), then |
1791 | */ | 1787 | * in the worse case, each tree level index/leaf need to be changed |
1792 | needed += (depth * 2) + (depth * 2); | 1788 | * if the tree split due to insert a new extent, then the old tree |
1789 | * index/leaf need to be updated too | ||
1790 | * | ||
1791 | * If the nrblocks are discontiguous, they could cause | ||
1792 | * the whole tree split more than once, but this is really rare. | ||
1793 | */ | ||
1794 | int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | ||
1795 | { | ||
1796 | int index; | ||
1797 | int depth = ext_depth(inode); | ||
1793 | 1798 | ||
1794 | /* any allocation modifies superblock */ | 1799 | if (chunk) |
1795 | needed += 1; | 1800 | index = depth * 2; |
1801 | else | ||
1802 | index = depth * 3; | ||
1796 | 1803 | ||
1797 | return needed; | 1804 | return index; |
1798 | } | 1805 | } |
1799 | 1806 | ||
1800 | static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | 1807 | 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, | |||
1921 | correct_index = 1; | 1928 | correct_index = 1; |
1922 | credits += (ext_depth(inode)) + 1; | 1929 | credits += (ext_depth(inode)) + 1; |
1923 | } | 1930 | } |
1924 | #ifdef CONFIG_QUOTA | ||
1925 | credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); | 1931 | credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); |
1926 | #endif | ||
1927 | 1932 | ||
1928 | err = ext4_ext_journal_restart(handle, credits); | 1933 | err = ext4_ext_journal_restart(handle, credits); |
1929 | if (err) | 1934 | if (err) |
@@ -2805,7 +2810,7 @@ void ext4_ext_truncate(struct inode *inode) | |||
2805 | /* | 2810 | /* |
2806 | * probably first extent we're gonna free will be last in block | 2811 | * probably first extent we're gonna free will be last in block |
2807 | */ | 2812 | */ |
2808 | err = ext4_writepage_trans_blocks(inode) + 3; | 2813 | err = ext4_writepage_trans_blocks(inode); |
2809 | handle = ext4_journal_start(inode, err); | 2814 | handle = ext4_journal_start(inode, err); |
2810 | if (IS_ERR(handle)) | 2815 | if (IS_ERR(handle)) |
2811 | return; | 2816 | return; |
@@ -2819,7 +2824,7 @@ void ext4_ext_truncate(struct inode *inode) | |||
2819 | down_write(&EXT4_I(inode)->i_data_sem); | 2824 | down_write(&EXT4_I(inode)->i_data_sem); |
2820 | ext4_ext_invalidate_cache(inode); | 2825 | ext4_ext_invalidate_cache(inode); |
2821 | 2826 | ||
2822 | ext4_mb_discard_inode_preallocations(inode); | 2827 | ext4_discard_reservation(inode); |
2823 | 2828 | ||
2824 | /* | 2829 | /* |
2825 | * TODO: optimization is possible here. | 2830 | * TODO: optimization is possible here. |
@@ -2858,27 +2863,6 @@ out_stop: | |||
2858 | ext4_journal_stop(handle); | 2863 | ext4_journal_stop(handle); |
2859 | } | 2864 | } |
2860 | 2865 | ||
2861 | /* | ||
2862 | * ext4_ext_writepage_trans_blocks: | ||
2863 | * calculate max number of blocks we could modify | ||
2864 | * in order to allocate new block for an inode | ||
2865 | */ | ||
2866 | int ext4_ext_writepage_trans_blocks(struct inode *inode, int num) | ||
2867 | { | ||
2868 | int needed; | ||
2869 | |||
2870 | needed = ext4_ext_calc_credits_for_insert(inode, NULL); | ||
2871 | |||
2872 | /* caller wants to allocate num blocks, but note it includes sb */ | ||
2873 | needed = needed * num - (num - 1); | ||
2874 | |||
2875 | #ifdef CONFIG_QUOTA | ||
2876 | needed += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); | ||
2877 | #endif | ||
2878 | |||
2879 | return needed; | ||
2880 | } | ||
2881 | |||
2882 | static void ext4_falloc_update_inode(struct inode *inode, | 2866 | static void ext4_falloc_update_inode(struct inode *inode, |
2883 | int mode, loff_t new_size, int update_ctime) | 2867 | int mode, loff_t new_size, int update_ctime) |
2884 | { | 2868 | { |
@@ -2939,10 +2923,9 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
2939 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) | 2923 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) |
2940 | - block; | 2924 | - block; |
2941 | /* | 2925 | /* |
2942 | * credits to insert 1 extent into extent tree + buffers to be able to | 2926 | * credits to insert 1 extent into extent tree |
2943 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | ||
2944 | */ | 2927 | */ |
2945 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; | 2928 | credits = ext4_chunk_trans_blocks(inode, max_blocks); |
2946 | mutex_lock(&inode->i_mutex); | 2929 | mutex_lock(&inode->i_mutex); |
2947 | retry: | 2930 | retry: |
2948 | while (ret >= 0 && ret < max_blocks) { | 2931 | while (ret >= 0 && ret < max_blocks) { |