aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 2a1cb0979768..e3a55eb8b26a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -326,11 +326,14 @@ ext4_ext_max_entries(struct inode *inode, int depth)
326 326
327static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) 327static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
328{ 328{
329 ext4_fsblk_t block = ext_pblock(ext); 329 ext4_fsblk_t block = ext_pblock(ext), valid_block;
330 int len = ext4_ext_get_actual_len(ext); 330 int len = ext4_ext_get_actual_len(ext);
331 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 331 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
332 if (unlikely(block < le32_to_cpu(es->s_first_data_block) || 332
333 ((block + len) > ext4_blocks_count(es)))) 333 valid_block = le32_to_cpu(es->s_first_data_block) +
334 EXT4_SB(inode->i_sb)->s_gdb_count;
335 if (unlikely(block <= valid_block ||
336 ((block + len) > ext4_blocks_count(es))))
334 return 0; 337 return 0;
335 else 338 else
336 return 1; 339 return 1;
@@ -339,10 +342,13 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
339static int ext4_valid_extent_idx(struct inode *inode, 342static int ext4_valid_extent_idx(struct inode *inode,
340 struct ext4_extent_idx *ext_idx) 343 struct ext4_extent_idx *ext_idx)
341{ 344{
342 ext4_fsblk_t block = idx_pblock(ext_idx); 345 ext4_fsblk_t block = idx_pblock(ext_idx), valid_block;
343 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 346 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
344 if (unlikely(block < le32_to_cpu(es->s_first_data_block) || 347
345 (block >= ext4_blocks_count(es)))) 348 valid_block = le32_to_cpu(es->s_first_data_block) +
349 EXT4_SB(inode->i_sb)->s_gdb_count;
350 if (unlikely(block <= valid_block ||
351 (block >= ext4_blocks_count(es))))
346 return 0; 352 return 0;
347 else 353 else
348 return 1; 354 return 1;
@@ -1835,11 +1841,13 @@ ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
1835{ 1841{
1836 struct ext4_ext_cache *cex; 1842 struct ext4_ext_cache *cex;
1837 BUG_ON(len == 0); 1843 BUG_ON(len == 0);
1844 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1838 cex = &EXT4_I(inode)->i_cached_extent; 1845 cex = &EXT4_I(inode)->i_cached_extent;
1839 cex->ec_type = type; 1846 cex->ec_type = type;
1840 cex->ec_block = block; 1847 cex->ec_block = block;
1841 cex->ec_len = len; 1848 cex->ec_len = len;
1842 cex->ec_start = start; 1849 cex->ec_start = start;
1850 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1843} 1851}
1844 1852
1845/* 1853/*
@@ -1896,12 +1904,17 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1896 struct ext4_extent *ex) 1904 struct ext4_extent *ex)
1897{ 1905{
1898 struct ext4_ext_cache *cex; 1906 struct ext4_ext_cache *cex;
1907 int ret = EXT4_EXT_CACHE_NO;
1899 1908
1909 /*
1910 * We borrow i_block_reservation_lock to protect i_cached_extent
1911 */
1912 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1900 cex = &EXT4_I(inode)->i_cached_extent; 1913 cex = &EXT4_I(inode)->i_cached_extent;
1901 1914
1902 /* has cache valid data? */ 1915 /* has cache valid data? */
1903 if (cex->ec_type == EXT4_EXT_CACHE_NO) 1916 if (cex->ec_type == EXT4_EXT_CACHE_NO)
1904 return EXT4_EXT_CACHE_NO; 1917 goto errout;
1905 1918
1906 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP && 1919 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
1907 cex->ec_type != EXT4_EXT_CACHE_EXTENT); 1920 cex->ec_type != EXT4_EXT_CACHE_EXTENT);
@@ -1912,11 +1925,11 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1912 ext_debug("%u cached by %u:%u:%llu\n", 1925 ext_debug("%u cached by %u:%u:%llu\n",
1913 block, 1926 block,
1914 cex->ec_block, cex->ec_len, cex->ec_start); 1927 cex->ec_block, cex->ec_len, cex->ec_start);
1915 return cex->ec_type; 1928 ret = cex->ec_type;
1916 } 1929 }
1917 1930errout:
1918 /* not in cache */ 1931 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1919 return EXT4_EXT_CACHE_NO; 1932 return ret;
1920} 1933}
1921 1934
1922/* 1935/*
@@ -2869,6 +2882,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2869 if (allocated > max_blocks) 2882 if (allocated > max_blocks)
2870 allocated = max_blocks; 2883 allocated = max_blocks;
2871 set_buffer_unwritten(bh_result); 2884 set_buffer_unwritten(bh_result);
2885 bh_result->b_bdev = inode->i_sb->s_bdev;
2886 bh_result->b_blocknr = newblock;
2872 goto out2; 2887 goto out2;
2873 } 2888 }
2874 2889