aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2014-06-05 13:19:08 -0800
committerBrian Behlendorf <[email protected]>2014-08-01 14:28:05 -0700
commit9b67f605601c77c814037613d8129562db642a29 (patch)
tree21a3270ed7eda24858e56a9584f64f6359f4b28f /lib
parentfaf0f58c69607a15e2d1563567afb815842805de (diff)
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 <[email protected]> Reviewed by: Max Grossman <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Christopher Siden <[email protected]> Reviewed by: Dan McDonald <[email protected]> Approved by: Dan McDonald <[email protected]> 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 <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #2544
Diffstat (limited to 'lib')
-rw-r--r--lib/libzfs/libzfs_sendrecv.c46
-rw-r--r--lib/libzfs_core/libzfs_core.c12
-rw-r--r--lib/libzpool/Makefile.am1
3 files changed, 52 insertions, 7 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index a11d4bf36..ebd8a7be2 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <[email protected]>.
* All rights reserved
@@ -49,6 +49,7 @@
#include <time.h>
#include <libzfs.h>
+#include <libzfs_core.h>
#include "zfs_namecheck.h"
#include "zfs_prop.h"
@@ -220,6 +221,7 @@ cksummer(void *arg)
struct drr_object *drro = &thedrr.drr_u.drr_object;
struct drr_write *drrw = &thedrr.drr_u.drr_write;
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
+ struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
FILE *ofp;
int outfd;
dmu_replay_record_t wbr_drr = {0};
@@ -415,6 +417,20 @@ cksummer(void *arg)
break;
}
+ case DRR_WRITE_EMBEDDED:
+ {
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ (void) ssread(buf,
+ P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
+ if (cksum_and_write(buf,
+ P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ break;
+ }
+
case DRR_FREE:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
@@ -796,7 +812,7 @@ typedef struct send_dump_data {
char prevsnap[ZFS_MAXNAMELEN];
uint64_t prevsnap_obj;
boolean_t seenfrom, seento, replicate, doall, fromorigin;
- boolean_t verbose, dryrun, parsable, progress;
+ boolean_t verbose, dryrun, parsable, progress, embed_data;
int outfd;
boolean_t err;
nvlist_t *fss;
@@ -876,7 +892,8 @@ estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
*/
static int
dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
- boolean_t fromorigin, int outfd, nvlist_t *debugnv)
+ boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
+ nvlist_t *debugnv)
{
zfs_cmd_t zc = {"\0"};
libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -890,6 +907,7 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
zc.zc_obj = fromorigin;
zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
zc.zc_fromobj = fromsnap_obj;
+ zc.zc_flags = flags;
VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
if (fromsnap && fromsnap[0] != '\0') {
@@ -1140,8 +1158,12 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
}
}
+ enum lzc_send_flags flags = 0;
+ if (sdd->embed_data)
+ flags |= LZC_SEND_FLAG_EMBED_DATA;
+
err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
- fromorigin, sdd->outfd, sdd->debugnv);
+ fromorigin, sdd->outfd, flags, sdd->debugnv);
if (sdd->progress) {
(void) pthread_cancel(tid);
@@ -1485,6 +1507,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sdd.parsable = flags->parsable;
sdd.progress = flags->progress;
sdd.dryrun = flags->dryrun;
+ sdd.embed_data = flags->embed_data;
sdd.filter_cb = filter_func;
sdd.filter_cb_arg = cb_arg;
if (debugnvp)
@@ -1616,7 +1639,8 @@ err_out:
}
int
-zfs_send_one(zfs_handle_t *zhp, const char *from, int fd)
+zfs_send_one(zfs_handle_t *zhp, const char *from, int fd,
+ enum lzc_send_flags flags)
{
int err;
libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -1625,7 +1649,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd)
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"warning: cannot send '%s'"), zhp->zfs_name);
- err = lzc_send(zhp->zfs_name, from, fd);
+ err = lzc_send(zhp->zfs_name, from, fd, flags);
if (err != 0) {
switch (errno) {
case EXDEV:
@@ -2543,6 +2567,16 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
(void) recv_read(hdl, fd, buf,
drr->drr_u.drr_spill.drr_length, B_FALSE, NULL);
break;
+ case DRR_WRITE_EMBEDDED:
+ if (byteswap) {
+ drr->drr_u.drr_write_embedded.drr_psize =
+ BSWAP_32(drr->drr_u.drr_write_embedded.
+ drr_psize);
+ }
+ (void) recv_read(hdl, fd, buf,
+ P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
+ 8), B_FALSE, NULL);
+ break;
case DRR_WRITE_BYREF:
case DRR_FREEOBJECTS:
case DRR_FREE:
diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c
index 0c05bbd27..2198ecd6f 100644
--- a/lib/libzfs_core/libzfs_core.c
+++ b/lib/libzfs_core/libzfs_core.c
@@ -439,6 +439,8 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
}
/*
+ * Generate a zfs send stream for the specified snapshot and write it to
+ * the specified file descriptor.
*
* "snapname" is the full name of the snapshot to send (e.g. "pool/fs@snap")
*
@@ -452,9 +454,15 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
* snapshot in the origin, etc.
*
* "fd" is the file descriptor to write the send stream to.
+ *
+ * If "flags" contains LZC_SEND_FLAG_EMBED_DATA, the stream is permitted
+ * to contain DRR_WRITE_EMBEDDED records with drr_etype==BP_EMBEDDED_TYPE_DATA,
+ * which the receiving system must support (as indicated by support
+ * for the "embedded_data" feature).
*/
int
-lzc_send(const char *snapname, const char *from, int fd)
+lzc_send(const char *snapname, const char *from, int fd,
+ enum lzc_send_flags flags)
{
nvlist_t *args;
int err;
@@ -463,6 +471,8 @@ lzc_send(const char *snapname, const char *from, int fd)
fnvlist_add_int32(args, "fd", fd);
if (from != NULL)
fnvlist_add_string(args, "fromsnap", from);
+ if (flags & LZC_SEND_FLAG_EMBED_DATA)
+ fnvlist_add_boolean(args, "embedok");
err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
nvlist_free(args);
return (err);
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am
index b960850fb..f4838da75 100644
--- a/lib/libzpool/Makefile.am
+++ b/lib/libzpool/Makefile.am
@@ -21,6 +21,7 @@ libzpool_la_SOURCES = \
$(top_srcdir)/module/zcommon/zpool_prop.c \
$(top_srcdir)/module/zcommon/zprop_common.c \
$(top_srcdir)/module/zfs/arc.c \
+ $(top_srcdir)/module/zfs/blkptr.c \
$(top_srcdir)/module/zfs/bplist.c \
$(top_srcdir)/module/zfs/bpobj.c \
$(top_srcdir)/module/zfs/bptree.c \