svn commit: r263398 - in stable: 8/cddl/contrib/opensolaris/cmd/zdb 8/cddl/contrib/opensolaris/cmd/zhack 8/cddl/contrib/opensolaris/cmd/zpool 8/sys/boot/zfs 8/sys/cddl/boot/zfs 8/sys/cddl/contrib/o...
Xin LI
delphij at FreeBSD.org
Wed Mar 19 23:58:08 UTC 2014
Author: delphij
Date: Wed Mar 19 23:58:05 2014
New Revision: 263398
URL: http://svnweb.freebsd.org/changeset/base/263398
Log:
MFC r260150: MFV r259170:
4370 avoid transmitting holes during zfs send
4371 DMU code clean up
illumos/illumos-gate at 43466aae47bfcd2ad9bf501faec8e75c08095e4f
NOTE: Make sure the boot code is updated if a zpool upgrade is
done on boot zpool.
Modified:
stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c
stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c
stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
stable/9/lib/libprocstat/zfs/Makefile
stable/9/sys/boot/zfs/zfsimpl.c
stable/9/sys/cddl/boot/zfs/zfsimpl.h
stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c
stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
Directory Properties:
stable/9/cddl/contrib/opensolaris/ (props changed)
stable/9/cddl/contrib/opensolaris/cmd/zpool/ (props changed)
stable/9/lib/libprocstat/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
Changes in other areas also in this revision:
Modified:
stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb.c
stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
stable/8/cddl/contrib/opensolaris/cmd/zhack/zhack.c
stable/8/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
stable/8/sys/boot/zfs/zfsimpl.c
stable/8/sys/cddl/boot/zfs/zfsimpl.h
stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c
stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
Directory Properties:
stable/8/cddl/contrib/opensolaris/ (props changed)
stable/8/cddl/contrib/opensolaris/cmd/zpool/ (props changed)
stable/8/sys/ (props changed)
stable/8/sys/boot/ (props changed)
stable/8/sys/cddl/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
Modified: stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -764,7 +764,7 @@ dump_dde(const ddt_t *ddt, const ddt_ent
if (ddp->ddp_phys_birth == 0)
continue;
ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
- sprintf_blkptr(blkbuf, &blk);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), &blk);
(void) printf("index %llx refcnt %llu %s %s\n",
(u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
types[p], blkbuf);
@@ -1024,31 +1024,39 @@ blkid2offset(const dnode_phys_t *dnp, co
}
static void
-sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
+snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp)
{
const dva_t *dva = bp->blk_dva;
int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
if (dump_opt['b'] >= 6) {
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, buflen, bp);
return;
}
blkbuf[0] = '\0';
for (int i = 0; i < ndvas; i++)
- (void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ",
+ (void) snprintf(blkbuf + strlen(blkbuf),
+ buflen - strlen(blkbuf), "%llu:%llx:%llx ",
(u_longlong_t)DVA_GET_VDEV(&dva[i]),
(u_longlong_t)DVA_GET_OFFSET(&dva[i]),
(u_longlong_t)DVA_GET_ASIZE(&dva[i]));
- (void) sprintf(blkbuf + strlen(blkbuf),
- "%llxL/%llxP F=%llu B=%llu/%llu",
- (u_longlong_t)BP_GET_LSIZE(bp),
- (u_longlong_t)BP_GET_PSIZE(bp),
- (u_longlong_t)bp->blk_fill,
- (u_longlong_t)bp->blk_birth,
- (u_longlong_t)BP_PHYSICAL_BIRTH(bp));
+ if (BP_IS_HOLE(bp)) {
+ (void) snprintf(blkbuf + strlen(blkbuf),
+ buflen - strlen(blkbuf), "B=%llu",
+ (u_longlong_t)bp->blk_birth);
+ } else {
+ (void) snprintf(blkbuf + strlen(blkbuf),
+ buflen - strlen(blkbuf),
+ "%llxL/%llxP F=%llu B=%llu/%llu",
+ (u_longlong_t)BP_GET_LSIZE(bp),
+ (u_longlong_t)BP_GET_PSIZE(bp),
+ (u_longlong_t)bp->blk_fill,
+ (u_longlong_t)bp->blk_birth,
+ (u_longlong_t)BP_PHYSICAL_BIRTH(bp));
+ }
}
static void
@@ -1073,7 +1081,7 @@ print_indirect(blkptr_t *bp, const zbook
}
}
- sprintf_blkptr_compact(blkbuf, bp);
+ snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp);
(void) printf("%s\n", blkbuf);
}
@@ -1088,7 +1096,7 @@ visit_indirect(spa_t *spa, const dnode_p
print_indirect(bp, zb, dnp);
- if (BP_GET_LEVEL(bp) > 0) {
+ if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
uint32_t flags = ARC_WAIT;
int i;
blkptr_t *cbp;
@@ -1213,7 +1221,7 @@ dump_dsl_dataset(objset_t *os, uint64_t
zdb_nicenum(ds->ds_compressed_bytes, compressed);
zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
zdb_nicenum(ds->ds_unique_bytes, unique);
- sprintf_blkptr(blkbuf, &ds->ds_bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), &ds->ds_bp);
(void) printf("\t\tdir_obj = %llu\n",
(u_longlong_t)ds->ds_dir_obj);
@@ -1258,7 +1266,7 @@ dump_bptree_cb(void *arg, const blkptr_t
char blkbuf[BP_SPRINTF_LEN];
if (bp->blk_birth != 0) {
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
(void) printf("\t%s\n", blkbuf);
}
return (0);
@@ -1296,7 +1304,7 @@ dump_bpobj_cb(void *arg, const blkptr_t
char blkbuf[BP_SPRINTF_LEN];
ASSERT(bp->blk_birth != 0);
- sprintf_blkptr_compact(blkbuf, bp);
+ snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp);
(void) printf("\t%s\n", blkbuf);
return (0);
}
@@ -1795,8 +1803,9 @@ dump_dir(objset_t *os)
zdb_nicenum(refdbytes, numbuf);
if (verbosity >= 4) {
- (void) sprintf(blkbuf, ", rootbp ");
- (void) sprintf_blkptr(blkbuf + strlen(blkbuf), os->os_rootbp);
+ (void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp ");
+ (void) snprintf_blkptr(blkbuf + strlen(blkbuf),
+ sizeof (blkbuf) - strlen(blkbuf), os->os_rootbp);
} else {
blkbuf[0] = '\0';
}
@@ -1826,7 +1835,7 @@ dump_dir(objset_t *os)
if (verbosity < 2)
return;
- if (os->os_rootbp->blk_birth == 0)
+ if (BP_IS_HOLE(os->os_rootbp))
return;
dump_object(os, 0, verbosity, &print_header);
@@ -1867,7 +1876,7 @@ dump_uberblock(uberblock_t *ub, const ch
(u_longlong_t)ub->ub_timestamp, asctime(localtime(×tamp)));
if (dump_opt['u'] >= 3) {
char blkbuf[BP_SPRINTF_LEN];
- sprintf_blkptr(blkbuf, &ub->ub_rootbp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), &ub->ub_rootbp);
(void) printf("\trootbp = %s\n", blkbuf);
}
(void) printf(footer ? footer : "");
@@ -2181,7 +2190,7 @@ zdb_blkptr_done(zio_t *zio)
zcb->zcb_errors[ioerr]++;
if (dump_opt['b'] >= 2)
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
else
blkbuf[0] = '\0';
@@ -2204,11 +2213,22 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog
const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
{
zdb_cb_t *zcb = arg;
- char blkbuf[BP_SPRINTF_LEN];
dmu_object_type_t type;
boolean_t is_metadata;
- if (bp == NULL)
+ if (dump_opt['b'] >= 5 && bp->blk_birth > 0) {
+ char blkbuf[BP_SPRINTF_LEN];
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
+ (void) printf("objset %llu object %llu "
+ "level %lld offset 0x%llx %s\n",
+ (u_longlong_t)zb->zb_objset,
+ (u_longlong_t)zb->zb_object,
+ (longlong_t)zb->zb_level,
+ (u_longlong_t)blkid2offset(dnp, bp, zb),
+ blkbuf);
+ }
+
+ if (BP_IS_HOLE(bp))
return (0);
type = BP_GET_TYPE(bp);
@@ -2239,17 +2259,6 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog
zcb->zcb_readfails = 0;
- if (dump_opt['b'] >= 5) {
- sprintf_blkptr(blkbuf, bp);
- (void) printf("objset %llu object %llu "
- "level %lld offset 0x%llx %s\n",
- (u_longlong_t)zb->zb_objset,
- (u_longlong_t)zb->zb_object,
- (longlong_t)zb->zb_level,
- (u_longlong_t)blkid2offset(dnp, bp, zb),
- blkbuf);
- }
-
if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) &&
gethrtime() > zcb->zcb_lastprint + NANOSEC) {
uint64_t now = gethrtime();
@@ -2406,7 +2415,7 @@ count_block_cb(void *arg, const blkptr_t
if (dump_opt['b'] >= 5) {
char blkbuf[BP_SPRINTF_LEN];
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
(void) printf("[%s] %s\n",
"deferred free", blkbuf);
}
@@ -2640,7 +2649,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilo
avl_index_t where;
zdb_ddt_entry_t *zdde, zdde_search;
- if (bp == NULL)
+ if (BP_IS_HOLE(bp))
return (0);
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
@@ -2807,7 +2816,7 @@ zdb_print_blkptr(blkptr_t *bp, int flags
if (flags & ZDB_FLAG_BSWAP)
byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
(void) printf("%s\n", blkbuf);
}
Modified: stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -24,6 +24,10 @@
*/
/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/*
* Print intent log header and statistics.
*/
@@ -47,7 +51,7 @@ print_log_bp(const blkptr_t *bp, const c
{
char blkbuf[BP_SPRINTF_LEN];
- sprintf_blkptr(blkbuf, bp);
+ snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
(void) printf("%s%s\n", prefix, blkbuf);
}
@@ -132,6 +136,7 @@ zil_prt_rec_write(zilog_t *zilog, int tx
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
(void) printf("%shas blkptr, %s\n", prefix,
+ !BP_IS_HOLE(bp) &&
bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
"will claim" : "won't claim");
print_log_bp(bp, prefix);
@@ -139,8 +144,6 @@ zil_prt_rec_write(zilog_t *zilog, int tx
if (BP_IS_HOLE(bp)) {
(void) printf("\t\t\tLSIZE 0x%llx\n",
(u_longlong_t)BP_GET_LSIZE(bp));
- }
- if (bp->blk_birth == 0) {
bzero(buf, sizeof (buf));
(void) printf("%s<hole>\n", prefix);
return;
@@ -313,7 +316,8 @@ print_log_block(zilog_t *zilog, blkptr_t
if (verbose >= 5) {
(void) strcpy(blkbuf, ", ");
- sprintf_blkptr(blkbuf + strlen(blkbuf), bp);
+ snprintf_blkptr(blkbuf + strlen(blkbuf),
+ sizeof (blkbuf) - strlen(blkbuf), bp);
} else {
blkbuf[0] = '\0';
}
@@ -361,7 +365,7 @@ dump_intent_log(zilog_t *zilog)
int verbose = MAX(dump_opt['d'], dump_opt['i']);
int i;
- if (zh->zh_log.blk_birth == 0 || verbose < 1)
+ if (BP_IS_HOLE(&zh->zh_log) || verbose < 1)
return;
(void) printf("\n ZIL header: claim_txg %llu, "
Modified: stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -277,6 +277,9 @@ zhack_do_feature_stat(int argc, char **a
dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
+ if (spa_feature_is_active(spa, SPA_FEATURE_ENABLED_TXG)) {
+ dump_obj(os, spa->spa_feat_enabled_txg_obj, "enabled_txg");
+ }
dump_mos(spa);
spa_close(spa, FTAG);
@@ -313,7 +316,9 @@ zhack_do_feature_enable(int argc, char *
feature.fi_uname = "zhack";
feature.fi_mos = B_FALSE;
feature.fi_can_readonly = B_FALSE;
+ feature.fi_activate_on_enable = B_FALSE;
feature.fi_depends = nodeps;
+ feature.fi_feature = SPA_FEATURE_NONE;
optind = 1;
while ((c = getopt(argc, argv, "rmd:")) != -1) {
@@ -371,7 +376,7 @@ feature_incr_sync(void *arg, dmu_tx_t *t
zfeature_info_t *feature = arg;
uint64_t refcount;
- VERIFY0(feature_get_refcount(spa, feature, &refcount));
+ VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount));
feature_sync(spa, feature, refcount + 1, tx);
spa_history_log_internal(spa, "zhack feature incr", tx,
"name=%s", feature->fi_guid);
@@ -384,7 +389,7 @@ feature_decr_sync(void *arg, dmu_tx_t *t
zfeature_info_t *feature = arg;
uint64_t refcount;
- VERIFY0(feature_get_refcount(spa, feature, &refcount));
+ VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount));
feature_sync(spa, feature, refcount - 1, tx);
spa_history_log_internal(spa, "zhack feature decr", tx,
"name=%s", feature->fi_guid);
@@ -411,6 +416,7 @@ zhack_do_feature_ref(int argc, char **ar
feature.fi_mos = B_FALSE;
feature.fi_desc = NULL;
feature.fi_depends = nodeps;
+ feature.fi_feature = SPA_FEATURE_NONE;
optind = 1;
while ((c = getopt(argc, argv, "md")) != -1) {
@@ -459,8 +465,8 @@ zhack_do_feature_ref(int argc, char **ar
if (decr) {
uint64_t count;
- if (feature_get_refcount(spa, &feature, &count) == 0 &&
- count != 0) {
+ if (feature_get_refcount_from_disk(spa, &feature,
+ &count) == 0 && count != 0) {
fatal(spa, FTAG, "feature refcount already 0: %s",
feature.fi_guid);
}
Modified: stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 Wed Mar 19 23:58:05 2014 (r263398)
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 08, 2013
+.Dd December 31, 2013
.Dt ZPOOL-FEATURES 7
.Os
.Sh NAME
@@ -286,6 +286,76 @@ and will be returned to the
.Sy enabled
state when all datasets that use
this feature are destroyed.
+.It Sy enabled_txg
+.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:enabled_txg"
+.It GUID Ta com.delphix:enabled_txg
+.It READ\-ONLY COMPATIBLE Ta yes
+.It DEPENDENCIES Ta none
+.El
+.Pp
+Once this feature is enabled ZFS records the transaction group number
+in which new features are enabled. This has no user-visible impact,
+but other features may depend on this feature.
+.Pp
+This feature becomes
+.Sy active
+as soon as it is enabled and will
+never return to being
+.Sy enabled .
+.It Sy hole_birth
+.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:hole_birth"
+.It GUID Ta com.delphix:hole_birth
+.It READ\-ONLY COMPATIBLE Ta no
+.It DEPENDENCIES Ta enabled_txg
+.El
+.Pp
+This feature improves performance of incremental sends
+.Pq Dq zfs send -i
+and receives for objects with many holes.
+The most common case of
+hole-filled objects is zvols.
+.Pp
+An incremental send stream from snapshot
+.Sy A
+to snapshot
+.Sy B
+contains information about every block that changed between
+.Sy A
+and
+.Sy B .
+Blocks which did not change between those snapshots can be
+identified and omitted from the stream using a piece of metadata called
+the 'block birth time', but birth times are not recorded for holes
+.Pq blocks filled only with zeroes .
+Since holes created after
+.Sy A
+cannot be
+distinguished from holes created before
+.Sy A ,
+information about every
+hole in the entire filesystem or zvol is included in the send stream.
+.Pp
+For workloads where holes are rare this is not a problem.
+However, when
+incrementally replicating filesystems or zvols with many holes
+.Pq for example a zvol formatted with another filesystem
+a lot of time will
+be spent sending and receiving unnecessary information about holes that
+already exist on the receiving side.
+.Pp
+Once the
+.Sy hole_birth
+feature has been enabled the block birth times
+of all new holes will be recorded.
+Incremental sends between snapshots
+created after this feature is enabled will use this new metadata to avoid
+sending information about holes that already exist on the receiving side.
+.Pp
+This feature becomes
+.Sy active
+as soon as it is enabled and will
+never return to being
+.Sy enabled .
.El
.Sh SEE ALSO
.Xr zpool 8
Modified: stable/9/lib/libprocstat/zfs/Makefile
==============================================================================
--- stable/9/lib/libprocstat/zfs/Makefile Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/lib/libprocstat/zfs/Makefile Wed Mar 19 23:58:05 2014 (r263398)
@@ -10,6 +10,7 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
+CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
Modified: stable/9/sys/boot/zfs/zfsimpl.c
==============================================================================
--- stable/9/sys/boot/zfs/zfsimpl.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/boot/zfs/zfsimpl.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -53,6 +53,9 @@ static vdev_list_t zfs_vdevs;
* List of ZFS features supported for read
*/
static const char *features_for_read[] = {
+ "org.illumos:lz4_compress",
+ "com.delphix:hole_birth",
+ "com.delphix:extensible_dataset",
NULL
};
Modified: stable/9/sys/cddl/boot/zfs/zfsimpl.h
==============================================================================
--- stable/9/sys/cddl/boot/zfs/zfsimpl.h Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/boot/zfs/zfsimpl.h Wed Mar 19 23:58:05 2014 (r263398)
@@ -222,9 +222,10 @@ typedef struct blkptr {
* Macros to get and set fields in a bp or DVA.
*/
#define DVA_GET_ASIZE(dva) \
- BF64_GET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0)
+ BF64_GET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0)
#define DVA_SET_ASIZE(dva, x) \
- BF64_SET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x)
+ BF64_SET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, \
+ SPA_MINBLOCKSHIFT, 0, x)
#define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8)
#define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x)
@@ -242,14 +243,14 @@ typedef struct blkptr {
#define BP_GET_LSIZE(bp) \
(BP_IS_HOLE(bp) ? 0 : \
- BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1))
+ 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, 16, SPA_MINBLOCKSHIFT, 1, x)
+ BF64_SET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
#define BP_GET_PSIZE(bp) \
- BF64_GET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1)
+ BF64_GET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1)
#define BP_SET_PSIZE(bp, x) \
- BF64_SET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)
+ BF64_SET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
#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)
@@ -266,7 +267,7 @@ typedef struct blkptr {
#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)
-#define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1))
+#define BP_GET_BYTEORDER(bp) BF64_GET((bp)->blk_prop, 63, 1)
#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x)
#define BP_PHYSICAL_BIRTH(bp) \
@@ -285,11 +286,6 @@ typedef struct blkptr {
!!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
!!DVA_GET_ASIZE(&(bp)->blk_dva[2]))
-#define BP_COUNT_GANG(bp) \
- (DVA_GET_GANG(&(bp)->blk_dva[0]) + \
- DVA_GET_GANG(&(bp)->blk_dva[1]) + \
- DVA_GET_GANG(&(bp)->blk_dva[2]))
-
#define DVA_EQUAL(dva1, dva2) \
((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
(dva1)->dva_word[0] == (dva2)->dva_word[0])
@@ -313,7 +309,9 @@ typedef struct blkptr {
#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
-#define BP_IS_HOLE(bp) ((bp)->blk_birth == 0)
+#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_OLDER(bp, txg) (!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg))
#define BP_ZERO(bp) \
Modified: stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -114,10 +114,21 @@ zfeature_lookup_name(const char *name, s
return (ENOENT);
}
+boolean_t
+zfeature_depends_on(spa_feature_t fid, spa_feature_t check) {
+ zfeature_info_t *feature = &spa_feature_table[fid];
+
+ for (int i = 0; feature->fi_depends[i] != SPA_FEATURE_NONE; i++) {
+ if (feature->fi_depends[i] == check)
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
static void
zfeature_register(spa_feature_t fid, const char *guid, const char *name,
const char *desc, boolean_t readonly, boolean_t mos,
- const spa_feature_t *deps)
+ boolean_t activate_on_enable, const spa_feature_t *deps)
{
zfeature_info_t *feature = &spa_feature_table[fid];
static spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
@@ -137,6 +148,7 @@ zfeature_register(spa_feature_t fid, con
feature->fi_desc = desc;
feature->fi_can_readonly = readonly;
feature->fi_mos = mos;
+ feature->fi_activate_on_enable = activate_on_enable;
feature->fi_depends = deps;
}
@@ -145,21 +157,43 @@ zpool_feature_init(void)
{
zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
"com.delphix:async_destroy", "async_destroy",
- "Destroy filesystems asynchronously.", B_TRUE, B_FALSE, NULL);
+ "Destroy filesystems asynchronously.", B_TRUE, B_FALSE,
+ B_FALSE, NULL);
+
zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
"com.delphix:empty_bpobj", "empty_bpobj",
- "Snapshots use less space.", B_TRUE, B_FALSE, NULL);
+ "Snapshots use less space.", B_TRUE, B_FALSE,
+ B_FALSE, NULL);
+
zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
"org.illumos:lz4_compress", "lz4_compress",
- "LZ4 compression algorithm support.", B_FALSE, B_FALSE, NULL);
+ "LZ4 compression algorithm support.", B_FALSE, B_FALSE,
+ B_FALSE, NULL);
+
zfeature_register(SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
"com.joyent:multi_vdev_crash_dump", "multi_vdev_crash_dump",
- "Crash dumps to multiple vdev pools.", B_FALSE, B_FALSE, NULL);
+ "Crash dumps to multiple vdev pools.", B_FALSE, B_FALSE,
+ B_FALSE, NULL);
+
zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
"com.delphix:spacemap_histogram", "spacemap_histogram",
- "Spacemaps maintain space histograms.", B_TRUE, B_FALSE, NULL);
+ "Spacemaps maintain space histograms.", B_TRUE, B_FALSE,
+ B_FALSE, NULL);
+
+ zfeature_register(SPA_FEATURE_ENABLED_TXG,
+ "com.delphix:enabled_txg", "enabled_txg",
+ "Record txg at which a feature is enabled", B_TRUE, B_FALSE,
+ B_FALSE, NULL);
+
+ static spa_feature_t hole_birth_deps[] = { SPA_FEATURE_ENABLED_TXG,
+ SPA_FEATURE_NONE };
+ zfeature_register(SPA_FEATURE_HOLE_BIRTH,
+ "com.delphix:hole_birth", "hole_birth",
+ "Retain hole birth txg for more precise zfs send",
+ B_FALSE, B_TRUE, B_TRUE, hole_birth_deps);
+
zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET,
"com.delphix:extensible_dataset", "extensible_dataset",
"Enhanced dataset functionality, used by other features.",
- B_FALSE, B_FALSE, NULL);
+ B_FALSE, B_FALSE, B_FALSE, NULL);
}
Modified: stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h Wed Mar 19 23:58:05 2014 (r263398)
@@ -44,10 +44,14 @@ typedef enum spa_feature {
SPA_FEATURE_LZ4_COMPRESS,
SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
SPA_FEATURE_SPACEMAP_HISTOGRAM,
+ SPA_FEATURE_ENABLED_TXG,
+ SPA_FEATURE_HOLE_BIRTH,
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURES
} spa_feature_t;
+#define SPA_FEATURE_DISABLED (-1ULL)
+
typedef struct zfeature_info {
spa_feature_t fi_feature;
const char *fi_uname; /* User-facing feature name */
@@ -55,6 +59,8 @@ typedef struct zfeature_info {
const char *fi_desc; /* Feature description */
boolean_t fi_can_readonly; /* Can open pool readonly w/o support? */
boolean_t fi_mos; /* Is the feature necessary to read the MOS? */
+ /* Activate this feature at the same time it is enabled */
+ boolean_t fi_activate_on_enable;
/* array of dependencies, terminated by SPA_FEATURE_NONE */
const spa_feature_t *fi_depends;
} zfeature_info_t;
@@ -69,6 +75,7 @@ extern boolean_t zfeature_is_valid_guid(
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 void zpool_feature_init(void);
Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -845,7 +845,7 @@ buf_hash(uint64_t spa, const dva_t *dva,
#define BUF_EMPTY(buf) \
((buf)->b_dva.dva_word[0] == 0 && \
(buf)->b_dva.dva_word[1] == 0 && \
- (buf)->b_birth == 0)
+ (buf)->b_cksum0 == 0)
#define BUF_EQUAL(spa, dva, birth, buf) \
((buf)->b_dva.dva_word[0] == (dva)->dva_word[0]) && \
@@ -3767,9 +3767,13 @@ arc_write_done(zio_t *zio)
ASSERT(hdr->b_acb == NULL);
if (zio->io_error == 0) {
- hdr->b_dva = *BP_IDENTITY(zio->io_bp);
- hdr->b_birth = BP_PHYSICAL_BIRTH(zio->io_bp);
- hdr->b_cksum0 = zio->io_bp->blk_cksum.zc_word[0];
+ if (BP_IS_HOLE(zio->io_bp)) {
+ buf_discard_identity(hdr);
+ } else {
+ hdr->b_dva = *BP_IDENTITY(zio->io_bp);
+ hdr->b_birth = BP_PHYSICAL_BIRTH(zio->io_bp);
+ hdr->b_cksum0 = zio->io_bp->blk_cksum.zc_word[0];
+ }
} else {
ASSERT(BUF_EMPTY(hdr));
}
Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <sys/arc.h>
@@ -141,7 +141,7 @@ bptree_visit_cb(spa_t *spa, zilog_t *zil
int err;
struct bptree_args *ba = arg;
- if (bp == NULL)
+ if (BP_IS_HOLE(bp))
return (0);
err = ba->ba_func(ba->ba_arg, bp, ba->ba_tx);
Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Mar 19 23:55:03 2014 (r263397)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Mar 19 23:58:05 2014 (r263398)
@@ -455,10 +455,9 @@ dbuf_loan_arcbuf(dmu_buf_impl_t *db)
mutex_enter(&db->db_mtx);
if (arc_released(db->db_buf) || refcount_count(&db->db_holds) > 1) {
int blksz = db->db.db_size;
- spa_t *spa;
+ spa_t *spa = db->db_objset->os_spa;
mutex_exit(&db->db_mtx);
- DB_GET_SPA(&spa, db);
abuf = arc_loan_buf(spa, blksz);
bcopy(db->db.db_data, abuf->b_data, blksz);
} else {
@@ -519,7 +518,6 @@ static void
dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags)
{
dnode_t *dn;
- spa_t *spa;
zbookmark_t zb;
uint32_t aflags = ARC_NOWAIT;
@@ -559,9 +557,9 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t
BP_IS_HOLE(db->db_blkptr)))) {
arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
- dbuf_set_data(db, arc_buf_alloc(dn->dn_objset->os_spa,
- db->db.db_size, db, type));
DB_DNODE_EXIT(db);
+ dbuf_set_data(db, arc_buf_alloc(db->db_objset->os_spa,
+ db->db.db_size, db, type));
bzero(db->db.db_data, db->db.db_size);
db->db_state = DB_CACHED;
*flags |= DB_RF_CACHED;
@@ -569,7 +567,6 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t
return;
}
- spa = dn->dn_objset->os_spa;
DB_DNODE_EXIT(db);
db->db_state = DB_READ;
@@ -586,7 +583,7 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t
dbuf_add_ref(db, NULL);
- (void) arc_read(zio, spa, db->db_blkptr,
+ (void) 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);
@@ -598,8 +595,8 @@ int
dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
{
int err = 0;
- int havepzio = (zio != NULL);
- int prefetch;
+ boolean_t havepzio = (zio != NULL);
+ boolean_t prefetch;
dnode_t *dn;
/*
@@ -694,11 +691,10 @@ dbuf_noread(dmu_buf_impl_t *db)
cv_wait(&db->db_changed, &db->db_mtx);
if (db->db_state == DB_UNCACHED) {
arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
- spa_t *spa;
+ spa_t *spa = db->db_objset->os_spa;
ASSERT(db->db_buf == NULL);
ASSERT(db->db.db_data == NULL);
- DB_GET_SPA(&spa, db);
dbuf_set_data(db, arc_buf_alloc(spa, db->db.db_size, db, type));
db->db_state = DB_FILL;
} else if (db->db_state == DB_NOFILL) {
@@ -753,9 +749,8 @@ dbuf_fix_old_data(dmu_buf_impl_t *db, ui
} else if (refcount_count(&db->db_holds) > db->db_dirtycnt) {
int size = db->db.db_size;
arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
- spa_t *spa;
+ spa_t *spa = db->db_objset->os_spa;
- DB_GET_SPA(&spa, db);
dr->dt.dl.dr_data = arc_buf_alloc(spa, size, db, type);
bcopy(db->db.db_data, dr->dt.dl.dr_data->b_data, size);
} else {
@@ -781,12 +776,9 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
ASSERT(db->db_data_pending != dr);
/* free this block */
- if (!BP_IS_HOLE(bp) && !dr->dt.dl.dr_nopwrite) {
- spa_t *spa;
+ if (!BP_IS_HOLE(bp) && !dr->dt.dl.dr_nopwrite)
+ zio_free(db->db_objset->os_spa, txg, bp);
- DB_GET_SPA(&spa, db);
- zio_free(spa, txg, bp);
- }
dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;
dr->dt.dl.dr_nopwrite = B_FALSE;
@@ -804,9 +796,7 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
/*
* Evict (if its unreferenced) or clear (if its referenced) any level-0
* data blocks in the free range, so that any future readers will find
- * empty blocks. Also, if we happen across any level-1 dbufs in the
- * range that have not already been marked dirty, mark them dirty so
- * they stay in memory.
+ * empty blocks.
*
* This is a no-op if the dataset is in the middle of an incremental
* receive; see comment below for details.
@@ -816,14 +806,9 @@ dbuf_free_range(dnode_t *dn, uint64_t st
{
dmu_buf_impl_t *db, *db_next;
uint64_t txg = tx->tx_txg;
- int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
- uint64_t first_l1 = start >> epbs;
- uint64_t last_l1 = end >> epbs;
- if (end > dn->dn_maxblkid && (end != DMU_SPILL_BLKID)) {
+ if (end > dn->dn_maxblkid && (end != DMU_SPILL_BLKID))
end = dn->dn_maxblkid;
- last_l1 = end >> epbs;
- }
dprintf_dnode(dn, "start=%llu end=%llu\n", start, end);
mutex_enter(&dn->dn_dbufs_mtx);
@@ -846,23 +831,8 @@ dbuf_free_range(dnode_t *dn, uint64_t st
db_next = list_next(&dn->dn_dbufs, db);
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
- if (db->db_level == 1 &&
- db->db_blkid >= first_l1 && db->db_blkid <= last_l1) {
- mutex_enter(&db->db_mtx);
- if (db->db_last_dirty &&
- db->db_last_dirty->dr_txg < txg) {
- dbuf_add_ref(db, FTAG);
- mutex_exit(&db->db_mtx);
- dbuf_will_dirty(db, tx);
- dbuf_rele(db, FTAG);
- } else {
- mutex_exit(&db->db_mtx);
- }
- }
-
if (db->db_level != 0)
continue;
- dprintf_dbuf(db, "found buf %s\n", "");
if (db->db_blkid < start || db->db_blkid > end)
continue;
@@ -939,24 +909,29 @@ dbuf_block_freeable(dmu_buf_impl_t *db)
* We don't need any locking to protect db_blkptr:
* If it's syncing, then db_last_dirty will be set
* so we'll ignore db_blkptr.
+ *
+ * This logic ensures that only block births for
+ * filled blocks are considered.
*/
ASSERT(MUTEX_HELD(&db->db_mtx));
- if (db->db_last_dirty)
+ if (db->db_last_dirty && (db->db_blkptr == NULL ||
+ !BP_IS_HOLE(db->db_blkptr))) {
birth_txg = db->db_last_dirty->dr_txg;
- else if (db->db_blkptr)
+ } else if (db->db_blkptr != NULL && !BP_IS_HOLE(db->db_blkptr)) {
birth_txg = db->db_blkptr->blk_birth;
+ }
/*
- * If we don't exist or are in a snapshot, we can't be freed.
+ * If this block don't exist or is in a snapshot, it can't be freed.
* Don't pass the bp to dsl_dataset_block_freeable() since we
* are holding the db_mtx lock and might deadlock if we are
* prefetching a dedup-ed block.
*/
- if (birth_txg)
+ if (birth_txg != 0)
return (ds == NULL ||
dsl_dataset_block_freeable(ds, NULL, birth_txg));
else
- return (FALSE);
+ return (B_FALSE);
}
void
@@ -976,7 +951,7 @@ dbuf_new_size(dmu_buf_impl_t *db, int si
ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
/*
- * This call to dbuf_will_dirty() with the dn_struct_rwlock held
+ * This call to dmu_buf_will_dirty() with the dn_struct_rwlock held
* is OK, because there can be no other references to the db
* when we are changing its size, so no concurrent DB_FILL can
* be happening.
@@ -985,7 +960,7 @@ dbuf_new_size(dmu_buf_impl_t *db, int si
* XXX we should be doing a dbuf_read, checking the return
* value and returning that up to our callers
*/
- dbuf_will_dirty(db, tx);
+ dmu_buf_will_dirty(&db->db, tx);
/* create the data buffer for the new block */
buf = arc_buf_alloc(dn->dn_objset->os_spa, size, db, type);
@@ -1015,9 +990,8 @@ dbuf_new_size(dmu_buf_impl_t *db, int si
void
dbuf_release_bp(dmu_buf_impl_t *db)
{
- objset_t *os;
+ objset_t *os = db->db_objset;
- DB_GET_OBJSET(&os, db);
ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
ASSERT(arc_released(os->os_phys_buf) ||
list_link_active(&os->os_dsl_dataset->ds_synced_link));
@@ -1391,10 +1365,10 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_
return (B_FALSE);
}
-#pragma weak dmu_buf_will_dirty = dbuf_will_dirty
void
-dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
+dmu_buf_will_dirty(dmu_buf_t *db_fake, dmu_tx_t *tx)
{
+ dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
int rf = DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH;
ASSERT(tx->tx_txg != 0);
@@ -1517,7 +1491,7 @@ dbuf_assign_arcbuf(dmu_buf_impl_t *db, a
db->db_state = DB_FILL;
mutex_exit(&db->db_mtx);
(void) dbuf_dirty(db, tx);
- dbuf_fill_done(db, tx);
+ dmu_buf_fill_done(&db->db, tx);
}
/*
@@ -2022,7 +1996,6 @@ dbuf_add_ref(dmu_buf_impl_t *db, void *t
* Without that, the dbuf_rele() could lead to a dnode_rele() followed by the
* dnode's parent dbuf evicting its dnode handles.
*/
-#pragma weak dmu_buf_rele = dbuf_rele
void
dbuf_rele(dmu_buf_impl_t *db, void *tag)
{
@@ -2030,6 +2003,12 @@ dbuf_rele(dmu_buf_impl_t *db, void *tag)
dbuf_rele_and_unlock(db, tag);
}
+void
+dmu_buf_rele(dmu_buf_t *db, void *tag)
+{
+ dbuf_rele((dmu_buf_impl_t *)db, tag);
+}
+
/*
* dbuf_rele() for an already-locked dbuf. This is necessary to allow
* db_dirtycnt and db_holds to be updated atomically.
@@ -2480,18 +2459,14 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *
dnode_diduse_space(dn, delta - zio->io_prev_space_delta);
zio->io_prev_space_delta = delta;
- if (BP_IS_HOLE(bp)) {
- ASSERT(bp->blk_fill == 0);
- DB_DNODE_EXIT(db);
- return;
+ if (bp->blk_birth != 0) {
+ ASSERT((db->db_blkid != DMU_SPILL_BLKID &&
+ BP_GET_TYPE(bp) == dn->dn_type) ||
+ (db->db_blkid == DMU_SPILL_BLKID &&
+ BP_GET_TYPE(bp) == dn->dn_bonustype));
+ ASSERT(BP_GET_LEVEL(bp) == db->db_level);
}
- ASSERT((db->db_blkid != DMU_SPILL_BLKID &&
- BP_GET_TYPE(bp) == dn->dn_type) ||
- (db->db_blkid == DMU_SPILL_BLKID &&
- BP_GET_TYPE(bp) == dn->dn_bonustype));
- ASSERT(BP_GET_LEVEL(bp) == db->db_level);
-
mutex_enter(&db->db_mtx);
#ifdef ZFS_DEBUG
@@ -2517,7 +2492,11 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *
fill++;
}
} else {
- fill = 1;
+ if (BP_IS_HOLE(bp)) {
+ fill = 0;
+ } else {
+ fill = 1;
+ }
}
} else {
blkptr_t *ibp = db->db.db_data;
@@ -2572,9 +2551,10 @@ static void
dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
{
dmu_buf_impl_t *db = vdb;
- blkptr_t *bp = zio->io_bp;
blkptr_t *bp_orig = &zio->io_bp_orig;
- uint64_t txg = zio->io_txg;
+ blkptr_t *bp = db->db_blkptr;
+ objset_t *os = db->db_objset;
+ dmu_tx_t *tx = os->os_synctx;
dbuf_dirty_record_t **drp, *dr;
ASSERT0(zio->io_error);
@@ -2587,14 +2567,7 @@ dbuf_write_done(zio_t *zio, arc_buf_t *b
if (zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE)) {
ASSERT(BP_EQUAL(bp, bp_orig));
} else {
- objset_t *os;
- dsl_dataset_t *ds;
- dmu_tx_t *tx;
-
- DB_GET_OBJSET(&os, db);
- ds = os->os_dsl_dataset;
- tx = os->os_synctx;
-
+ dsl_dataset_t *ds = os->os_dsl_dataset;
(void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
dsl_dataset_block_born(ds, bp, tx);
}
@@ -2607,7 +2580,6 @@ dbuf_write_done(zio_t *zio, arc_buf_t *b
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-9
mailing list