@@ -1271,7 +1271,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1271
1271
u64 disk_num_bytes ;
1272
1272
u64 ram_bytes ;
1273
1273
int extent_type ;
1274
- int ret , err ;
1274
+ int ret ;
1275
1275
int type ;
1276
1276
int nocow ;
1277
1277
int check_prev = 1 ;
@@ -1403,11 +1403,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1403
1403
* if there are pending snapshots for this root,
1404
1404
* we fall into common COW way.
1405
1405
*/
1406
- if (!nolock ) {
1407
- err = btrfs_start_write_no_snapshotting (root );
1408
- if (!err )
1409
- goto out_check ;
1410
- }
1406
+ if (!nolock && atomic_read (& root -> snapshot_force_cow ))
1407
+ goto out_check ;
1411
1408
/*
1412
1409
* force cow if csum exists in the range.
1413
1410
* this ensure that csum for a given extent are
@@ -1416,9 +1413,6 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1416
1413
ret = csum_exist_in_range (fs_info , disk_bytenr ,
1417
1414
num_bytes );
1418
1415
if (ret ) {
1419
- if (!nolock )
1420
- btrfs_end_write_no_snapshotting (root );
1421
-
1422
1416
/*
1423
1417
* ret could be -EIO if the above fails to read
1424
1418
* metadata.
@@ -1431,11 +1425,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1431
1425
WARN_ON_ONCE (nolock );
1432
1426
goto out_check ;
1433
1427
}
1434
- if (!btrfs_inc_nocow_writers (fs_info , disk_bytenr )) {
1435
- if (!nolock )
1436
- btrfs_end_write_no_snapshotting (root );
1428
+ if (!btrfs_inc_nocow_writers (fs_info , disk_bytenr ))
1437
1429
goto out_check ;
1438
- }
1439
1430
nocow = 1 ;
1440
1431
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE ) {
1441
1432
extent_end = found_key .offset +
@@ -1448,8 +1439,6 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1448
1439
out_check :
1449
1440
if (extent_end <= start ) {
1450
1441
path -> slots [0 ]++ ;
1451
- if (!nolock && nocow )
1452
- btrfs_end_write_no_snapshotting (root );
1453
1442
if (nocow )
1454
1443
btrfs_dec_nocow_writers (fs_info , disk_bytenr );
1455
1444
goto next_slot ;
@@ -1471,8 +1460,6 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1471
1460
end , page_started , nr_written , 1 ,
1472
1461
NULL );
1473
1462
if (ret ) {
1474
- if (!nolock && nocow )
1475
- btrfs_end_write_no_snapshotting (root );
1476
1463
if (nocow )
1477
1464
btrfs_dec_nocow_writers (fs_info ,
1478
1465
disk_bytenr );
@@ -1492,8 +1479,6 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1492
1479
ram_bytes , BTRFS_COMPRESS_NONE ,
1493
1480
BTRFS_ORDERED_PREALLOC );
1494
1481
if (IS_ERR (em )) {
1495
- if (!nolock && nocow )
1496
- btrfs_end_write_no_snapshotting (root );
1497
1482
if (nocow )
1498
1483
btrfs_dec_nocow_writers (fs_info ,
1499
1484
disk_bytenr );
@@ -1532,8 +1517,6 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1532
1517
EXTENT_CLEAR_DATA_RESV ,
1533
1518
PAGE_UNLOCK | PAGE_SET_PRIVATE2 );
1534
1519
1535
- if (!nolock && nocow )
1536
- btrfs_end_write_no_snapshotting (root );
1537
1520
cur_offset = extent_end ;
1538
1521
1539
1522
/*
@@ -6639,6 +6622,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
6639
6622
drop_inode = 1 ;
6640
6623
} else {
6641
6624
struct dentry * parent = dentry -> d_parent ;
6625
+ int ret ;
6626
+
6642
6627
err = btrfs_update_inode (trans , root , inode );
6643
6628
if (err )
6644
6629
goto fail ;
@@ -6652,7 +6637,12 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
6652
6637
goto fail ;
6653
6638
}
6654
6639
d_instantiate (dentry , inode );
6655
- btrfs_log_new_name (trans , BTRFS_I (inode ), NULL , parent );
6640
+ ret = btrfs_log_new_name (trans , BTRFS_I (inode ), NULL , parent ,
6641
+ true, NULL );
6642
+ if (ret == BTRFS_NEED_TRANS_COMMIT ) {
6643
+ err = btrfs_commit_transaction (trans );
6644
+ trans = NULL ;
6645
+ }
6656
6646
}
6657
6647
6658
6648
fail :
@@ -9388,14 +9378,21 @@ static int btrfs_rename_exchange(struct inode *old_dir,
9388
9378
u64 new_idx = 0 ;
9389
9379
u64 root_objectid ;
9390
9380
int ret ;
9391
- int ret2 ;
9392
9381
bool root_log_pinned = false;
9393
9382
bool dest_log_pinned = false;
9383
+ struct btrfs_log_ctx ctx_root ;
9384
+ struct btrfs_log_ctx ctx_dest ;
9385
+ bool sync_log_root = false;
9386
+ bool sync_log_dest = false;
9387
+ bool commit_transaction = false;
9394
9388
9395
9389
/* we only allow rename subvolume link between subvolumes */
9396
9390
if (old_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest )
9397
9391
return - EXDEV ;
9398
9392
9393
+ btrfs_init_log_ctx (& ctx_root , old_inode );
9394
+ btrfs_init_log_ctx (& ctx_dest , new_inode );
9395
+
9399
9396
/* close the race window with snapshot create/destroy ioctl */
9400
9397
if (old_ino == BTRFS_FIRST_FREE_OBJECTID )
9401
9398
down_read (& fs_info -> subvol_sem );
@@ -9542,15 +9539,29 @@ static int btrfs_rename_exchange(struct inode *old_dir,
9542
9539
9543
9540
if (root_log_pinned ) {
9544
9541
parent = new_dentry -> d_parent ;
9545
- btrfs_log_new_name (trans , BTRFS_I (old_inode ), BTRFS_I (old_dir ),
9546
- parent );
9542
+ ret = btrfs_log_new_name (trans , BTRFS_I (old_inode ),
9543
+ BTRFS_I (old_dir ), parent ,
9544
+ false, & ctx_root );
9545
+ if (ret == BTRFS_NEED_LOG_SYNC )
9546
+ sync_log_root = true;
9547
+ else if (ret == BTRFS_NEED_TRANS_COMMIT )
9548
+ commit_transaction = true;
9549
+ ret = 0 ;
9547
9550
btrfs_end_log_trans (root );
9548
9551
root_log_pinned = false;
9549
9552
}
9550
9553
if (dest_log_pinned ) {
9551
- parent = old_dentry -> d_parent ;
9552
- btrfs_log_new_name (trans , BTRFS_I (new_inode ), BTRFS_I (new_dir ),
9553
- parent );
9554
+ if (!commit_transaction ) {
9555
+ parent = old_dentry -> d_parent ;
9556
+ ret = btrfs_log_new_name (trans , BTRFS_I (new_inode ),
9557
+ BTRFS_I (new_dir ), parent ,
9558
+ false, & ctx_dest );
9559
+ if (ret == BTRFS_NEED_LOG_SYNC )
9560
+ sync_log_dest = true;
9561
+ else if (ret == BTRFS_NEED_TRANS_COMMIT )
9562
+ commit_transaction = true;
9563
+ ret = 0 ;
9564
+ }
9554
9565
btrfs_end_log_trans (dest );
9555
9566
dest_log_pinned = false;
9556
9567
}
@@ -9583,8 +9594,26 @@ static int btrfs_rename_exchange(struct inode *old_dir,
9583
9594
dest_log_pinned = false;
9584
9595
}
9585
9596
}
9586
- ret2 = btrfs_end_transaction (trans );
9587
- ret = ret ? ret : ret2 ;
9597
+ if (!ret && sync_log_root && !commit_transaction ) {
9598
+ ret = btrfs_sync_log (trans , BTRFS_I (old_inode )-> root ,
9599
+ & ctx_root );
9600
+ if (ret )
9601
+ commit_transaction = true;
9602
+ }
9603
+ if (!ret && sync_log_dest && !commit_transaction ) {
9604
+ ret = btrfs_sync_log (trans , BTRFS_I (new_inode )-> root ,
9605
+ & ctx_dest );
9606
+ if (ret )
9607
+ commit_transaction = true;
9608
+ }
9609
+ if (commit_transaction ) {
9610
+ ret = btrfs_commit_transaction (trans );
9611
+ } else {
9612
+ int ret2 ;
9613
+
9614
+ ret2 = btrfs_end_transaction (trans );
9615
+ ret = ret ? ret : ret2 ;
9616
+ }
9588
9617
out_notrans :
9589
9618
if (new_ino == BTRFS_FIRST_FREE_OBJECTID )
9590
9619
up_read (& fs_info -> subvol_sem );
@@ -9661,6 +9690,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9661
9690
int ret ;
9662
9691
u64 old_ino = btrfs_ino (BTRFS_I (old_inode ));
9663
9692
bool log_pinned = false;
9693
+ struct btrfs_log_ctx ctx ;
9694
+ bool sync_log = false;
9695
+ bool commit_transaction = false;
9664
9696
9665
9697
if (btrfs_ino (BTRFS_I (new_dir )) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID )
9666
9698
return - EPERM ;
@@ -9818,8 +9850,15 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9818
9850
if (log_pinned ) {
9819
9851
struct dentry * parent = new_dentry -> d_parent ;
9820
9852
9821
- btrfs_log_new_name (trans , BTRFS_I (old_inode ), BTRFS_I (old_dir ),
9822
- parent );
9853
+ btrfs_init_log_ctx (& ctx , old_inode );
9854
+ ret = btrfs_log_new_name (trans , BTRFS_I (old_inode ),
9855
+ BTRFS_I (old_dir ), parent ,
9856
+ false, & ctx );
9857
+ if (ret == BTRFS_NEED_LOG_SYNC )
9858
+ sync_log = true;
9859
+ else if (ret == BTRFS_NEED_TRANS_COMMIT )
9860
+ commit_transaction = true;
9861
+ ret = 0 ;
9823
9862
btrfs_end_log_trans (root );
9824
9863
log_pinned = false;
9825
9864
}
@@ -9856,7 +9895,19 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9856
9895
btrfs_end_log_trans (root );
9857
9896
log_pinned = false;
9858
9897
}
9859
- btrfs_end_transaction (trans );
9898
+ if (!ret && sync_log ) {
9899
+ ret = btrfs_sync_log (trans , BTRFS_I (old_inode )-> root , & ctx );
9900
+ if (ret )
9901
+ commit_transaction = true;
9902
+ }
9903
+ if (commit_transaction ) {
9904
+ ret = btrfs_commit_transaction (trans );
9905
+ } else {
9906
+ int ret2 ;
9907
+
9908
+ ret2 = btrfs_end_transaction (trans );
9909
+ ret = ret ? ret : ret2 ;
9910
+ }
9860
9911
out_notrans :
9861
9912
if (old_ino == BTRFS_FIRST_FREE_OBJECTID )
9862
9913
up_read (& fs_info -> subvol_sem );
0 commit comments