mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Illumos 4757, 4913
4757 ZFS embedded-data block pointers ("zero block compression")
4913 zfs release should not be subject to space checks
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>
References:
https://www.illumos.org/issues/4757
https://www.illumos.org/issues/4913
https://github.com/illumos/illumos-gate/commit/5d7b4d4
Porting notes:
For compatibility with the fastpath code the zio_done() function
needed to be updated. Because embedded-data block pointers do
not require DVAs to be allocated the associated vdevs will not
be marked and therefore should not be unmarked.
Ported by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2544
This commit is contained in:
committed by
Brian Behlendorf
parent
faf0f58c69
commit
9b67f60560
+5
-1
@@ -39,6 +39,7 @@
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/avl.h>
|
||||
#include <ucred.h>
|
||||
#include <libzfs_core.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -614,13 +615,16 @@ typedef struct sendflags {
|
||||
|
||||
/* show progress (ie. -v) */
|
||||
boolean_t progress;
|
||||
|
||||
/* WRITE_EMBEDDED records of type DATA are permitted */
|
||||
boolean_t embed_data;
|
||||
} sendflags_t;
|
||||
|
||||
typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
|
||||
|
||||
extern int zfs_send(zfs_handle_t *, const char *, const char *,
|
||||
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
|
||||
extern int zfs_send_one(zfs_handle_t *, const char *, int);
|
||||
extern int zfs_send_one(zfs_handle_t *, const char *, int, enum lzc_send_flags);
|
||||
|
||||
extern int zfs_promote(zfs_handle_t *);
|
||||
extern int zfs_hold(zfs_handle_t *, const char *, const char *,
|
||||
|
||||
@@ -52,7 +52,11 @@ int lzc_hold(nvlist_t *, int, nvlist_t **);
|
||||
int lzc_release(nvlist_t *, nvlist_t **);
|
||||
int lzc_get_holds(const char *, nvlist_t **);
|
||||
|
||||
int lzc_send(const char *, const char *, int);
|
||||
enum lzc_send_flags {
|
||||
LZC_SEND_FLAG_EMBED_DATA = 1 << 0
|
||||
};
|
||||
|
||||
int lzc_send(const char *, const char *, int, enum lzc_send_flags);
|
||||
int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int);
|
||||
int lzc_send_space(const char *, const char *, uint64_t *);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ COMMON_H = \
|
||||
$(top_srcdir)/include/sys/arc.h \
|
||||
$(top_srcdir)/include/sys/avl.h \
|
||||
$(top_srcdir)/include/sys/avl_impl.h \
|
||||
$(top_srcdir)/include/sys/blkptr.h \
|
||||
$(top_srcdir)/include/sys/bplist.h \
|
||||
$(top_srcdir)/include/sys/bpobj.h \
|
||||
$(top_srcdir)/include/sys/bptree.h \
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BLKPTR_H
|
||||
#define _SYS_BLKPTR_H
|
||||
|
||||
#include <sys/spa.h>
|
||||
#include <sys/zio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void encode_embedded_bp_compressed(blkptr_t *, void *,
|
||||
enum zio_compress, int, int);
|
||||
void decode_embedded_bp_compressed(const blkptr_t *, void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_BLKPTR_H */
|
||||
@@ -272,6 +272,9 @@ void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx);
|
||||
void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
|
||||
dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
|
||||
arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
|
||||
void dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
|
||||
bp_embedded_type_t etype, enum zio_compress comp,
|
||||
int uncompressed_size, int compressed_size, int byteorder, dmu_tx_t *tx);
|
||||
|
||||
void dbuf_clear(dmu_buf_impl_t *db);
|
||||
void dbuf_evict(dmu_buf_impl_t *db);
|
||||
|
||||
@@ -116,6 +116,14 @@ typedef enum dmu_object_byteswap {
|
||||
((ot) & DMU_OT_METADATA) : \
|
||||
dmu_ot[(int)(ot)].ot_metadata)
|
||||
|
||||
/*
|
||||
* These object types use bp_fill != 1 for their L0 bp's. Therefore they can't
|
||||
* have their data embedded (i.e. use a BP_IS_EMBEDDED() bp), because bp_fill
|
||||
* is repurposed for embedded BPs.
|
||||
*/
|
||||
#define DMU_OT_HAS_FILL(ot) \
|
||||
((ot) == DMU_OT_DNODE || (ot) == DMU_OT_OBJSET)
|
||||
|
||||
#define DMU_OT_BYTESWAP(ot) (((ot) & DMU_OT_NEWTYPE) ? \
|
||||
((ot) & DMU_OT_BYTESWAP_MASK) : \
|
||||
dmu_ot[(int)(ot)].ot_byteswap)
|
||||
@@ -391,6 +399,11 @@ void dmu_object_set_checksum(objset_t *os, uint64_t object, uint8_t checksum,
|
||||
void dmu_object_set_compress(objset_t *os, uint64_t object, uint8_t compress,
|
||||
dmu_tx_t *tx);
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* Decide how to write a block: checksum, compression, number of copies, etc.
|
||||
*/
|
||||
|
||||
@@ -269,12 +269,15 @@ typedef struct dmu_sendarg {
|
||||
int dsa_err;
|
||||
dmu_pendop_t dsa_pending_op;
|
||||
boolean_t dsa_incremental;
|
||||
uint64_t dsa_featureflags;
|
||||
uint64_t dsa_last_data_object;
|
||||
uint64_t dsa_last_data_offset;
|
||||
} dmu_sendarg_t;
|
||||
|
||||
void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *);
|
||||
void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *);
|
||||
int dmu_buf_hold_noread(objset_t *, uint64_t, uint64_t,
|
||||
void *, dmu_buf_t **);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ struct dsl_dataset;
|
||||
struct drr_begin;
|
||||
struct avl_tree;
|
||||
|
||||
int dmu_send(const char *tosnap, const char *fromsnap, int outfd,
|
||||
struct vnode *vp, offset_t *off);
|
||||
int dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok,
|
||||
int outfd, struct vnode *vp, offset_t *off);
|
||||
int dmu_send_estimate(struct dsl_dataset *ds, struct dsl_dataset *fromds,
|
||||
uint64_t *sizep);
|
||||
int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
|
||||
int outfd, struct vnode *vp, offset_t *off);
|
||||
boolean_t embedok, int outfd, vnode_t *vp, offset_t *off);
|
||||
|
||||
typedef struct dmu_recv_cookie {
|
||||
struct dsl_dataset *drc_ds;
|
||||
|
||||
+155
-24
@@ -156,7 +156,7 @@ typedef struct zio_cksum {
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 5 |G| offset3 |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE |
|
||||
* 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 7 | padding |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
@@ -190,7 +190,8 @@ typedef struct zio_cksum {
|
||||
* G gang block indicator
|
||||
* B byteorder (endianness)
|
||||
* D dedup
|
||||
* X unused
|
||||
* X encryption (on version 30, which is not supported)
|
||||
* E blkptr_t contains embedded data (see below)
|
||||
* lvl level of indirection
|
||||
* type DMU object type
|
||||
* phys birth txg of block allocation; zero if same as logical birth txg
|
||||
@@ -198,6 +199,100 @@ typedef struct zio_cksum {
|
||||
* fill count number of non-zero blocks under this bp
|
||||
* checksum[4] 256-bit checksum of the data this bp describes
|
||||
*/
|
||||
|
||||
/*
|
||||
* "Embedded" blkptr_t's don't actually point to a block, instead they
|
||||
* have a data payload embedded in the blkptr_t itself. See the comment
|
||||
* in blkptr.c for more details.
|
||||
*
|
||||
* The blkptr_t is laid out as follows:
|
||||
*
|
||||
* 64 56 48 40 32 24 16 8 0
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 0 | payload |
|
||||
* 1 | payload |
|
||||
* 2 | payload |
|
||||
* 3 | payload |
|
||||
* 4 | payload |
|
||||
* 5 | payload |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 6 |BDX|lvl| type | etype |E| comp| PSIZE| LSIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 7 | payload |
|
||||
* 8 | payload |
|
||||
* 9 | payload |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* a | logical birth txg |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* b | payload |
|
||||
* c | payload |
|
||||
* d | payload |
|
||||
* e | payload |
|
||||
* f | payload |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*
|
||||
* Legend:
|
||||
*
|
||||
* payload contains the embedded data
|
||||
* B (byteorder) byteorder (endianness)
|
||||
* D (dedup) padding (set to zero)
|
||||
* X encryption (set to zero; see above)
|
||||
* E (embedded) set to one
|
||||
* lvl indirection level
|
||||
* type DMU object type
|
||||
* etype how to interpret embedded data (BP_EMBEDDED_TYPE_*)
|
||||
* comp compression function of payload
|
||||
* PSIZE size of payload after compression, in bytes
|
||||
* LSIZE logical size of payload, in bytes
|
||||
* note that 25 bits is enough to store the largest
|
||||
* "normal" BP's LSIZE (2^16 * 2^9) in bytes
|
||||
* log. birth transaction group in which the block was logically born
|
||||
*
|
||||
* Note that LSIZE and PSIZE are stored in bytes, whereas for non-embedded
|
||||
* bp's they are stored in units of SPA_MINBLOCKSHIFT.
|
||||
* Generally, the generic BP_GET_*() macros can be used on embedded BP's.
|
||||
* The B, D, X, lvl, type, and comp fields are stored the same as with normal
|
||||
* BP's so the BP_SET_* macros can be used with them. etype, PSIZE, LSIZE must
|
||||
* be set with the BPE_SET_* macros. BP_SET_EMBEDDED() should be called before
|
||||
* other macros, as they assert that they are only used on BP's of the correct
|
||||
* "embedded-ness".
|
||||
*/
|
||||
|
||||
#define BPE_GET_ETYPE(bp) \
|
||||
(ASSERT(BP_IS_EMBEDDED(bp)), \
|
||||
BF64_GET((bp)->blk_prop, 40, 8))
|
||||
#define BPE_SET_ETYPE(bp, t) do { \
|
||||
ASSERT(BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET((bp)->blk_prop, 40, 8, t); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
#define BPE_GET_LSIZE(bp) \
|
||||
(ASSERT(BP_IS_EMBEDDED(bp)), \
|
||||
BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1))
|
||||
#define BPE_SET_LSIZE(bp, x) do { \
|
||||
ASSERT(BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET_SB((bp)->blk_prop, 0, 25, 0, 1, x); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
#define BPE_GET_PSIZE(bp) \
|
||||
(ASSERT(BP_IS_EMBEDDED(bp)), \
|
||||
BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1))
|
||||
#define BPE_SET_PSIZE(bp, x) do { \
|
||||
ASSERT(BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET_SB((bp)->blk_prop, 25, 7, 0, 1, x); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
typedef enum bp_embedded_type {
|
||||
BP_EMBEDDED_TYPE_DATA,
|
||||
BP_EMBEDDED_TYPE_RESERVED, /* Reserved for an unintegrated feature. */
|
||||
NUM_BP_EMBEDDED_TYPES = BP_EMBEDDED_TYPE_RESERVED
|
||||
} bp_embedded_type_t;
|
||||
|
||||
#define BPE_NUM_WORDS 14
|
||||
#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t))
|
||||
#define BPE_IS_PAYLOADWORD(bp, wp) \
|
||||
((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
|
||||
|
||||
#define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */
|
||||
#define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */
|
||||
|
||||
@@ -244,20 +339,37 @@ typedef struct blkptr {
|
||||
#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x)
|
||||
|
||||
#define BP_GET_LSIZE(bp) \
|
||||
BF64_GET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1)
|
||||
#define BP_SET_LSIZE(bp, x) \
|
||||
BF64_SET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
|
||||
(BP_IS_EMBEDDED(bp) ? \
|
||||
(BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA ? BPE_GET_LSIZE(bp) : 0): \
|
||||
BF64_GET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1))
|
||||
#define BP_SET_LSIZE(bp, x) do { \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET_SB((bp)->blk_prop, \
|
||||
0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
#define BP_GET_PSIZE(bp) \
|
||||
BF64_GET_SB((bp)->blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1)
|
||||
#define BP_SET_PSIZE(bp, x) \
|
||||
BF64_SET_SB((bp)->blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
BF64_GET_SB((bp)->blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1))
|
||||
#define BP_SET_PSIZE(bp, x) do { \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET_SB((bp)->blk_prop, \
|
||||
16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8)
|
||||
#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x)
|
||||
#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7)
|
||||
#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x)
|
||||
|
||||
#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
|
||||
#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
|
||||
#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1)
|
||||
#define BP_SET_EMBEDDED(bp, x) BF64_SET((bp)->blk_prop, 39, 1, x)
|
||||
|
||||
#define BP_GET_CHECKSUM(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? ZIO_CHECKSUM_OFF : \
|
||||
BF64_GET((bp)->blk_prop, 40, 8))
|
||||
#define BP_SET_CHECKSUM(bp, x) do { \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET((bp)->blk_prop, 40, 8, x); \
|
||||
_NOTE(CONSTCOND) } while (0)
|
||||
|
||||
#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8)
|
||||
#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x)
|
||||
@@ -265,9 +377,6 @@ typedef struct blkptr {
|
||||
#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
|
||||
#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
|
||||
|
||||
#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1)
|
||||
#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x)
|
||||
|
||||
#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1)
|
||||
#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x)
|
||||
|
||||
@@ -275,31 +384,39 @@ typedef struct blkptr {
|
||||
#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x)
|
||||
|
||||
#define BP_PHYSICAL_BIRTH(bp) \
|
||||
((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth)
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
(bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth)
|
||||
|
||||
#define BP_SET_BIRTH(bp, logical, physical) \
|
||||
{ \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
(bp)->blk_birth = (logical); \
|
||||
(bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \
|
||||
}
|
||||
|
||||
#define BP_GET_FILL(bp) (BP_IS_EMBEDDED(bp) ? 1 : (bp)->blk_fill)
|
||||
|
||||
#define BP_GET_ASIZE(bp) \
|
||||
(DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
|
||||
DVA_GET_ASIZE(&(bp)->blk_dva[2]))
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
|
||||
DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
|
||||
DVA_GET_ASIZE(&(bp)->blk_dva[2]))
|
||||
|
||||
#define BP_GET_UCSIZE(bp) \
|
||||
((BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp))) ? \
|
||||
BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp))
|
||||
|
||||
#define BP_GET_NDVAS(bp) \
|
||||
(!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
|
||||
!!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
|
||||
!!DVA_GET_ASIZE(&(bp)->blk_dva[2]))
|
||||
|
||||
#define BP_COUNT_GANG(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
(DVA_GET_GANG(&(bp)->blk_dva[0]) + \
|
||||
DVA_GET_GANG(&(bp)->blk_dva[1]) + \
|
||||
DVA_GET_GANG(&(bp)->blk_dva[2]))
|
||||
DVA_GET_GANG(&(bp)->blk_dva[2])))
|
||||
|
||||
#define DVA_EQUAL(dva1, dva2) \
|
||||
((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
|
||||
@@ -307,6 +424,7 @@ typedef struct blkptr {
|
||||
|
||||
#define BP_EQUAL(bp1, bp2) \
|
||||
(BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) && \
|
||||
(bp1)->blk_birth == (bp2)->blk_birth && \
|
||||
DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \
|
||||
DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \
|
||||
DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2]))
|
||||
@@ -327,11 +445,13 @@ typedef struct blkptr {
|
||||
(zcp)->zc_word[3] = w3; \
|
||||
}
|
||||
|
||||
#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
|
||||
#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
|
||||
#define BP_IDENTITY(bp) (ASSERT(!BP_IS_EMBEDDED(bp)), &(bp)->blk_dva[0])
|
||||
#define BP_IS_GANG(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? B_FALSE : DVA_GET_GANG(BP_IDENTITY(bp)))
|
||||
#define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] == 0ULL && \
|
||||
(dva)->dva_word[1] == 0ULL)
|
||||
#define BP_IS_HOLE(bp) DVA_IS_EMPTY(BP_IDENTITY(bp))
|
||||
#define BP_IS_HOLE(bp) \
|
||||
(!BP_IS_EMBEDDED(bp) && DVA_IS_EMPTY(BP_IDENTITY(bp)))
|
||||
|
||||
/* BP_IS_RAIDZ(bp) assumes no block compression */
|
||||
#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
|
||||
@@ -386,6 +506,17 @@ typedef struct blkptr {
|
||||
" birth=%lluL", \
|
||||
(u_longlong_t)bp->blk_birth); \
|
||||
} \
|
||||
} else if (BP_IS_EMBEDDED(bp)) { \
|
||||
len = func(buf + len, size - len, \
|
||||
"EMBEDDED [L%llu %s] et=%u %s " \
|
||||
"size=%llxL/%llxP birth=%lluL", \
|
||||
(u_longlong_t)BP_GET_LEVEL(bp), \
|
||||
type, \
|
||||
(int)BPE_GET_ETYPE(bp), \
|
||||
compress, \
|
||||
(u_longlong_t)BPE_GET_LSIZE(bp), \
|
||||
(u_longlong_t)BPE_GET_PSIZE(bp), \
|
||||
(u_longlong_t)bp->blk_birth); \
|
||||
} else { \
|
||||
for (d = 0; d < BP_GET_NDVAS(bp); d++) { \
|
||||
const dva_t *dva = &bp->blk_dva[d]; \
|
||||
@@ -419,7 +550,7 @@ typedef struct blkptr {
|
||||
(u_longlong_t)BP_GET_PSIZE(bp), \
|
||||
(u_longlong_t)bp->blk_birth, \
|
||||
(u_longlong_t)BP_PHYSICAL_BIRTH(bp), \
|
||||
(u_longlong_t)bp->blk_fill, \
|
||||
(u_longlong_t)BP_GET_FILL(bp), \
|
||||
ws, \
|
||||
(u_longlong_t)bp->blk_cksum.zc_word[0], \
|
||||
(u_longlong_t)bp->blk_cksum.zc_word[1], \
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/bplist.h>
|
||||
#include <sys/bpobj.h>
|
||||
#include <sys/zfeature.h>
|
||||
#include <zfeature_common.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+25
-8
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_IOCTL_H
|
||||
@@ -90,15 +90,19 @@ typedef enum drr_headertype {
|
||||
* Feature flags for zfs send streams (flags in drr_versioninfo)
|
||||
*/
|
||||
|
||||
#define DMU_BACKUP_FEATURE_DEDUP (0x1)
|
||||
#define DMU_BACKUP_FEATURE_DEDUPPROPS (0x2)
|
||||
#define DMU_BACKUP_FEATURE_SA_SPILL (0x4)
|
||||
#define DMU_BACKUP_FEATURE_DEDUP (1<<0)
|
||||
#define DMU_BACKUP_FEATURE_DEDUPPROPS (1<<1)
|
||||
#define DMU_BACKUP_FEATURE_SA_SPILL (1<<2)
|
||||
/* flags #3 - #15 are reserved for incompatible closed-source implementations */
|
||||
#define DMU_BACKUP_FEATURE_EMBED_DATA (1<<16)
|
||||
#define DMU_BACKUP_FEATURE_EMBED_DATA_LZ4 (1<<17)
|
||||
|
||||
/*
|
||||
* Mask of all supported backup features
|
||||
*/
|
||||
#define DMU_BACKUP_FEATURE_MASK (DMU_BACKUP_FEATURE_DEDUP | \
|
||||
DMU_BACKUP_FEATURE_DEDUPPROPS | DMU_BACKUP_FEATURE_SA_SPILL)
|
||||
DMU_BACKUP_FEATURE_DEDUPPROPS | DMU_BACKUP_FEATURE_SA_SPILL | \
|
||||
DMU_BACKUP_FEATURE_EMBED_DATA | DMU_BACKUP_FEATURE_EMBED_DATA_LZ4)
|
||||
|
||||
/* Are all features in the given flag word currently supported? */
|
||||
#define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK))
|
||||
@@ -140,7 +144,7 @@ typedef struct dmu_replay_record {
|
||||
enum {
|
||||
DRR_BEGIN, DRR_OBJECT, DRR_FREEOBJECTS,
|
||||
DRR_WRITE, DRR_FREE, DRR_END, DRR_WRITE_BYREF,
|
||||
DRR_SPILL, DRR_NUMTYPES
|
||||
DRR_SPILL, DRR_WRITE_EMBEDDED, DRR_NUMTYPES
|
||||
} drr_type;
|
||||
uint32_t drr_payloadlen;
|
||||
union {
|
||||
@@ -217,6 +221,19 @@ typedef struct dmu_replay_record {
|
||||
uint64_t drr_pad[4]; /* needed for crypto */
|
||||
/* spill data follows */
|
||||
} drr_spill;
|
||||
struct drr_write_embedded {
|
||||
uint64_t drr_object;
|
||||
uint64_t drr_offset;
|
||||
/* logical length, should equal blocksize */
|
||||
uint64_t drr_length;
|
||||
uint64_t drr_toguid;
|
||||
uint8_t drr_compression;
|
||||
uint8_t drr_etype;
|
||||
uint8_t drr_pad[6];
|
||||
uint32_t drr_lsize; /* uncompressed size of payload */
|
||||
uint32_t drr_psize; /* compr. (real) size of payload */
|
||||
/* (possibly compressed) content follows */
|
||||
} drr_write_embedded;
|
||||
} drr_u;
|
||||
} dmu_replay_record_t;
|
||||
|
||||
@@ -325,8 +342,8 @@ typedef struct zfs_cmd {
|
||||
dmu_objset_stats_t zc_objset_stats;
|
||||
struct drr_begin zc_begin_record;
|
||||
zinject_record_t zc_inject_record;
|
||||
boolean_t zc_defer_destroy;
|
||||
boolean_t zc_temphold;
|
||||
uint32_t zc_defer_destroy;
|
||||
uint32_t zc_flags;
|
||||
uint64_t zc_action_handle;
|
||||
int zc_cleanup_fd;
|
||||
uint8_t zc_simple;
|
||||
|
||||
@@ -82,6 +82,12 @@ enum zio_checksum {
|
||||
ZIO_CHECKSUM_FUNCTIONS
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of "legacy" compression functions which can be set on individual
|
||||
* objects.
|
||||
*/
|
||||
#define ZIO_CHECKSUM_LEGACY_FUNCTIONS ZIO_CHECKSUM_ZILOG2
|
||||
|
||||
#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_4
|
||||
#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON
|
||||
|
||||
@@ -111,6 +117,12 @@ enum zio_compress {
|
||||
ZIO_COMPRESS_FUNCTIONS
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of "legacy" compression functions which can be set on individual
|
||||
* objects.
|
||||
*/
|
||||
#define ZIO_COMPRESS_LEGACY_FUNCTIONS ZIO_COMPRESS_LZ4
|
||||
|
||||
#define ZIO_COMPRESS_ON_VALUE ZIO_COMPRESS_LZJB
|
||||
#define ZIO_COMPRESS_DEFAULT ZIO_COMPRESS_OFF
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ typedef enum spa_feature {
|
||||
SPA_FEATURE_ENABLED_TXG,
|
||||
SPA_FEATURE_HOLE_BIRTH,
|
||||
SPA_FEATURE_EXTENSIBLE_DATASET,
|
||||
SPA_FEATURE_EMBEDDED_DATA,
|
||||
SPA_FEATURE_BOOKMARKS,
|
||||
SPA_FEATURES
|
||||
} spa_feature_t;
|
||||
@@ -65,7 +66,7 @@ typedef struct zfeature_info {
|
||||
const spa_feature_t *fi_depends;
|
||||
} zfeature_info_t;
|
||||
|
||||
typedef int (zfeature_func_t)(zfeature_info_t *fi, void *arg);
|
||||
typedef int (zfeature_func_t)(zfeature_info_t *, void *);
|
||||
|
||||
#define ZFS_FEATURE_DEBUG
|
||||
|
||||
@@ -74,8 +75,8 @@ extern zfeature_info_t spa_feature_table[SPA_FEATURES];
|
||||
extern boolean_t zfeature_is_valid_guid(const char *);
|
||||
|
||||
extern boolean_t zfeature_is_supported(const char *);
|
||||
extern int zfeature_lookup_name(const char *name, spa_feature_t *res);
|
||||
extern boolean_t zfeature_depends_on(spa_feature_t fid, spa_feature_t check);
|
||||
extern int zfeature_lookup_name(const char *, spa_feature_t *);
|
||||
extern boolean_t zfeature_depends_on(spa_feature_t, spa_feature_t);
|
||||
|
||||
extern void zpool_feature_init(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user