Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/dmu.c @ 7385:f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
6734875 assertion failed: list_head(&osi->os_meta_dnode->dn_dbufs) == 0L
6728399 [f]truncate(2) to non-zero offset broken on ZFS for files < max-blocksize
6730750 pool shows disk space in used but no related files/dirs
6737329 dmu_offset_next() does not find holes
author | Mark Maybee <Mark.Maybee@Sun.COM> |
---|---|
date | Thu, 21 Aug 2008 14:27:33 -0600 |
parents | cdba25672122 |
children | 23915842aa09 |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dmu.c Thu Aug 21 11:46:39 2008 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu.c Thu Aug 21 14:27:33 2008 -0600 @@ -368,23 +368,24 @@ static int get_next_chunk(dnode_t *dn, uint64_t *offset, uint64_t limit) { - uint64_t len = limit - *offset; + uint64_t len = *offset - limit; uint64_t chunk_len = dn->dn_datablksz * DMU_MAX_DELETEBLKCNT; - uint64_t dn_used; - int err; + uint64_t subchunk = + dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT); ASSERT(limit <= *offset); - dn_used = dn->dn_phys->dn_used << - (dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES ? 0 : DEV_BSHIFT); - if (len <= chunk_len || dn_used <= chunk_len) { + if (len <= chunk_len) { *offset = limit; return (0); } + ASSERT(ISP2(subchunk)); + while (*offset > limit) { - uint64_t initial_offset = *offset; + uint64_t initial_offset = P2ROUNDUP(*offset, subchunk); uint64_t delta; + int err; /* skip over allocated data */ err = dnode_next_offset(dn, @@ -395,6 +396,7 @@ return (err); ASSERT3U(*offset, <=, initial_offset); + *offset = P2ALIGN(*offset, subchunk); delta = initial_offset - *offset; if (delta >= chunk_len) { *offset += delta - chunk_len; @@ -454,14 +456,15 @@ dnode_free_range(dn, start, trunc ? -1 : len, tx); - if (start == 0 && trunc && free_dnode) + if (start == 0 && free_dnode) { + ASSERT(trunc); dnode_free(dn, tx); + } length -= end - start; dmu_tx_commit(tx); end = start; - trunc = FALSE; } return (0); }