diff options
author | delphij <delphij@FreeBSD.org> | 2014-07-15 04:53:34 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2014-07-15 04:53:34 +0000 |
commit | 9d1dc5bcc93f630c5fc480593d45fbcfebef15f2 (patch) | |
tree | 8bb48019ff1fadeaecb28e32888ab6093a430843 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c | |
parent | 5ed76404fecd3da81f3708db0259176767603aa5 (diff) | |
download | FreeBSD-src-9d1dc5bcc93f630c5fc480593d45fbcfebef15f2.zip FreeBSD-src-9d1dc5bcc93f630c5fc480593d45fbcfebef15f2.tar.gz |
MFC r268075: MFV r267565:
4757 ZFS embedded-data block pointers ("zero block compression")
4913 zfs release should not be subject to space checks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c | 85 |
1 files changed, 65 insertions, 20 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 4aa1c88..b7152d7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -129,17 +129,13 @@ const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS] = { }; int -dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, - void *tag, dmu_buf_t **dbp, int flags) +dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset, + void *tag, dmu_buf_t **dbp) { dnode_t *dn; uint64_t blkid; dmu_buf_impl_t *db; int err; - int db_flags = DB_RF_CANFAIL; - - if (flags & DMU_READ_NO_PREFETCH) - db_flags |= DB_RF_NOPREFETCH; err = dnode_hold(os, object, FTAG, &dn); if (err) @@ -148,18 +144,37 @@ dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, rw_enter(&dn->dn_struct_rwlock, RW_READER); db = dbuf_hold(dn, blkid, tag); rw_exit(&dn->dn_struct_rwlock); + dnode_rele(dn, FTAG); + if (db == NULL) { - err = SET_ERROR(EIO); - } else { + *dbp = NULL; + return (SET_ERROR(EIO)); + } + + *dbp = &db->db; + return (err); +} + +int +dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, + void *tag, dmu_buf_t **dbp, int flags) +{ + int err; + int db_flags = DB_RF_CANFAIL; + + if (flags & DMU_READ_NO_PREFETCH) + db_flags |= DB_RF_NOPREFETCH; + + err = dmu_buf_hold_noread(os, object, offset, tag, dbp); + if (err == 0) { + dmu_buf_impl_t *db = (dmu_buf_impl_t *)(*dbp); err = dbuf_read(db, NULL, db_flags); - if (err) { + if (err != 0) { dbuf_rele(db, tag); - db = NULL; + *dbp = NULL; } } - dnode_rele(dn, FTAG); - *dbp = &db->db; /* NULL db plus first field offset is NULL */ return (err); } @@ -855,6 +870,25 @@ dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_rele_array(dbp, numbufs, FTAG); } +void +dmu_write_embedded(objset_t *os, uint64_t object, uint64_t offset, + void *data, uint8_t etype, uint8_t comp, int uncompressed_size, + int compressed_size, int byteorder, dmu_tx_t *tx) +{ + dmu_buf_t *db; + + ASSERT3U(etype, <, NUM_BP_EMBEDDED_TYPES); + ASSERT3U(comp, <, ZIO_COMPRESS_FUNCTIONS); + VERIFY0(dmu_buf_hold_noread(os, object, offset, + FTAG, &db)); + + dmu_buf_write_embedded(db, + data, (bp_embedded_type_t)etype, (enum zio_compress)comp, + uncompressed_size, compressed_size, byteorder, tx); + + dmu_buf_rele(db, FTAG); +} + /* * DMU support for xuio */ @@ -1332,7 +1366,7 @@ dmu_sync_ready(zio_t *zio, arc_buf_t *buf, void *varg) * block size still needs to be known for replay. */ BP_SET_LSIZE(bp, db->db_size); - } else { + } else if (!BP_IS_EMBEDDED(bp)) { ASSERT(BP_GET_LEVEL(bp) == 0); bp->blk_fill = 1; } @@ -1603,9 +1637,15 @@ dmu_object_set_checksum(objset_t *os, uint64_t object, uint8_t checksum, { dnode_t *dn; - /* XXX assumes dnode_hold will not get an i/o error */ - (void) dnode_hold(os, object, FTAG, &dn); - ASSERT(checksum < ZIO_CHECKSUM_FUNCTIONS); + /* + * Send streams include each object's checksum function. This + * check ensures that the receiving system can understand the + * checksum function transmitted. + */ + ASSERT3U(checksum, <, ZIO_CHECKSUM_LEGACY_FUNCTIONS); + + VERIFY0(dnode_hold(os, object, FTAG, &dn)); + ASSERT3U(checksum, <, ZIO_CHECKSUM_FUNCTIONS); dn->dn_checksum = checksum; dnode_setdirty(dn, tx); dnode_rele(dn, FTAG); @@ -1617,9 +1657,14 @@ dmu_object_set_compress(objset_t *os, uint64_t object, uint8_t compress, { dnode_t *dn; - /* XXX assumes dnode_hold will not get an i/o error */ - (void) dnode_hold(os, object, FTAG, &dn); - ASSERT(compress < ZIO_COMPRESS_FUNCTIONS); + /* + * Send streams include each object's compression function. This + * check ensures that the receiving system can understand the + * compression function transmitted. + */ + ASSERT3U(compress, <, ZIO_COMPRESS_LEGACY_FUNCTIONS); + + VERIFY0(dnode_hold(os, object, FTAG, &dn)); dn->dn_compress = compress; dnode_setdirty(dn, tx); dnode_rele(dn, FTAG); @@ -1789,7 +1834,7 @@ dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi) doi->doi_max_offset = (dn->dn_maxblkid + 1) * dn->dn_datablksz; doi->doi_fill_count = 0; for (int i = 0; i < dnp->dn_nblkptr; i++) - doi->doi_fill_count += dnp->dn_blkptr[i].blk_fill; + doi->doi_fill_count += BP_GET_FILL(&dnp->dn_blkptr[i]); mutex_exit(&dn->dn_mtx); rw_exit(&dn->dn_struct_rwlock); |