diff options
author | Gvozden Neskovic <[email protected]> | 2016-08-31 10:12:08 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-09-29 15:55:41 -0700 |
commit | 031d7c2fe6afaa78943bd0a563b91fc84ace42d7 (patch) | |
tree | e30c20bc233c680f997e8b11948988c7e97f1c83 /include/sys | |
parent | 0b78aeae927833de580e140375a15ea5ea9d924a (diff) |
fix: Shift exponent too large
Undefined operation is reported by running ztest (or zloop) compiled with GCC
UndefinedBehaviorSanitizer. Error only happens on top level of dnode indirection
with large enough offset values. Logically, left shift operation would work,
but bit shift semantics in C, and limitation of uint64_t, do not produce desired
result.
Issue #5059, #4883
Signed-off-by: Gvozden Neskovic <[email protected]>
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/dbuf.h | 3 | ||||
-rw-r--r-- | include/sys/dnode.h | 5 |
2 files changed, 4 insertions, 4 deletions
diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index bf546db6f..6262f012e 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -270,7 +270,8 @@ typedef struct dbuf_hash_table { kmutex_t hash_mutexes[DBUF_MUTEXES]; } dbuf_hash_table_t; -uint64_t dbuf_whichblock(struct dnode *di, int64_t level, uint64_t offset); +uint64_t dbuf_whichblock(const struct dnode *di, const int64_t level, + const uint64_t offset); void dbuf_create_bonus(struct dnode *dn); int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx); diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 7b4d7b9d3..fe36e5989 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -104,9 +104,8 @@ extern "C" { #define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) #define DNODES_PER_LEVEL (1ULL << DNODES_PER_LEVEL_SHIFT) -/* The +2 here is a cheesy way to round up */ -#define DN_MAX_LEVELS (2 + ((DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT) / \ - (DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT))) +#define DN_MAX_LEVELS (DIV_ROUND_UP(DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT, \ + DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT) + 1) #define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) |