diff options
author | delphij <delphij@FreeBSD.org> | 2013-07-30 21:02:09 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2013-07-30 21:02:09 +0000 |
commit | c5affee6a3a59d69c44d3493fa98bec9080bb11f (patch) | |
tree | 23a5763925ca6f88812017c8afbc82918ed35156 /sys/cddl | |
parent | ef92cf9910e5912fe431aaad8b444da2aaae9741 (diff) | |
download | FreeBSD-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')
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; |