@@ -239,20 +239,20 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
239239 * no overlapping inline items exist in the btree
240240 */
241241static int insert_inline_extent (struct btrfs_trans_handle * trans ,
242- struct btrfs_path * path , bool extent_inserted ,
243- struct btrfs_root * root , struct inode * inode ,
244- u64 start , size_t size , size_t compressed_size ,
242+ struct btrfs_path * path ,
243+ struct btrfs_inode * inode , bool extent_inserted ,
244+ size_t size , size_t compressed_size ,
245245 int compress_type ,
246246 struct page * * compressed_pages )
247247{
248+ struct btrfs_root * root = inode -> root ;
248249 struct extent_buffer * leaf ;
249250 struct page * page = NULL ;
250251 char * kaddr ;
251252 unsigned long ptr ;
252253 struct btrfs_file_extent_item * ei ;
253254 int ret ;
254255 size_t cur_size = size ;
255- unsigned long offset ;
256256
257257 ASSERT ((compressed_size > 0 && compressed_pages ) ||
258258 (compressed_size == 0 && !compressed_pages ));
@@ -264,8 +264,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
264264 struct btrfs_key key ;
265265 size_t datasize ;
266266
267- key .objectid = btrfs_ino (BTRFS_I ( inode ) );
268- key .offset = start ;
267+ key .objectid = btrfs_ino (inode );
268+ key .offset = 0 ;
269269 key .type = BTRFS_EXTENT_DATA_KEY ;
270270
271271 datasize = btrfs_file_extent_calc_inline_size (cur_size );
@@ -303,12 +303,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
303303 btrfs_set_file_extent_compression (leaf , ei ,
304304 compress_type );
305305 } else {
306- page = find_get_page (inode -> i_mapping ,
307- start >> PAGE_SHIFT );
306+ page = find_get_page (inode -> vfs_inode .i_mapping , 0 );
308307 btrfs_set_file_extent_compression (leaf , ei , 0 );
309308 kaddr = kmap_atomic (page );
310- offset = offset_in_page (start );
311- write_extent_buffer (leaf , kaddr + offset , ptr , size );
309+ write_extent_buffer (leaf , kaddr , ptr , size );
312310 kunmap_atomic (kaddr );
313311 put_page (page );
314312 }
@@ -319,8 +317,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
319317 * We align size to sectorsize for inline extents just for simplicity
320318 * sake.
321319 */
322- size = ALIGN ( size , root -> fs_info -> sectorsize );
323- ret = btrfs_inode_set_file_extent_range ( BTRFS_I ( inode ), start , size );
320+ ret = btrfs_inode_set_file_extent_range ( inode , 0 ,
321+ ALIGN ( size , root -> fs_info -> sectorsize ) );
324322 if (ret )
325323 goto fail ;
326324
@@ -333,7 +331,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
333331 * before we unlock the pages. Otherwise we
334332 * could end up racing with unlink.
335333 */
336- BTRFS_I (inode )-> disk_i_size = inode -> i_size ;
334+ inode -> disk_i_size = i_size_read (& inode -> vfs_inode );
335+
337336fail :
338337 return ret ;
339338}
@@ -344,35 +343,30 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
344343 * does the checks required to make sure the data is small enough
345344 * to fit as an inline extent.
346345 */
347- static noinline int cow_file_range_inline (struct btrfs_inode * inode , u64 start ,
348- u64 end , size_t compressed_size ,
346+ static noinline int cow_file_range_inline (struct btrfs_inode * inode , u64 size ,
347+ size_t compressed_size ,
349348 int compress_type ,
350349 struct page * * compressed_pages )
351350{
352351 struct btrfs_drop_extents_args drop_args = { 0 };
353352 struct btrfs_root * root = inode -> root ;
354353 struct btrfs_fs_info * fs_info = root -> fs_info ;
355354 struct btrfs_trans_handle * trans ;
356- u64 isize = i_size_read (& inode -> vfs_inode );
357- u64 actual_end = min (end + 1 , isize );
358- u64 inline_len = actual_end - start ;
359- u64 aligned_end = ALIGN (end , fs_info -> sectorsize );
360- u64 data_len = inline_len ;
355+ u64 data_len = (compressed_size ?: size );
361356 int ret ;
362357 struct btrfs_path * path ;
363358
364- if (compressed_size )
365- data_len = compressed_size ;
366-
367- if (start > 0 ||
368- actual_end > fs_info -> sectorsize ||
359+ /*
360+ * We can create an inline extent if it ends at or beyond the current
361+ * i_size, is no larger than a sector (decompressed), and the (possibly
362+ * compressed) data fits in a leaf and the configured maximum inline
363+ * size.
364+ */
365+ if (size < i_size_read (& inode -> vfs_inode ) ||
366+ size > fs_info -> sectorsize ||
369367 data_len > BTRFS_MAX_INLINE_DATA_SIZE (fs_info ) ||
370- (!compressed_size &&
371- (actual_end & (fs_info -> sectorsize - 1 )) == 0 ) ||
372- end + 1 < isize ||
373- data_len > fs_info -> max_inline ) {
368+ data_len > fs_info -> max_inline )
374369 return 1 ;
375- }
376370
377371 path = btrfs_alloc_path ();
378372 if (!path )
@@ -386,30 +380,20 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
386380 trans -> block_rsv = & inode -> block_rsv ;
387381
388382 drop_args .path = path ;
389- drop_args .start = start ;
390- drop_args .end = aligned_end ;
383+ drop_args .start = 0 ;
384+ drop_args .end = fs_info -> sectorsize ;
391385 drop_args .drop_cache = true;
392386 drop_args .replace_extent = true;
393-
394- if (compressed_size && compressed_pages )
395- drop_args .extent_item_size = btrfs_file_extent_calc_inline_size (
396- compressed_size );
397- else
398- drop_args .extent_item_size = btrfs_file_extent_calc_inline_size (
399- inline_len );
400-
387+ drop_args .extent_item_size = btrfs_file_extent_calc_inline_size (data_len );
401388 ret = btrfs_drop_extents (trans , root , inode , & drop_args );
402389 if (ret ) {
403390 btrfs_abort_transaction (trans , ret );
404391 goto out ;
405392 }
406393
407- if (isize > actual_end )
408- inline_len = min_t (u64 , isize , actual_end );
409- ret = insert_inline_extent (trans , path , drop_args .extent_inserted ,
410- root , & inode -> vfs_inode , start ,
411- inline_len , compressed_size ,
412- compress_type , compressed_pages );
394+ ret = insert_inline_extent (trans , path , inode , drop_args .extent_inserted ,
395+ size , compressed_size , compress_type ,
396+ compressed_pages );
413397 if (ret && ret != - ENOSPC ) {
414398 btrfs_abort_transaction (trans , ret );
415399 goto out ;
@@ -418,7 +402,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
418402 goto out ;
419403 }
420404
421- btrfs_update_inode_bytes (inode , inline_len , drop_args .bytes_found );
405+ btrfs_update_inode_bytes (inode , size , drop_args .bytes_found );
422406 ret = btrfs_update_inode (trans , root , inode );
423407 if (ret && ret != - ENOSPC ) {
424408 btrfs_abort_transaction (trans , ret );
@@ -739,12 +723,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
739723 /* we didn't compress the entire range, try
740724 * to make an uncompressed inline extent.
741725 */
742- ret = cow_file_range_inline (BTRFS_I (inode ), start , end ,
726+ ret = cow_file_range_inline (BTRFS_I (inode ), actual_end ,
743727 0 , BTRFS_COMPRESS_NONE ,
744728 NULL );
745729 } else {
746730 /* try making a compressed inline extent */
747- ret = cow_file_range_inline (BTRFS_I (inode ), start , end ,
731+ ret = cow_file_range_inline (BTRFS_I (inode ), actual_end ,
748732 total_compressed ,
749733 compress_type , pages );
750734 }
@@ -1159,8 +1143,11 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
11591143 * So here we skip inline extent creation completely.
11601144 */
11611145 if (start == 0 && fs_info -> sectorsize == PAGE_SIZE ) {
1146+ u64 actual_end = min_t (u64 , i_size_read (& inode -> vfs_inode ),
1147+ end + 1 );
1148+
11621149 /* lets try to make an inline extent */
1163- ret = cow_file_range_inline (inode , start , end , 0 ,
1150+ ret = cow_file_range_inline (inode , actual_end , 0 ,
11641151 BTRFS_COMPRESS_NONE , NULL );
11651152 if (ret == 0 ) {
11661153 /*
0 commit comments