Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: Fix race in ext4_inode_info.i_cached_extent
ext4: Clear the unwritten buffer_head flag after the extent is initialized
ext4: Use a fake block number for delayed new buffer_head
ext4: Fix sub-block zeroing for writes into preallocated extents

+39 -6
+14 -5
fs/ext4/extents.c
··· 1841 1841 { 1842 1842 struct ext4_ext_cache *cex; 1843 1843 BUG_ON(len == 0); 1844 + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); 1844 1845 cex = &EXT4_I(inode)->i_cached_extent; 1845 1846 cex->ec_type = type; 1846 1847 cex->ec_block = block; 1847 1848 cex->ec_len = len; 1848 1849 cex->ec_start = start; 1850 + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1849 1851 } 1850 1852 1851 1853 /* ··· 1904 1902 struct ext4_extent *ex) 1905 1903 { 1906 1904 struct ext4_ext_cache *cex; 1905 + int ret = EXT4_EXT_CACHE_NO; 1907 1906 1907 + /* 1908 + * We borrow i_block_reservation_lock to protect i_cached_extent 1909 + */ 1910 + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); 1908 1911 cex = &EXT4_I(inode)->i_cached_extent; 1909 1912 1910 1913 /* has cache valid data? */ 1911 1914 if (cex->ec_type == EXT4_EXT_CACHE_NO) 1912 - return EXT4_EXT_CACHE_NO; 1915 + goto errout; 1913 1916 1914 1917 BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP && 1915 1918 cex->ec_type != EXT4_EXT_CACHE_EXTENT); ··· 1925 1918 ext_debug("%u cached by %u:%u:%llu\n", 1926 1919 block, 1927 1920 cex->ec_block, cex->ec_len, cex->ec_start); 1928 - return cex->ec_type; 1921 + ret = cex->ec_type; 1929 1922 } 1930 - 1931 - /* not in cache */ 1932 - return EXT4_EXT_CACHE_NO; 1923 + errout: 1924 + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1925 + return ret; 1933 1926 } 1934 1927 1935 1928 /* ··· 2882 2875 if (allocated > max_blocks) 2883 2876 allocated = max_blocks; 2884 2877 set_buffer_unwritten(bh_result); 2878 + bh_result->b_bdev = inode->i_sb->s_bdev; 2879 + bh_result->b_blocknr = newblock; 2885 2880 goto out2; 2886 2881 } 2887 2882
+25 -1
fs/ext4/inode.c
··· 1149 1149 int retval; 1150 1150 1151 1151 clear_buffer_mapped(bh); 1152 + clear_buffer_unwritten(bh); 1152 1153 1153 1154 /* 1154 1155 * Try to see if we can get the block without requesting ··· 1178 1177 */ 1179 1178 if (retval > 0 && buffer_mapped(bh)) 1180 1179 return retval; 1180 + 1181 + /* 1182 + * When we call get_blocks without the create flag, the 1183 + * BH_Unwritten flag could have gotten set if the blocks 1184 + * requested were part of a uninitialized extent. We need to 1185 + * clear this flag now that we are committed to convert all or 1186 + * part of the uninitialized extent to be an initialized 1187 + * extent. This is because we need to avoid the combination 1188 + * of BH_Unwritten and BH_Mapped flags being simultaneously 1189 + * set on the buffer_head. 1190 + */ 1191 + clear_buffer_unwritten(bh); 1181 1192 1182 1193 /* 1183 1194 * New blocks allocate and/or writing to uninitialized extent ··· 2310 2297 struct buffer_head *bh_result, int create) 2311 2298 { 2312 2299 int ret = 0; 2300 + sector_t invalid_block = ~((sector_t) 0xffff); 2301 + 2302 + if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es)) 2303 + invalid_block = ~0; 2313 2304 2314 2305 BUG_ON(create == 0); 2315 2306 BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize); ··· 2335 2318 /* not enough space to reserve */ 2336 2319 return ret; 2337 2320 2338 - map_bh(bh_result, inode->i_sb, 0); 2321 + map_bh(bh_result, inode->i_sb, invalid_block); 2339 2322 set_buffer_new(bh_result); 2340 2323 set_buffer_delay(bh_result); 2341 2324 } else if (ret > 0) { 2342 2325 bh_result->b_size = (ret << inode->i_blkbits); 2326 + /* 2327 + * With sub-block writes into unwritten extents 2328 + * we also need to mark the buffer as new so that 2329 + * the unwritten parts of the buffer gets correctly zeroed. 2330 + */ 2331 + if (buffer_unwritten(bh_result)) 2332 + set_buffer_new(bh_result); 2343 2333 ret = 0; 2344 2334 } 2345 2335