@@ -1255,16 +1255,6 @@ dbuf_set_data(dmu_buf_impl_t *db, arc_buf_t *buf)
1255
1255
ASSERT (buf != NULL );
1256
1256
1257
1257
db -> db_buf = buf ;
1258
-
1259
- /*
1260
- * If there is a Direct I/O, set its data too. Then its state
1261
- * will be the same as if we did a ZIL dmu_sync().
1262
- */
1263
- dbuf_dirty_record_t * dr = list_head (& db -> db_dirty_records );
1264
- if (dbuf_dirty_is_direct_write (db , dr )) {
1265
- dr -> dt .dl .dr_data = db -> db_buf ;
1266
- }
1267
-
1268
1258
ASSERT (buf -> b_data != NULL );
1269
1259
db -> db .db_data = buf -> b_data ;
1270
1260
}
@@ -1843,7 +1833,7 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *pio, uint32_t flags)
1843
1833
/*
1844
1834
* If a block clone or Direct I/O write has occurred we will
1845
1835
* get the dirty records overridden BP so we get the most
1846
- * recent data..
1836
+ * recent data.
1847
1837
*/
1848
1838
err = dmu_buf_get_bp_from_dbuf (db , & bp );
1849
1839
@@ -1948,13 +1938,14 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
1948
1938
if (!BP_IS_HOLE (bp ) && !dr -> dt .dl .dr_nopwrite )
1949
1939
zio_free (db -> db_objset -> os_spa , txg , bp );
1950
1940
1951
- if (dr -> dt .dl .dr_brtwrite ) {
1941
+ if (dr -> dt .dl .dr_brtwrite || dr -> dt . dl . dr_diowrite ) {
1952
1942
ASSERT0P (dr -> dt .dl .dr_data );
1953
1943
dr -> dt .dl .dr_data = db -> db_buf ;
1954
1944
}
1955
1945
dr -> dt .dl .dr_override_state = DR_NOT_OVERRIDDEN ;
1956
1946
dr -> dt .dl .dr_nopwrite = B_FALSE ;
1957
1947
dr -> dt .dl .dr_brtwrite = B_FALSE ;
1948
+ dr -> dt .dl .dr_diowrite = B_FALSE ;
1958
1949
dr -> dt .dl .dr_has_raw_params = B_FALSE ;
1959
1950
1960
1951
/*
@@ -2161,26 +2152,11 @@ dbuf_redirty(dbuf_dirty_record_t *dr)
2161
2152
*/
2162
2153
dbuf_unoverride (dr );
2163
2154
if (db -> db .db_object != DMU_META_DNODE_OBJECT &&
2164
- db -> db_state != DB_NOFILL && db -> db_buf != NULL ) {
2165
- /*
2166
- * Already released on initial dirty,
2167
- * so just thaw.
2168
- */
2155
+ db -> db_state != DB_NOFILL ) {
2156
+ /* Already released on initial dirty, so just thaw. */
2169
2157
ASSERT (arc_released (db -> db_buf ));
2170
2158
arc_buf_thaw (db -> db_buf );
2171
2159
}
2172
- /*
2173
- * If initial dirty was via Direct I/O, may not have a dr_data.
2174
- *
2175
- * If the dirty record was associated with cloned block then
2176
- * the call above to dbuf_unoverride() will have reset
2177
- * dr->dt.dl.dr_data and it will not be NULL here.
2178
- */
2179
- if (dr -> dt .dl .dr_data == NULL ) {
2180
- ASSERT3B (dbuf_dirty_is_direct_write (db , dr ), = = ,
2181
- B_TRUE );
2182
- dr -> dt .dl .dr_data = db -> db_buf ;
2183
- }
2184
2160
}
2185
2161
}
2186
2162
@@ -2564,6 +2540,7 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
2564
2540
{
2565
2541
uint64_t txg = tx -> tx_txg ;
2566
2542
boolean_t brtwrite ;
2543
+ boolean_t diowrite ;
2567
2544
2568
2545
ASSERT (txg != 0 );
2569
2546
@@ -2589,7 +2566,9 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
2589
2566
ASSERT (dr -> dr_dbuf == db );
2590
2567
2591
2568
brtwrite = dr -> dt .dl .dr_brtwrite ;
2569
+ diowrite = dr -> dt .dl .dr_diowrite ;
2592
2570
if (brtwrite ) {
2571
+ ASSERT3B (diowrite , = = , B_FALSE );
2593
2572
/*
2594
2573
* We are freeing a block that we cloned in the same
2595
2574
* transaction group.
@@ -2630,11 +2609,7 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
2630
2609
if (db -> db_state != DB_NOFILL && !brtwrite ) {
2631
2610
dbuf_unoverride (dr );
2632
2611
2633
- /*
2634
- * In the Direct I/O case, the buffer is still dirty, but it
2635
- * may be UNCACHED, so we do not need to destroy an ARC buffer.
2636
- */
2637
- if (dr -> dt .dl .dr_data && dr -> dt .dl .dr_data != db -> db_buf ) {
2612
+ if (dr -> dt .dl .dr_data != db -> db_buf ) {
2638
2613
ASSERT (db -> db_buf != NULL );
2639
2614
ASSERT (dr -> dt .dl .dr_data != NULL );
2640
2615
arc_buf_destroy (dr -> dt .dl .dr_data , db );
@@ -2647,12 +2622,8 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
2647
2622
db -> db_dirtycnt -= 1 ;
2648
2623
2649
2624
if (zfs_refcount_remove (& db -> db_holds , (void * )(uintptr_t )txg ) == 0 ) {
2650
- /*
2651
- * In the Direct I/O case our db_buf will be NULL as we are not
2652
- * caching in the ARC.
2653
- */
2654
- ASSERT (db -> db_state == DB_NOFILL || brtwrite ||
2655
- db -> db_buf == NULL || arc_released (db -> db_buf ));
2625
+ ASSERT (db -> db_state == DB_NOFILL || brtwrite || diowrite ||
2626
+ arc_released (db -> db_buf ));
2656
2627
dbuf_destroy (db );
2657
2628
return (B_TRUE );
2658
2629
}
@@ -2711,8 +2682,7 @@ dmu_buf_will_dirty_impl(dmu_buf_t *db_fake, int flags, dmu_tx_t *tx)
2711
2682
* Block cloning: Do the dbuf_read() before undirtying the dbuf, as we
2712
2683
* want to make sure dbuf_read() will read the pending cloned block and
2713
2684
* not the uderlying block that is being replaced. dbuf_undirty() will
2714
- * do dbuf_unoverride(), so we will end up with cloned block content,
2715
- * without overridden BP.
2685
+ * do brt_pending_remove() before removing the dirty record.
2716
2686
*/
2717
2687
(void ) dbuf_read (db , NULL , flags );
2718
2688
if (undirty ) {
@@ -2761,19 +2731,16 @@ dmu_buf_get_bp_from_dbuf(dmu_buf_impl_t *db, blkptr_t **bp)
2761
2731
2762
2732
* bp = db -> db_blkptr ;
2763
2733
dbuf_dirty_record_t * dr = list_head (& db -> db_dirty_records );
2764
- if (dr ) {
2765
- if (db -> db_state == DB_NOFILL ) {
2766
- /* Block clone */
2767
- if (!dr -> dt .dl .dr_brtwrite )
2768
- error = EIO ;
2769
- else
2770
- * bp = & dr -> dt .dl .dr_overridden_by ;
2771
- } else if (dr -> dt .dl .dr_override_state == DR_OVERRIDDEN &&
2772
- dr -> dt .dl .dr_data == NULL ) {
2773
- ASSERT (db -> db_state == DB_UNCACHED );
2774
- /* Direct I/O write */
2734
+ if (dr && db -> db_state == DB_NOFILL ) {
2735
+ /* Block clone */
2736
+ if (!dr -> dt .dl .dr_brtwrite )
2737
+ error = EIO ;
2738
+ else
2739
+ * bp = & dr -> dt .dl .dr_overridden_by ;
2740
+ } else if (dr && db -> db_state == DB_UNCACHED ) {
2741
+ /* Direct I/O write */
2742
+ if (dr -> dt .dl .dr_diowrite )
2775
2743
* bp = & dr -> dt .dl .dr_overridden_by ;
2776
- }
2777
2744
}
2778
2745
2779
2746
return (error );
@@ -2929,21 +2896,28 @@ dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx, boolean_t canfail)
2929
2896
dmu_tx_private_ok (tx ));
2930
2897
2931
2898
mutex_enter (& db -> db_mtx );
2932
- if (db -> db_state == DB_NOFILL ) {
2899
+ dbuf_dirty_record_t * dr = dbuf_find_dirty_eq (db , tx -> tx_txg );
2900
+ if (db -> db_state == DB_NOFILL ||
2901
+ (db -> db_state == DB_UNCACHED && dr && dr -> dt .dl .dr_diowrite )) {
2933
2902
/*
2934
- * Block cloning: We will be completely overwriting a block
2935
- * cloned in this transaction group, so let's undirty the
2936
- * pending clone and mark the block as uncached. This will be
2937
- * as if the clone was never done. But if the fill can fail
2938
- * we should have a way to return back to the cloned data.
2903
+ * If the fill can fail we should have a way to return back to
2904
+ * the cloned or Direct I/O write data.
2939
2905
*/
2940
- if (canfail && dbuf_find_dirty_eq ( db , tx -> tx_txg ) != NULL ) {
2906
+ if (canfail && dr ) {
2941
2907
mutex_exit (& db -> db_mtx );
2942
2908
dmu_buf_will_dirty (db_fake , tx );
2943
2909
return ;
2944
2910
}
2945
- VERIFY (!dbuf_undirty (db , tx ));
2946
- db -> db_state = DB_UNCACHED ;
2911
+ /*
2912
+ * Block cloning: We will be completely overwriting a block
2913
+ * cloned in this transaction group, so let's undirty the
2914
+ * pending clone and mark the block as uncached. This will be
2915
+ * as if the clone was never done.
2916
+ */
2917
+ if (dr && dr -> dt .dl .dr_brtwrite ) {
2918
+ VERIFY (!dbuf_undirty (db , tx ));
2919
+ db -> db_state = DB_UNCACHED ;
2920
+ }
2947
2921
}
2948
2922
mutex_exit (& db -> db_mtx );
2949
2923
@@ -5085,6 +5059,7 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
5085
5059
if (dr -> dt .dl .dr_data != NULL &&
5086
5060
dr -> dt .dl .dr_data != db -> db_buf ) {
5087
5061
ASSERT3B (dr -> dt .dl .dr_brtwrite , = = , B_FALSE );
5062
+ ASSERT3B (dr -> dt .dl .dr_diowrite , = = , B_FALSE );
5088
5063
arc_buf_destroy (dr -> dt .dl .dr_data , db );
5089
5064
}
5090
5065
} else {
@@ -5146,9 +5121,7 @@ dbuf_write_override_done(zio_t *zio)
5146
5121
if (!BP_EQUAL (zio -> io_bp , obp )) {
5147
5122
if (!BP_IS_HOLE (obp ))
5148
5123
dsl_free (spa_get_dsl (zio -> io_spa ), zio -> io_txg , obp );
5149
-
5150
- if (dr -> dt .dl .dr_data && dr -> dt .dl .dr_data != db -> db_buf )
5151
- arc_release (dr -> dt .dl .dr_data , db );
5124
+ arc_release (dr -> dt .dl .dr_data , db );
5152
5125
}
5153
5126
mutex_exit (& db -> db_mtx );
5154
5127
@@ -5355,14 +5328,8 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
5355
5328
* (by dmu_sync(), dmu_write_direct(),
5356
5329
* or dmu_buf_write_embedded()).
5357
5330
*/
5358
- blkptr_t * bp = & dr -> dt .dl .dr_overridden_by ;
5359
- abd_t * contents = NULL ;
5360
- if (data ) {
5361
- ASSERT (BP_IS_HOLE (bp ) ||
5362
- arc_buf_lsize (data ) == BP_GET_LSIZE (bp ));
5363
- contents = abd_get_from_buf (data -> b_data ,
5364
- arc_buf_size (data ));
5365
- }
5331
+ abd_t * contents = (data != NULL ) ?
5332
+ abd_get_from_buf (data -> b_data , arc_buf_size (data )) : NULL ;
5366
5333
5367
5334
dr -> dr_zio = zio_write (pio , os -> os_spa , txg , & dr -> dr_bp_copy ,
5368
5335
contents , db -> db .db_size , db -> db .db_size , & zp ,
@@ -5371,8 +5338,9 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
5371
5338
dr , ZIO_PRIORITY_ASYNC_WRITE , ZIO_FLAG_MUSTSUCCEED , & zb );
5372
5339
mutex_enter (& db -> db_mtx );
5373
5340
dr -> dt .dl .dr_override_state = DR_NOT_OVERRIDDEN ;
5374
- zio_write_override (dr -> dr_zio , bp , dr -> dt .dl .dr_copies ,
5375
- dr -> dt .dl .dr_nopwrite , dr -> dt .dl .dr_brtwrite );
5341
+ zio_write_override (dr -> dr_zio , & dr -> dt .dl .dr_overridden_by ,
5342
+ dr -> dt .dl .dr_copies , dr -> dt .dl .dr_nopwrite ,
5343
+ dr -> dt .dl .dr_brtwrite );
5376
5344
mutex_exit (& db -> db_mtx );
5377
5345
} else if (data == NULL ) {
5378
5346
ASSERT (zp .zp_checksum == ZIO_CHECKSUM_OFF ||
0 commit comments