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.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e40332158340..e3a55eb8b26a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1841,11 +1841,13 @@ ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
1841{ 1841{
1842 struct ext4_ext_cache *cex; 1842 struct ext4_ext_cache *cex;
1843 BUG_ON(len == 0); 1843 BUG_ON(len == 0);
1844 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1844 cex = &EXT4_I(inode)->i_cached_extent; 1845 cex = &EXT4_I(inode)->i_cached_extent;
1845 cex->ec_type = type; 1846 cex->ec_type = type;
1846 cex->ec_block = block; 1847 cex->ec_block = block;
1847 cex->ec_len = len; 1848 cex->ec_len = len;
1848 cex->ec_start = start; 1849 cex->ec_start = start;
1850 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1849} 1851}
1850 1852
1851/* 1853/*
@@ -1902,12 +1904,17 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1902 struct ext4_extent *ex) 1904 struct ext4_extent *ex)
1903{ 1905{
1904 struct ext4_ext_cache *cex; 1906 struct ext4_ext_cache *cex;
1907 int ret = EXT4_EXT_CACHE_NO;
1905 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);
1906 cex = &EXT4_I(inode)->i_cached_extent; 1913 cex = &EXT4_I(inode)->i_cached_extent;
1907 1914
1908 /* has cache valid data? */ 1915 /* has cache valid data? */
1909 if (cex->ec_type == EXT4_EXT_CACHE_NO) 1916 if (cex->ec_type == EXT4_EXT_CACHE_NO)
1910 return EXT4_EXT_CACHE_NO; 1917 goto errout;
1911 1918
1912 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP && 1919 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
1913 cex->ec_type != EXT4_EXT_CACHE_EXTENT); 1920 cex->ec_type != EXT4_EXT_CACHE_EXTENT);
@@ -1918,11 +1925,11 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1918 ext_debug("%u cached by %u:%u:%llu\n", 1925 ext_debug("%u cached by %u:%u:%llu\n",
1919 block, 1926 block,
1920 cex->ec_block, cex->ec_len, cex->ec_start); 1927 cex->ec_block, cex->ec_len, cex->ec_start);
1921 return cex->ec_type; 1928 ret = cex->ec_type;
1922 } 1929 }
1923 1930errout:
1924 /* not in cache */ 1931 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1925 return EXT4_EXT_CACHE_NO; 1932 return ret;
1926} 1933}
1927 1934
1928/* 1935/*
@@ -2875,6 +2882,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2875 if (allocated > max_blocks) 2882 if (allocated > max_blocks)
2876 allocated = max_blocks; 2883 allocated = max_blocks;
2877 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;
2878 goto out2; 2887 goto out2;
2879 } 2888 }
2880 2889