diff options
author | maybee <none@none> | 2008-07-07 15:54:05 -0700 |
---|---|---|
committer | maybee <none@none> | 2008-07-07 15:54:05 -0700 |
commit | 56d55a5391b4507b679f3d8e08cc28fbe2be62b9 (patch) | |
tree | 16912427760c7b2069095c69f8f72b415ecdec01 /usr/src/uts/common/fs/zfs/dnode.c | |
parent | a6968364ab2a8da17f9f80644b1ff26b9093ef32 (diff) | |
download | illumos-gate-56d55a5391b4507b679f3d8e08cc28fbe2be62b9.tar.gz |
6723124 Assertion failed: all || blocks_freed == 0 || db->db_last_dirty
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dnode.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/dnode.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/usr/src/uts/common/fs/zfs/dnode.c b/usr/src/uts/common/fs/zfs/dnode.c index 848560ea51..cc6dbeaaa7 100644 --- a/usr/src/uts/common/fs/zfs/dnode.c +++ b/usr/src/uts/common/fs/zfs/dnode.c @@ -1078,24 +1078,34 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) /* * Read in and mark all the level-1 indirects dirty, * so that they will stay in memory until syncing phase. + * Always dirty the first and last indirect to make sure + * we dirty all the partial indirects. */ if (dn->dn_nlevels > 1) { uint64_t i, first, last; int shift = epbs + dn->dn_datablkshift; first = blkid >> epbs; + if (db = dbuf_hold_level(dn, 1, first, FTAG)) { + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } if (trunc) last = dn->dn_maxblkid >> epbs; else last = (blkid + nblks - 1) >> epbs; - for (i = first; i <= last; i++) { + if (last > first && (db = dbuf_hold_level(dn, 1, last, FTAG))) { + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } + for (i = first + 1; i < last; i++) { uint64_t ibyte = i << shift; int err; err = dnode_next_offset(dn, DNODE_FIND_HAVELOCK, &ibyte, 1, 1, 0); i = ibyte >> shift; - if (err == ESRCH || i > last) + if (err == ESRCH || i >= last) break; ASSERT(err == 0); db = dbuf_hold_level(dn, 1, i, FTAG); |