Skip to content

Commit

Permalink
Fix deadlocks resulting from the post-kmem rework merge
Browse files Browse the repository at this point in the history
Put the following functions under PF_FSTRANS to prevent deadlocks
due to re-entering the filesystem during reclaim:

	dbuf_hold()
	dmu_prefetch()
	sa_buf_hold()

Testing this one now:
	dmu_zfetch_fetch() - z_hold_mtx[] via zget and zf_rwlock via dmu_zfetch
  • Loading branch information
dweeezil committed Mar 24, 2015
1 parent 4c7b7ee commit fc43636
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 2 deletions.
7 changes: 6 additions & 1 deletion module/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,12 @@ dmu_buf_impl_t *
dbuf_hold(dnode_t *dn, uint64_t blkid, void *tag)
{
dmu_buf_impl_t *db;
int err = dbuf_hold_impl(dn, 0, blkid, FALSE, tag, &db);
int err;
fstrans_cookie_t cookie;

cookie = spl_fstrans_mark();
err = dbuf_hold_impl(dn, 0, blkid, FALSE, tag, &db);
spl_fstrans_unmark(cookie);
return (err ? NULL : db);
}

Expand Down
6 changes: 6 additions & 0 deletions module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,14 +541,17 @@ dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset, uint64_t len)
return;

if (len == 0) { /* they're interested in the bonus buffer */
fstrans_cookie_t cookie;
dn = DMU_META_DNODE(os);

if (object == 0 || object >= DN_MAX_OBJECT)
return;

rw_enter(&dn->dn_struct_rwlock, RW_READER);
blkid = dbuf_whichblock(dn, object * sizeof (dnode_phys_t));
cookie = spl_fstrans_mark();
dbuf_prefetch(dn, blkid, ZIO_PRIORITY_SYNC_READ);
spl_fstrans_unmark(cookie);
rw_exit(&dn->dn_struct_rwlock);
return;
}
Expand All @@ -573,10 +576,13 @@ dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset, uint64_t len)

if (nblks != 0) {
int i;
fstrans_cookie_t cookie;

blkid = dbuf_whichblock(dn, offset);
cookie = spl_fstrans_mark();
for (i = 0; i < nblks; i++)
dbuf_prefetch(dn, blkid + i, ZIO_PRIORITY_SYNC_READ);
spl_fstrans_unmark(cookie);
}

rw_exit(&dn->dn_struct_rwlock);
Expand Down
3 changes: 3 additions & 0 deletions module/zfs/dmu_zfetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,15 @@ dmu_zfetch_fetch(dnode_t *dn, uint64_t blkid, uint64_t nblks)
{
uint64_t fetchsz;
uint64_t i;
fstrans_cookie_t cookie;

fetchsz = dmu_zfetch_fetchsz(dn, blkid, nblks);

cookie = spl_fstrans_mark();
for (i = 0; i < fetchsz; i++) {
dbuf_prefetch(dn, blkid + i, ZIO_PRIORITY_ASYNC_READ);
}
spl_fstrans_unmark(cookie);

return (fetchsz);
}
Expand Down
8 changes: 7 additions & 1 deletion module/zfs/sa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,13 @@ sa_handle_get(objset_t *objset, uint64_t objid, void *userp,
int
sa_buf_hold(objset_t *objset, uint64_t obj_num, void *tag, dmu_buf_t **db)
{
return (dmu_bonus_hold(objset, obj_num, tag, db));
fstrans_cookie_t cookie;
int rval;

cookie = spl_fstrans_mark();
rval = (dmu_bonus_hold(objset, obj_num, tag, db));
spl_fstrans_unmark(cookie);
return (rval);
}

void
Expand Down

0 comments on commit fc43636

Please sign in to comment.