@@ -66,37 +66,46 @@ static void bkey_nocow_unlock(struct bch_fs *c, struct bkey_s_c k)
66
66
}
67
67
}
68
68
69
- static bool bkey_nocow_lock (struct bch_fs * c , struct moving_context * ctxt , struct bkey_s_c k )
69
+ static noinline_for_stack
70
+ bool __bkey_nocow_lock (struct bch_fs * c , struct moving_context * ctxt , struct bkey_ptrs_c ptrs ,
71
+ const struct bch_extent_ptr * start )
70
72
{
71
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (k );
73
+ if (!ctxt ) {
74
+ bkey_for_each_ptr (ptrs , ptr ) {
75
+ if (ptr == start )
76
+ break ;
77
+
78
+ struct bch_dev * ca = bch2_dev_have_ref (c , ptr -> dev );
79
+ struct bpos bucket = PTR_BUCKET_POS (ca , ptr );
80
+ bch2_bucket_nocow_unlock (& c -> nocow_locks , bucket , 0 );
81
+ }
82
+ return false;
83
+ }
72
84
85
+ __bkey_for_each_ptr (start , ptrs .end , ptr ) {
86
+ struct bch_dev * ca = bch2_dev_have_ref (c , ptr -> dev );
87
+ struct bpos bucket = PTR_BUCKET_POS (ca , ptr );
88
+
89
+ bool locked ;
90
+ move_ctxt_wait_event (ctxt ,
91
+ (locked = bch2_bucket_nocow_trylock (& c -> nocow_locks , bucket , 0 )) ||
92
+ list_empty (& ctxt -> ios ));
93
+ if (!locked )
94
+ bch2_bucket_nocow_lock (& c -> nocow_locks , bucket , 0 );
95
+ }
96
+ return true;
97
+ }
98
+
99
+ static bool bkey_nocow_lock (struct bch_fs * c , struct moving_context * ctxt , struct bkey_ptrs_c ptrs )
100
+ {
73
101
bkey_for_each_ptr (ptrs , ptr ) {
74
102
struct bch_dev * ca = bch2_dev_have_ref (c , ptr -> dev );
75
103
struct bpos bucket = PTR_BUCKET_POS (ca , ptr );
76
104
77
- if (ctxt ) {
78
- bool locked ;
79
-
80
- move_ctxt_wait_event (ctxt ,
81
- (locked = bch2_bucket_nocow_trylock (& c -> nocow_locks , bucket , 0 )) ||
82
- list_empty (& ctxt -> ios ));
83
-
84
- if (!locked )
85
- bch2_bucket_nocow_lock (& c -> nocow_locks , bucket , 0 );
86
- } else {
87
- if (!bch2_bucket_nocow_trylock (& c -> nocow_locks , bucket , 0 )) {
88
- bkey_for_each_ptr (ptrs , ptr2 ) {
89
- if (ptr2 == ptr )
90
- break ;
91
-
92
- ca = bch2_dev_have_ref (c , ptr2 -> dev );
93
- bucket = PTR_BUCKET_POS (ca , ptr2 );
94
- bch2_bucket_nocow_unlock (& c -> nocow_locks , bucket , 0 );
95
- }
96
- return false;
97
- }
98
- }
105
+ if (!bch2_bucket_nocow_trylock (& c -> nocow_locks , bucket , 0 ))
106
+ return __bkey_nocow_lock (c , ctxt , ptrs , ptr );
99
107
}
108
+
100
109
return true;
101
110
}
102
111
@@ -523,8 +532,9 @@ void bch2_data_update_exit(struct data_update *update)
523
532
bch2_bkey_buf_exit (& update -> k , c );
524
533
}
525
534
526
- static int bch2_update_unwritten_extent (struct btree_trans * trans ,
527
- struct data_update * update )
535
+ static noinline_for_stack
536
+ int bch2_update_unwritten_extent (struct btree_trans * trans ,
537
+ struct data_update * update )
528
538
{
529
539
struct bch_fs * c = update -> op .c ;
530
540
struct bkey_i_extent * e ;
@@ -716,18 +726,10 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
716
726
bch2_trans_commit (trans , NULL , NULL , BCH_TRANS_COMMIT_no_enospc );
717
727
}
718
728
719
- int bch2_data_update_bios_init (struct data_update * m , struct bch_fs * c ,
720
- struct bch_io_opts * io_opts )
729
+ static int __bch2_data_update_bios_init (struct data_update * m , struct bch_fs * c ,
730
+ struct bch_io_opts * io_opts ,
731
+ unsigned buf_bytes )
721
732
{
722
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (bkey_i_to_s_c (m -> k .k ));
723
- const union bch_extent_entry * entry ;
724
- struct extent_ptr_decoded p ;
725
-
726
- /* write path might have to decompress data: */
727
- unsigned buf_bytes = 0 ;
728
- bkey_for_each_ptr_decode (& m -> k .k -> k , ptrs , p , entry )
729
- buf_bytes = max_t (unsigned , buf_bytes , p .crc .uncompressed_size << 9 );
730
-
731
733
unsigned nr_vecs = DIV_ROUND_UP (buf_bytes , PAGE_SIZE );
732
734
733
735
m -> bvecs = kmalloc_array (nr_vecs , sizeof * (m -> bvecs ), GFP_KERNEL );
@@ -751,6 +753,21 @@ int bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
751
753
return 0 ;
752
754
}
753
755
756
+ int bch2_data_update_bios_init (struct data_update * m , struct bch_fs * c ,
757
+ struct bch_io_opts * io_opts )
758
+ {
759
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (bkey_i_to_s_c (m -> k .k ));
760
+ const union bch_extent_entry * entry ;
761
+ struct extent_ptr_decoded p ;
762
+
763
+ /* write path might have to decompress data: */
764
+ unsigned buf_bytes = 0 ;
765
+ bkey_for_each_ptr_decode (& m -> k .k -> k , ptrs , p , entry )
766
+ buf_bytes = max_t (unsigned , buf_bytes , p .crc .uncompressed_size << 9 );
767
+
768
+ return __bch2_data_update_bios_init (m , c , io_opts , buf_bytes );
769
+ }
770
+
754
771
static int can_write_extent (struct bch_fs * c , struct data_update * m )
755
772
{
756
773
if ((m -> op .flags & BCH_WRITE_alloc_nowait ) &&
@@ -802,10 +819,6 @@ int bch2_data_update_init(struct btree_trans *trans,
802
819
struct bkey_s_c k )
803
820
{
804
821
struct bch_fs * c = trans -> c ;
805
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (k );
806
- const union bch_extent_entry * entry ;
807
- struct extent_ptr_decoded p ;
808
- unsigned reserve_sectors = k .k -> size * data_opts .extra_replicas ;
809
822
int ret = 0 ;
810
823
811
824
/*
@@ -842,6 +855,13 @@ int bch2_data_update_init(struct btree_trans *trans,
842
855
843
856
unsigned durability_have = 0 , durability_removing = 0 ;
844
857
858
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (bkey_i_to_s_c (m -> k .k ));
859
+ const union bch_extent_entry * entry ;
860
+ struct extent_ptr_decoded p ;
861
+ unsigned reserve_sectors = k .k -> size * data_opts .extra_replicas ;
862
+ unsigned buf_bytes = 0 ;
863
+ bool unwritten = false;
864
+
845
865
unsigned ptr_bit = 1 ;
846
866
bkey_for_each_ptr_decode (k .k , ptrs , p , entry ) {
847
867
if (!p .ptr .cached ) {
@@ -872,6 +892,9 @@ int bch2_data_update_init(struct btree_trans *trans,
872
892
if (p .crc .compression_type == BCH_COMPRESSION_TYPE_incompressible )
873
893
m -> op .incompressible = true;
874
894
895
+ buf_bytes = max_t (unsigned , buf_bytes , p .crc .uncompressed_size << 9 );
896
+ unwritten |= p .ptr .unwritten ;
897
+
875
898
ptr_bit <<= 1 ;
876
899
}
877
900
@@ -946,18 +969,18 @@ int bch2_data_update_init(struct btree_trans *trans,
946
969
}
947
970
948
971
if (c -> opts .nocow_enabled &&
949
- !bkey_nocow_lock (c , ctxt , k )) {
972
+ !bkey_nocow_lock (c , ctxt , ptrs )) {
950
973
ret = - BCH_ERR_nocow_lock_blocked ;
951
974
goto out_put_dev_refs ;
952
975
}
953
976
954
- if (bkey_extent_is_unwritten ( k ) ) {
977
+ if (unwritten ) {
955
978
ret = bch2_update_unwritten_extent (trans , m ) ?:
956
979
- BCH_ERR_data_update_done_unwritten ;
957
980
goto out_nocow_unlock ;
958
981
}
959
982
960
- ret = bch2_data_update_bios_init (m , c , io_opts );
983
+ ret = __bch2_data_update_bios_init (m , c , io_opts , buf_bytes );
961
984
if (ret )
962
985
goto out_nocow_unlock ;
963
986
0 commit comments