@@ -239,20 +239,20 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
239
239
* no overlapping inline items exist in the btree
240
240
*/
241
241
static 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 ,
245
245
int compress_type ,
246
246
struct page * * compressed_pages )
247
247
{
248
+ struct btrfs_root * root = inode -> root ;
248
249
struct extent_buffer * leaf ;
249
250
struct page * page = NULL ;
250
251
char * kaddr ;
251
252
unsigned long ptr ;
252
253
struct btrfs_file_extent_item * ei ;
253
254
int ret ;
254
255
size_t cur_size = size ;
255
- unsigned long offset ;
256
256
257
257
ASSERT ((compressed_size > 0 && compressed_pages ) ||
258
258
(compressed_size == 0 && !compressed_pages ));
@@ -264,8 +264,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
264
264
struct btrfs_key key ;
265
265
size_t datasize ;
266
266
267
- key .objectid = btrfs_ino (BTRFS_I ( inode ) );
268
- key .offset = start ;
267
+ key .objectid = btrfs_ino (inode );
268
+ key .offset = 0 ;
269
269
key .type = BTRFS_EXTENT_DATA_KEY ;
270
270
271
271
datasize = btrfs_file_extent_calc_inline_size (cur_size );
@@ -303,12 +303,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
303
303
btrfs_set_file_extent_compression (leaf , ei ,
304
304
compress_type );
305
305
} else {
306
- page = find_get_page (inode -> i_mapping ,
307
- start >> PAGE_SHIFT );
306
+ page = find_get_page (inode -> vfs_inode .i_mapping , 0 );
308
307
btrfs_set_file_extent_compression (leaf , ei , 0 );
309
308
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 );
312
310
kunmap_atomic (kaddr );
313
311
put_page (page );
314
312
}
@@ -319,8 +317,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
319
317
* We align size to sectorsize for inline extents just for simplicity
320
318
* sake.
321
319
*/
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 ) );
324
322
if (ret )
325
323
goto fail ;
326
324
@@ -333,7 +331,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
333
331
* before we unlock the pages. Otherwise we
334
332
* could end up racing with unlink.
335
333
*/
336
- BTRFS_I (inode )-> disk_i_size = inode -> i_size ;
334
+ inode -> disk_i_size = i_size_read (& inode -> vfs_inode );
335
+
337
336
fail :
338
337
return ret ;
339
338
}
@@ -344,35 +343,30 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
344
343
* does the checks required to make sure the data is small enough
345
344
* to fit as an inline extent.
346
345
*/
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 ,
349
348
int compress_type ,
350
349
struct page * * compressed_pages )
351
350
{
352
351
struct btrfs_drop_extents_args drop_args = { 0 };
353
352
struct btrfs_root * root = inode -> root ;
354
353
struct btrfs_fs_info * fs_info = root -> fs_info ;
355
354
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 );
361
356
int ret ;
362
357
struct btrfs_path * path ;
363
358
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 ||
369
367
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 )
374
369
return 1 ;
375
- }
376
370
377
371
path = btrfs_alloc_path ();
378
372
if (!path )
@@ -386,30 +380,20 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
386
380
trans -> block_rsv = & inode -> block_rsv ;
387
381
388
382
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 ;
391
385
drop_args .drop_cache = true;
392
386
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 );
401
388
ret = btrfs_drop_extents (trans , root , inode , & drop_args );
402
389
if (ret ) {
403
390
btrfs_abort_transaction (trans , ret );
404
391
goto out ;
405
392
}
406
393
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 );
413
397
if (ret && ret != - ENOSPC ) {
414
398
btrfs_abort_transaction (trans , ret );
415
399
goto out ;
@@ -418,7 +402,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
418
402
goto out ;
419
403
}
420
404
421
- btrfs_update_inode_bytes (inode , inline_len , drop_args .bytes_found );
405
+ btrfs_update_inode_bytes (inode , size , drop_args .bytes_found );
422
406
ret = btrfs_update_inode (trans , root , inode );
423
407
if (ret && ret != - ENOSPC ) {
424
408
btrfs_abort_transaction (trans , ret );
@@ -739,12 +723,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
739
723
/* we didn't compress the entire range, try
740
724
* to make an uncompressed inline extent.
741
725
*/
742
- ret = cow_file_range_inline (BTRFS_I (inode ), start , end ,
726
+ ret = cow_file_range_inline (BTRFS_I (inode ), actual_end ,
743
727
0 , BTRFS_COMPRESS_NONE ,
744
728
NULL );
745
729
} else {
746
730
/* 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 ,
748
732
total_compressed ,
749
733
compress_type , pages );
750
734
}
@@ -1159,8 +1143,11 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
1159
1143
* So here we skip inline extent creation completely.
1160
1144
*/
1161
1145
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
+
1162
1149
/* 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 ,
1164
1151
BTRFS_COMPRESS_NONE , NULL );
1165
1152
if (ret == 0 ) {
1166
1153
/*
0 commit comments