@@ -4360,47 +4360,11 @@ static int truncate_space_check(struct btrfs_trans_handle *trans,
4360
4360
4361
4361
}
4362
4362
4363
- static int truncate_inline_extent (struct inode * inode ,
4364
- struct btrfs_path * path ,
4365
- struct btrfs_key * found_key ,
4366
- const u64 item_end ,
4367
- const u64 new_size )
4368
- {
4369
- struct extent_buffer * leaf = path -> nodes [0 ];
4370
- int slot = path -> slots [0 ];
4371
- struct btrfs_file_extent_item * fi ;
4372
- u32 size = (u32 )(new_size - found_key -> offset );
4373
- struct btrfs_root * root = BTRFS_I (inode )-> root ;
4374
-
4375
- fi = btrfs_item_ptr (leaf , slot , struct btrfs_file_extent_item );
4376
-
4377
- if (btrfs_file_extent_compression (leaf , fi ) != BTRFS_COMPRESS_NONE ) {
4378
- loff_t offset = new_size ;
4379
- loff_t page_end = ALIGN (offset , PAGE_SIZE );
4380
-
4381
- /*
4382
- * Zero out the remaining of the last page of our inline extent,
4383
- * instead of directly truncating our inline extent here - that
4384
- * would be much more complex (decompressing all the data, then
4385
- * compressing the truncated data, which might be bigger than
4386
- * the size of the inline extent, resize the extent, etc).
4387
- * We release the path because to get the page we might need to
4388
- * read the extent item from disk (data not in the page cache).
4389
- */
4390
- btrfs_release_path (path );
4391
- return btrfs_truncate_block (inode , offset , page_end - offset ,
4392
- 0 );
4393
- }
4394
-
4395
- btrfs_set_file_extent_ram_bytes (leaf , fi , size );
4396
- size = btrfs_file_extent_calc_inline_size (size );
4397
- btrfs_truncate_item (root -> fs_info , path , size , 1 );
4398
-
4399
- if (test_bit (BTRFS_ROOT_REF_COWS , & root -> state ))
4400
- inode_sub_bytes (inode , item_end + 1 - new_size );
4401
-
4402
- return 0 ;
4403
- }
4363
+ /*
4364
+ * Return this if we need to call truncate_block for the last bit of the
4365
+ * truncate.
4366
+ */
4367
+ #define NEED_TRUNCATE_BLOCK 1
4404
4368
4405
4369
/*
4406
4370
* this can truncate away extent items, csum items and directory items.
@@ -4561,11 +4525,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
4561
4525
if (found_type != BTRFS_EXTENT_DATA_KEY )
4562
4526
goto delete ;
4563
4527
4564
- if (del_item )
4565
- last_size = found_key .offset ;
4566
- else
4567
- last_size = new_size ;
4568
-
4569
4528
if (extent_type != BTRFS_FILE_EXTENT_INLINE ) {
4570
4529
u64 num_dec ;
4571
4530
extent_start = btrfs_file_extent_disk_bytenr (leaf , fi );
@@ -4607,40 +4566,30 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
4607
4566
*/
4608
4567
if (!del_item &&
4609
4568
btrfs_file_extent_encryption (leaf , fi ) == 0 &&
4610
- btrfs_file_extent_other_encoding (leaf , fi ) == 0 ) {
4611
-
4569
+ btrfs_file_extent_other_encoding (leaf , fi ) == 0 &&
4570
+ btrfs_file_extent_compression (leaf , fi ) == 0 ) {
4571
+ u32 size = (u32 )(new_size - found_key .offset );
4572
+
4573
+ btrfs_set_file_extent_ram_bytes (leaf , fi , size );
4574
+ size = btrfs_file_extent_calc_inline_size (size );
4575
+ btrfs_truncate_item (root -> fs_info , path , size , 1 );
4576
+ } else if (!del_item ) {
4612
4577
/*
4613
- * Need to release path in order to truncate a
4614
- * compressed extent. So delete any accumulated
4615
- * extent items so far.
4578
+ * We have to bail so the last_size is set to
4579
+ * just before this extent.
4616
4580
*/
4617
- if (btrfs_file_extent_compression (leaf , fi ) !=
4618
- BTRFS_COMPRESS_NONE && pending_del_nr ) {
4619
- err = btrfs_del_items (trans , root , path ,
4620
- pending_del_slot ,
4621
- pending_del_nr );
4622
- if (err ) {
4623
- btrfs_abort_transaction (trans ,
4624
- err );
4625
- goto error ;
4626
- }
4627
- pending_del_nr = 0 ;
4628
- }
4581
+ err = NEED_TRUNCATE_BLOCK ;
4582
+ break ;
4583
+ }
4629
4584
4630
- err = truncate_inline_extent (inode , path ,
4631
- & found_key ,
4632
- item_end ,
4633
- new_size );
4634
- if (err ) {
4635
- btrfs_abort_transaction (trans , err );
4636
- goto error ;
4637
- }
4638
- } else if (test_bit (BTRFS_ROOT_REF_COWS ,
4639
- & root -> state )) {
4585
+ if (test_bit (BTRFS_ROOT_REF_COWS , & root -> state ))
4640
4586
inode_sub_bytes (inode , item_end + 1 - new_size );
4641
- }
4642
4587
}
4643
4588
delete :
4589
+ if (del_item )
4590
+ last_size = found_key .offset ;
4591
+ else
4592
+ last_size = new_size ;
4644
4593
if (del_item ) {
4645
4594
if (!pending_del_nr ) {
4646
4595
/* no pending yet, add ourselves */
@@ -9338,12 +9287,12 @@ static int btrfs_truncate(struct inode *inode)
9338
9287
ret = btrfs_truncate_inode_items (trans , root , inode ,
9339
9288
inode -> i_size ,
9340
9289
BTRFS_EXTENT_DATA_KEY );
9290
+ trans -> block_rsv = & fs_info -> trans_block_rsv ;
9341
9291
if (ret != - ENOSPC && ret != - EAGAIN ) {
9342
9292
err = ret ;
9343
9293
break ;
9344
9294
}
9345
9295
9346
- trans -> block_rsv = & fs_info -> trans_block_rsv ;
9347
9296
ret = btrfs_update_inode (trans , root , inode );
9348
9297
if (ret ) {
9349
9298
err = ret ;
@@ -9367,6 +9316,27 @@ static int btrfs_truncate(struct inode *inode)
9367
9316
trans -> block_rsv = rsv ;
9368
9317
}
9369
9318
9319
+ /*
9320
+ * We can't call btrfs_truncate_block inside a trans handle as we could
9321
+ * deadlock with freeze, if we got NEED_TRUNCATE_BLOCK then we know
9322
+ * we've truncated everything except the last little bit, and can do
9323
+ * btrfs_truncate_block and then update the disk_i_size.
9324
+ */
9325
+ if (ret == NEED_TRUNCATE_BLOCK ) {
9326
+ btrfs_end_transaction (trans );
9327
+ btrfs_btree_balance_dirty (fs_info );
9328
+
9329
+ ret = btrfs_truncate_block (inode , inode -> i_size , 0 , 0 );
9330
+ if (ret )
9331
+ goto out ;
9332
+ trans = btrfs_start_transaction (root , 1 );
9333
+ if (IS_ERR (trans )) {
9334
+ ret = PTR_ERR (trans );
9335
+ goto out ;
9336
+ }
9337
+ btrfs_ordered_update_i_size (inode , inode -> i_size , NULL );
9338
+ }
9339
+
9370
9340
if (ret == 0 && inode -> i_nlink > 0 ) {
9371
9341
trans -> block_rsv = root -> orphan_block_rsv ;
9372
9342
ret = btrfs_orphan_del (trans , BTRFS_I (inode ));
0 commit comments