diff --git a/include/sys/arc.h b/include/sys/arc.h index 6328392bee23..215c75b6dfa3 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -125,15 +125,15 @@ typedef struct arc_buf_info { void arc_space_consume(uint64_t space, arc_space_type_t type); void arc_space_return(uint64_t space, arc_space_type_t type); -arc_buf_t *arc_buf_alloc(spa_t *spa, int size, void *tag, +arc_buf_t *arc_buf_alloc(spa_t *spa, uint64_t size, void *tag, arc_buf_contents_t type); -arc_buf_t *arc_loan_buf(spa_t *spa, int size); +arc_buf_t *arc_loan_buf(spa_t *spa, uint64_t size); void arc_return_buf(arc_buf_t *buf, void *tag); void arc_loan_inuse_buf(arc_buf_t *buf, void *tag); void arc_buf_add_ref(arc_buf_t *buf, void *tag); boolean_t arc_buf_remove_ref(arc_buf_t *buf, void *tag); void arc_buf_info(arc_buf_t *buf, arc_buf_info_t *abi, int state_index); -int arc_buf_size(arc_buf_t *buf); +uint64_t arc_buf_size(arc_buf_t *buf); void arc_release(arc_buf_t *buf, void *tag); int arc_released(arc_buf_t *buf); void arc_buf_sigsegv(int sig, siginfo_t *si, void *unused); diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 2c7abe6ec542..408388aaff43 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -1434,12 +1434,12 @@ arc_space_return(uint64_t space, arc_space_type_t type) } arc_buf_t * -arc_buf_alloc(spa_t *spa, int size, void *tag, arc_buf_contents_t type) +arc_buf_alloc(spa_t *spa, uint64_t size, void *tag, arc_buf_contents_t type) { arc_buf_hdr_t *hdr; arc_buf_t *buf; - ASSERT3U(size, >, 0); + VERIFY3U(size, <=, SPA_MAXBLOCKSIZE); hdr = kmem_cache_alloc(hdr_cache, KM_PUSHPAGE); ASSERT(BUF_EMPTY(hdr)); hdr->b_size = size; @@ -1477,7 +1477,7 @@ static char *arc_onloan_tag = "onloan"; * freed. */ arc_buf_t * -arc_loan_buf(spa_t *spa, int size) +arc_loan_buf(spa_t *spa, uint64_t size) { arc_buf_t *buf; @@ -1837,7 +1837,7 @@ arc_buf_remove_ref(arc_buf_t *buf, void* tag) return (no_callback); } -int +uint64_t arc_buf_size(arc_buf_t *buf) { return (buf->b_hdr->b_size); @@ -3307,6 +3307,12 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, enum zio_compress b_compress = ZIO_COMPRESS_OFF; uint64_t b_asize = 0; + /* Gracefully handle a damaged logical block size. */ + if (size > SPA_MAXBLOCKSIZE) { + rc = ECKSUM; + goto out; + } + if (hdr == NULL) { /* this block is not in the cache */ arc_buf_hdr_t *exists = NULL;