summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2013-07-30 21:02:09 +0000
committerdelphij <delphij@FreeBSD.org>2013-07-30 21:02:09 +0000
commitc5affee6a3a59d69c44d3493fa98bec9080bb11f (patch)
tree23a5763925ca6f88812017c8afbc82918ed35156 /sys/cddl
parentef92cf9910e5912fe431aaad8b444da2aaae9741 (diff)
downloadFreeBSD-src-c5affee6a3a59d69c44d3493fa98bec9080bb11f.zip
FreeBSD-src-c5affee6a3a59d69c44d3493fa98bec9080bb11f.tar.gz
MFV r253781 + r253871:
Illumos ZFS issues: 3894 zfs should not allow snapshot of inconsistent dataset MFC after: 2 weeks
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c19
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h1
5 files changed, 22 insertions, 6 deletions
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
index 4243c20..4bdc946 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
@@ -395,6 +395,8 @@ zfs_prop_init(void)
PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE");
zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
+ zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
+ PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
/* oddball properties */
zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index d3fd995..5c15009 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -1608,7 +1608,7 @@ dmu_recv_end_check(void *arg, dmu_tx_t *tx)
return (error);
}
error = dsl_dataset_snapshot_check_impl(origin_head,
- drc->drc_tosnap, tx);
+ drc->drc_tosnap, tx, B_TRUE);
dsl_dataset_rele(origin_head, FTAG);
if (error != 0)
return (error);
@@ -1616,7 +1616,7 @@ dmu_recv_end_check(void *arg, dmu_tx_t *tx)
error = dsl_destroy_head_check_impl(drc->drc_ds, 1);
} else {
error = dsl_dataset_snapshot_check_impl(drc->drc_ds,
- drc->drc_tosnap, tx);
+ drc->drc_tosnap, tx, B_TRUE);
}
return (error);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index aabc23b..774f354 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -994,7 +994,7 @@ typedef struct dsl_dataset_snapshot_arg {
int
dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
- dmu_tx_t *tx)
+ dmu_tx_t *tx, boolean_t recv)
{
int error;
uint64_t value;
@@ -1020,6 +1020,18 @@ dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
if (error != ENOENT)
return (error);
+ /*
+ * We don't allow taking snapshots of inconsistent datasets, such as
+ * those into which we are currently receiving. However, if we are
+ * creating this snapshot as part of a receive, this check will be
+ * executed atomically with respect to the completion of the receive
+ * itself but prior to the clearing of DS_FLAG_INCONSISTENT; in this
+ * case we ignore this, knowing it will be fixed up for us shortly in
+ * dmu_recv_end_sync().
+ */
+ if (!recv && DS_IS_INCONSISTENT(ds))
+ return (SET_ERROR(EBUSY));
+
error = dsl_dataset_snapshot_reserve_space(ds, tx);
if (error != 0)
return (error);
@@ -1056,7 +1068,7 @@ dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx)
error = dsl_dataset_hold(dp, dsname, FTAG, &ds);
if (error == 0) {
error = dsl_dataset_snapshot_check_impl(ds,
- atp + 1, tx);
+ atp + 1, tx, B_FALSE);
dsl_dataset_rele(ds, FTAG);
}
@@ -1322,7 +1334,8 @@ dsl_dataset_snapshot_tmp_check(void *arg, dmu_tx_t *tx)
if (error != 0)
return (error);
- error = dsl_dataset_snapshot_check_impl(ds, ddsta->ddsta_snapname, tx);
+ error = dsl_dataset_snapshot_check_impl(ds, ddsta->ddsta_snapname,
+ tx, B_FALSE);
if (error != 0) {
dsl_dataset_rele(ds, FTAG);
return (error);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
index 18bee83..2a6e0b8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
@@ -251,7 +251,7 @@ int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
dsl_dataset_t *origin_head, dmu_tx_t *tx);
int dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
- dmu_tx_t *tx);
+ dmu_tx_t *tx, boolean_t recv);
void dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
dmu_tx_t *tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 51c7506..478735d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -143,6 +143,7 @@ typedef enum {
ZFS_PROP_CLONES,
ZFS_PROP_LOGICALUSED,
ZFS_PROP_LOGICALREFERENCED,
+ ZFS_PROP_INCONSISTENT, /* not exposed to the user */
ZFS_NUM_PROPS
} zfs_prop_t;
OpenPOWER on IntegriCloud