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);
}
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;
* 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;
return (no_callback);
}
-int
+uint64_t
arc_buf_size(arc_buf_t *buf)
{
return (buf->b_hdr->b_size);
enum zio_compress b_compress = ZIO_COMPRESS_OFF;
uint64_t b_asize = 0;
+ /*
+ * Gracefully handle a damaged logical block size as a
+ * checksum error by passing a dummy zio to the done callback.
+ */
+ if (size > SPA_MAXBLOCKSIZE) {
+ if (done) {
+ rzio = zio_null(pio, spa, NULL,
+ NULL, NULL, zio_flags);
+ rzio->io_error = ECKSUM;
+ done(rzio, buf, private);
+ zio_nowait(rzio);
+ }
+ rc = ECKSUM;
+ goto out;
+ }
+
if (hdr == NULL) {
/* this block is not in the cache */
arc_buf_hdr_t *exists = NULL;
dbuf_rele_and_unlock(db, NULL);
}
-static void
+static int
dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags)
{
dnode_t *dn;
zbookmark_phys_t zb;
uint32_t aflags = ARC_NOWAIT;
+ int err;
DB_DNODE_ENTER(db);
dn = DB_DNODE(db);
dbuf_update_data(db);
db->db_state = DB_CACHED;
mutex_exit(&db->db_mtx);
- return;
+ return (0);
}
/*
db->db_state = DB_CACHED;
*flags |= DB_RF_CACHED;
mutex_exit(&db->db_mtx);
- return;
+ return (0);
}
DB_DNODE_EXIT(db);
dbuf_add_ref(db, NULL);
- (void) arc_read(zio, db->db_objset->os_spa, db->db_blkptr,
+ err = arc_read(zio, db->db_objset->os_spa, db->db_blkptr,
dbuf_read_done, db, ZIO_PRIORITY_SYNC_READ,
(*flags & DB_RF_CANFAIL) ? ZIO_FLAG_CANFAIL : ZIO_FLAG_MUSTSUCCEED,
&aflags, &zb);
if (aflags & ARC_CACHED)
*flags |= DB_RF_CACHED;
+
+ return (SET_ERROR(err));
}
int
if (zio == NULL)
zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL);
- dbuf_read_impl(db, zio, &flags);
+
+ err = dbuf_read_impl(db, zio, &flags);
/* dbuf_read_impl has dropped db_mtx for us */
- if (prefetch)
+ if (!err && prefetch)
dmu_zfetch(&dn->dn_zfetch, db->db.db_offset,
db->db.db_size, flags & DB_RF_CACHED);
rw_exit(&dn->dn_struct_rwlock);
DB_DNODE_EXIT(db);
- if (!havepzio)
+ if (!err && !havepzio)
err = zio_wait(zio);
} else {
/*