Ramzec commented on this pull request.
first look. will try to understand how it works.
> @@ -188,9 +188,13 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func,
> void *data)
/* Setup the requested properties nvlist. */
props = fnvlist_alloc();
- fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_GUID));
- fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATETXG));
- fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATION));
+ for (zfs_prop_t p = 0; p < ZFS_NUM_PROPS; p++) {
+ if (zfs_prop_valid_for_type(p, ZFS_TYPE_BOOKMARK)) {
+ fnvlist_add_boolean(props, zfs_prop_to_name(p));
+ }
+ }
+ fnvlist_add_boolean(props, "redact_snaps");
As I understand "redact_snaps" can be handled by the above loop.
> + */
+static int
+find_redact_book(libzfs_handle_t *hdl, const char *path,
+ const uint64_t *redact_snap_guids, int num_redact_snaps,
+ char **bookname)
+{
+ char errbuf[1024];
+ int error = 0;
+ nvlist_t *props = fnvlist_alloc();
+ nvlist_t *bmarks;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot resume send"));
+
+ fnvlist_add_boolean(props, "redact_complete");
+ fnvlist_add_boolean(props, "redact_snaps");
zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS) instead of "redact_snaps" ??
> + } else if (error == ENOENT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset to be sent no longer exists"));
+ } else {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "unknown error: %s"), strerror(error));
+ }
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+ nvpair_t *pair;
+ for (pair = nvlist_next_nvpair(bmarks, NULL); pair;
+ pair = nvlist_next_nvpair(bmarks, pair)) {
+
+ nvlist_t *bmark = fnvpair_value_nvlist(pair);
+ nvlist_t *vallist = fnvlist_lookup_nvlist(bmark,
+ "redact_snaps");
zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS) instead of "redact_snaps" ??
> @@ -1644,14 +1878,38 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t
> *flags, int outfd,
fromname = name;
}
- if (flags->verbose) {
- uint64_t size = 0;
- error = lzc_send_space(zhp->zfs_name, fromname,
- lzc_flags, &size);
- if (error == 0)
- size = MAX(0, (int64_t)(size - bytes));
- send_print_verbose(stderr, zhp->zfs_name, fromname,
- size, flags->parsable);
+ redact_snap_guids = NULL;
+
+ if (nvlist_lookup_uint64_array(resume_nvl, "redact_snaps",
zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS) instead of "redact_snaps" ??
> - size = MAX(0, (int64_t)(size - bytes));
- send_print_verbose(stderr, zhp->zfs_name, fromname,
- size, flags->parsable);
+ redact_snap_guids = NULL;
+
+ if (nvlist_lookup_uint64_array(resume_nvl, "redact_snaps",
+ &redact_snap_guids, (uint_t *)&num_redact_snaps) == 0) {
+ char path[ZFS_MAX_DATASET_NAME_LEN];
+
+ (void) strlcpy(path, toname, sizeof (path));
+ char *at = strchr(path, '@');
+ ASSERT3P(at, !=, NULL);
+
+ *at = '\0';
+
+ if ((error = find_redact_book(hdl, path, redact_snap_guids,
It seems "redact_book" will not be freed if "flags->dryrun == B_TRUE"
> } guid_to_name_data_t;
+boolean_t
+redact_snaps_match(zfs_handle_t *zhp, guid_to_name_data_t *gtnd)
+{
+ uint64_t *bmark_snaps;
+ uint_t bmark_num_snaps;
+ nvlist_t *nvl;
+ if (zhp->zfs_type != ZFS_TYPE_BOOKMARK)
+ return (B_FALSE);
+
+ nvl = fnvlist_lookup_nvlist(zhp->zfs_props, "redact_snaps");
zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS) instead of "redact_snaps" ??
> @@ -1054,6 +1054,20 @@ dmu_write_embedded(objset_t *os, uint64_t object,
> uint64_t offset,
dmu_buf_rele(db, FTAG);
}
+void
+dmu_redact(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+ dmu_tx_t *tx)
+{
+ int numbufs, i;
+ dmu_buf_t **dbp;
+
+ VERIFY(0 == dmu_buf_hold_array(os, object, offset, size, FALSE, FTAG,
VERIFY0()
> +
+ tx = dmu_tx_create(rwa->os);
+
+ dmu_tx_hold_spill(tx, db->db_object);
+
+ err = dmu_tx_assign(tx, TXG_WAIT);
+ if (err != 0) {
+ dmu_buf_rele(db, FTAG);
+ dmu_buf_rele(db_spill, FTAG);
+ dmu_tx_abort(tx);
+ return (err);
+ }
+ dmu_buf_will_dirty(db_spill, tx);
+
+ if (db_spill->db_size < drrs->drr_length)
+ VERIFY(0 == dbuf_spill_set_blksz(db_spill,
VERIFY0
- return (0);
+ switch (new_type) {
+ case HOLE:
+ pending->sru.hole.datablksz = datablksz;
+ break;
+ case DATA:
+ pending->sru.data.datablksz = datablksz;
+ pending->sru.data.obj_type = dn->dn_type;
+ pending->sru.data.bp = *bp;
+ if (spta->issue_prefetches) {
+ zbookmark_phys_t zb = {0};
+ zb.zb_objset = dmu_objset_id(dn->dn_objset);
+ zb.zb_object = dn->dn_obj
Just a nit, but there is no reason to walk over the whole nvlist, so
nvlist_empty(nvl) is more logical.
> + dbn->dbn_dirty = B_FALSE;
+ }
+ }
+#ifdef ZFS_DEBUG
+ for (dsl_bookmark_node_t *dbn = avl_first(&ds->ds_bookmarks);
+ dbn != NULL; dbn = AVL_NEXT(&ds->ds_bookmarks, dbn)) {
+ ASSERT(!dbn->dbn_dirty);
+ }
+#endif
+}
+
+/*
+ * Return the TXG of the most recent bookmark (or 0 if there are no bookmarks).
+ */
+uint64_t
+dsl_bookmark_latest_txg(dsl_dataset_t *ds)
Don't you need to add an ASSERT()+comment to this function to be sure nobody
modified ds->ds_bookmarks at this time?
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/openzfs/openzfs/pull/484#pullrequestreview-77908732
------------------------------------------
openzfs-developer
Archives:
https://openzfs.topicbox.com/groups/developer/discussions/T1fcfd4fc81bcdfff-Mafeb965f6e7f8596f3b705f3
Powered by Topicbox: https://topicbox.com