Skip to content

Commit bacde33

Browse files
committed
Linux: dbuf_undirty should work with uint64_t txg
RIP: 0010:dbuf_undirty+0x19/0x820 [zfs] Call Trace: <TASK> ? __die+0x1f/0x60 ? page_fault_oops+0x17d/0x550 ? zfs_btree_add_idx+0xa4/0x340 [zfs] ? exc_page_fault+0x67/0x140 ? asm_exc_page_fault+0x22/0x30 ? dbuf_undirty+0x19/0x820 [zfs] ? kfree+0x27c/0x310 ? spl_kmem_cache_free+0x12e/0x270 [spl] dmu_write_direct_done+0x126/0x310 [zfs] zio_done+0x2df/0x21e0 [zfs] zio_execute+0xd7/0x290 [zfs] taskq_thread+0x350/0x880 [spl] ? __pfx_default_wake_function+0x10/0x10 ? __pfx_zio_execute+0x10/0x10 [zfs] ? __pfx_taskq_thread+0x10/0x10 [spl] kthread+0xc9/0x100 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2d/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Signed-off-by: Pavel Snajdr <[email protected]>
1 parent 035947a commit bacde33

File tree

7 files changed

+17
-16
lines changed

7 files changed

+17
-16
lines changed

include/sys/brt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extern void brt_init(void);
4848
extern void brt_fini(void);
4949

5050
extern void brt_pending_add(spa_t *spa, const blkptr_t *bp, dmu_tx_t *tx);
51-
extern void brt_pending_remove(spa_t *spa, const blkptr_t *bp, dmu_tx_t *tx);
51+
extern void brt_pending_remove(spa_t *spa, const blkptr_t *bp, uint64_t txg);
5252
extern void brt_pending_apply(spa_t *spa, uint64_t txg);
5353

5454
extern void brt_create(spa_t *spa);

include/sys/dbuf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
388388
dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
389389
dbuf_dirty_record_t *dbuf_dirty_lightweight(dnode_t *dn, uint64_t blkid,
390390
dmu_tx_t *tx);
391-
boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
391+
boolean_t dbuf_undirty(dmu_buf_impl_t *db, uint64_t txg);
392392
int dmu_buf_get_bp_from_dbuf(dmu_buf_impl_t *db, blkptr_t **bp);
393393
int dmu_buf_untransform_direct(dmu_buf_impl_t *db, spa_t *spa);
394394
arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);

include/sys/dmu_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ typedef struct {
259259
dbuf_dirty_record_t *dsa_dr;
260260
void (*dsa_done)(struct zgd *, int);
261261
struct zgd *dsa_zgd;
262+
uint64_t dsa_txg;
262263
dmu_tx_t *dsa_tx;
263264
} dmu_sync_arg_t;
264265

module/zfs/brt.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,16 +1421,14 @@ brt_pending_add(spa_t *spa, const blkptr_t *bp, dmu_tx_t *tx)
14211421
}
14221422

14231423
void
1424-
brt_pending_remove(spa_t *spa, const blkptr_t *bp, dmu_tx_t *tx)
1424+
brt_pending_remove(spa_t *spa, const blkptr_t *bp, uint64_t txg)
14251425
{
14261426
brt_t *brt;
14271427
avl_tree_t *pending_tree;
14281428
kmutex_t *pending_lock;
14291429
brt_pending_entry_t *bpe, bpe_search;
1430-
uint64_t txg;
14311430

14321431
brt = spa->spa_brt;
1433-
txg = dmu_tx_get_txg(tx);
14341432
ASSERT3U(txg, !=, 0);
14351433
pending_tree = &brt->brt_pending_tree[txg & TXG_MASK];
14361434
pending_lock = &brt->brt_pending_lock[txg & TXG_MASK];

module/zfs/dbuf.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,7 +2006,7 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
20062006

20072007
/* found a level 0 buffer in the range */
20082008
mutex_enter(&db->db_mtx);
2009-
if (dbuf_undirty(db, tx)) {
2009+
if (dbuf_undirty(db, tx->tx_txg)) {
20102010
/* mutex has been dropped and dbuf destroyed */
20112011
continue;
20122012
}
@@ -2536,9 +2536,8 @@ dbuf_undirty_bonus(dbuf_dirty_record_t *dr)
25362536
* transaction. Return whether this evicted the dbuf.
25372537
*/
25382538
boolean_t
2539-
dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
2539+
dbuf_undirty(dmu_buf_impl_t *db, uint64_t txg)
25402540
{
2541-
uint64_t txg = tx->tx_txg;
25422541
boolean_t brtwrite;
25432542
boolean_t diowrite;
25442543

@@ -2574,7 +2573,7 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
25742573
* transaction group.
25752574
*/
25762575
brt_pending_remove(dmu_objset_spa(db->db_objset),
2577-
&dr->dt.dl.dr_overridden_by, tx);
2576+
&dr->dt.dl.dr_overridden_by, txg);
25782577
}
25792578

25802579
dnode_t *dn = dr->dr_dnode;
@@ -2687,7 +2686,7 @@ dmu_buf_will_dirty_impl(dmu_buf_t *db_fake, int flags, dmu_tx_t *tx)
26872686
(void) dbuf_read(db, NULL, flags);
26882687
if (undirty) {
26892688
mutex_enter(&db->db_mtx);
2690-
VERIFY(!dbuf_undirty(db, tx));
2689+
VERIFY(!dbuf_undirty(db, tx->tx_txg));
26912690
mutex_exit(&db->db_mtx);
26922691
}
26932692
(void) dbuf_dirty(db, tx);
@@ -2829,7 +2828,7 @@ dmu_buf_will_clone_or_dio(dmu_buf_t *db_fake, dmu_tx_t *tx)
28292828
* hold on the db, so it should never be evicted after calling
28302829
* dbuf_undirty().
28312830
*/
2832-
VERIFY3B(dbuf_undirty(db, tx), ==, B_FALSE);
2831+
VERIFY3B(dbuf_undirty(db, tx->tx_txg), ==, B_FALSE);
28332832
ASSERT0P(dbuf_find_dirty_eq(db, tx->tx_txg));
28342833

28352834
if (db->db_buf != NULL) {
@@ -2912,7 +2911,7 @@ dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx, boolean_t canfail)
29122911
* as if the clone was never done.
29132912
*/
29142913
if (dr && dr->dt.dl.dr_brtwrite) {
2915-
VERIFY(!dbuf_undirty(db, tx));
2914+
VERIFY(!dbuf_undirty(db, tx->tx_txg));
29162915
db->db_state = DB_UNCACHED;
29172916
}
29182917
}
@@ -2993,7 +2992,7 @@ dmu_buf_fill_done(dmu_buf_t *dbuf, dmu_tx_t *tx, boolean_t failed)
29932992
"fill done handling freed in flight");
29942993
failed = B_FALSE;
29952994
} else if (failed) {
2996-
VERIFY(!dbuf_undirty(db, tx));
2995+
VERIFY(!dbuf_undirty(db, tx->tx_txg));
29972996
arc_buf_destroy(db->db_buf, db);
29982997
db->db_buf = NULL;
29992998
dbuf_clear_data(db);
@@ -3144,7 +3143,7 @@ dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx)
31443143
* pending clone and mark the block as uncached. This will be
31453144
* as if the clone was never done.
31463145
*/
3147-
VERIFY(!dbuf_undirty(db, tx));
3146+
VERIFY(!dbuf_undirty(db, tx->tx_txg));
31483147
db->db_state = DB_UNCACHED;
31493148
}
31503149
ASSERT(db->db_buf == NULL);

module/zfs/dmu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,7 @@ dmu_sync_late_arrival(zio_t *pio, objset_t *os, dmu_sync_cb_t *done, zgd_t *zgd,
20072007
dsa->dsa_dr = NULL;
20082008
dsa->dsa_done = done;
20092009
dsa->dsa_zgd = zgd;
2010+
dsa->dsa_txg = tx->tx_txg;
20102011
dsa->dsa_tx = tx;
20112012

20122013
/*
@@ -2198,6 +2199,7 @@ dmu_sync(zio_t *pio, uint64_t txg, dmu_sync_cb_t *done, zgd_t *zgd)
21982199
dsa->dsa_dr = dr;
21992200
dsa->dsa_done = done;
22002201
dsa->dsa_zgd = zgd;
2202+
dsa->dsa_txg = 0;
22012203
dsa->dsa_tx = NULL;
22022204

22032205
zio_nowait(arc_write(pio, os->os_spa, txg, zgd->zgd_bp,

module/zfs/dmu_direct.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ dmu_write_direct_done(zio_t *zio)
119119
* calling dbuf_undirty().
120120
*/
121121
mutex_enter(&db->db_mtx);
122-
VERIFY3B(dbuf_undirty(db, dsa->dsa_tx), ==, B_FALSE);
122+
VERIFY3B(dbuf_undirty(db, dsa->dsa_txg), ==, B_FALSE);
123123
mutex_exit(&db->db_mtx);
124124
}
125125

@@ -189,7 +189,8 @@ dmu_write_direct(zio_t *pio, dmu_buf_impl_t *db, abd_t *data, dmu_tx_t *tx)
189189

190190
dmu_sync_arg_t *dsa = kmem_zalloc(sizeof (dmu_sync_arg_t), KM_SLEEP);
191191
dsa->dsa_dr = dr_head;
192-
dsa->dsa_tx = tx;
192+
dsa->dsa_txg = tx->tx_txg;
193+
dsa->dsa_tx = NULL;
193194

194195
zio_t *zio = zio_write(pio, os->os_spa, txg, bp, data,
195196
db->db.db_size, db->db.db_size, &zp,

0 commit comments

Comments
 (0)