Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
Show First 20 Lines • Show All 1,540 Lines • ▼ Show 20 Lines | if (ds->ds_prev) | ||||
dsl_dataset_rele(ds->ds_prev, ds); | dsl_dataset_rele(ds->ds_prev, ds); | ||||
VERIFY0(dsl_dataset_hold_obj(dp, | VERIFY0(dsl_dataset_hold_obj(dp, | ||||
dsl_dataset_phys(ds)->ds_prev_snap_obj, ds, &ds->ds_prev)); | dsl_dataset_phys(ds)->ds_prev_snap_obj, ds, &ds->ds_prev)); | ||||
dsl_scan_ds_snapshotted(ds, tx); | dsl_scan_ds_snapshotted(ds, tx); | ||||
dsl_dir_snap_cmtime_update(ds->ds_dir); | dsl_dir_snap_cmtime_update(ds->ds_dir); | ||||
#if defined(__FreeBSD__) && defined(_KERNEL) | |||||
char fullname[ZFS_MAX_DATASET_NAME_LEN]; | |||||
dsl_dataset_name(ds, fullname); | |||||
strlcat(fullname, "@", sizeof(fullname)); | |||||
strlcat(fullname, snapname, sizeof(fullname)); | |||||
zvol_create_minors(dp->dp_spa, fullname); | |||||
#endif | |||||
spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, ""); | spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, ""); | ||||
} | } | ||||
void | void | ||||
dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx) | dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx) | ||||
{ | { | ||||
dsl_dataset_snapshot_arg_t *ddsa = arg; | dsl_dataset_snapshot_arg_t *ddsa = arg; | ||||
dsl_pool_t *dp = dmu_tx_pool(tx); | dsl_pool_t *dp = dmu_tx_pool(tx); | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | if (suspended != NULL) { | ||||
for (pair = nvlist_next_nvpair(suspended, NULL); pair != NULL; | for (pair = nvlist_next_nvpair(suspended, NULL); pair != NULL; | ||||
pair = nvlist_next_nvpair(suspended, pair)) { | pair = nvlist_next_nvpair(suspended, pair)) { | ||||
zil_resume((void *)(uintptr_t) | zil_resume((void *)(uintptr_t) | ||||
fnvpair_value_uint64(pair)); | fnvpair_value_uint64(pair)); | ||||
} | } | ||||
fnvlist_free(suspended); | fnvlist_free(suspended); | ||||
} | } | ||||
#ifdef __FreeBSD__ | |||||
#ifdef _KERNEL | |||||
if (error == 0) { | |||||
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; | |||||
pair = nvlist_next_nvpair(snaps, pair)) { | |||||
char *snapname = nvpair_name(pair); | |||||
zvol_create_minors(snapname); | |||||
} | |||||
} | |||||
#endif | |||||
#endif | |||||
return (error); | return (error); | ||||
} | } | ||||
typedef struct dsl_dataset_snapshot_tmp_arg { | typedef struct dsl_dataset_snapshot_tmp_arg { | ||||
const char *ddsta_fsname; | const char *ddsta_fsname; | ||||
const char *ddsta_snapname; | const char *ddsta_snapname; | ||||
minor_t ddsta_cleanup_minor; | minor_t ddsta_cleanup_minor; | ||||
const char *ddsta_htag; | const char *ddsta_htag; | ||||
▲ Show 20 Lines • Show All 855 Lines • ▼ Show 20 Lines | #endif | ||||
(void) strcpy(ds->ds_snapname, ddrsa->ddrsa_newsnapname); | (void) strcpy(ds->ds_snapname, ddrsa->ddrsa_newsnapname); | ||||
mutex_exit(&ds->ds_lock); | mutex_exit(&ds->ds_lock); | ||||
VERIFY0(zap_add(dp->dp_meta_objset, | VERIFY0(zap_add(dp->dp_meta_objset, | ||||
dsl_dataset_phys(hds)->ds_snapnames_zapobj, | dsl_dataset_phys(hds)->ds_snapnames_zapobj, | ||||
ds->ds_snapname, 8, 1, &ds->ds_object, tx)); | ds->ds_snapname, 8, 1, &ds->ds_object, tx)); | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | oldname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); | ||||
newname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | newname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); | ||||
snprintf(oldname, MAXPATHLEN, "%s@%s", ddrsa->ddrsa_fsname, | snprintf(oldname, ZFS_MAX_DATASET_NAME_LEN, "%s@%s", | ||||
ddrsa->ddrsa_oldsnapname); | ddrsa->ddrsa_fsname, ddrsa->ddrsa_oldsnapname); | ||||
snprintf(newname, MAXPATHLEN, "%s@%s", ddrsa->ddrsa_fsname, | snprintf(newname, ZFS_MAX_DATASET_NAME_LEN, "%s@%s", | ||||
ddrsa->ddrsa_newsnapname); | ddrsa->ddrsa_fsname, ddrsa->ddrsa_newsnapname); | ||||
zfsvfs_update_fromname(oldname, newname); | zfsvfs_update_fromname(oldname, newname); | ||||
zvol_rename_minors(oldname, newname); | zvol_rename_minors(dp->dp_spa, oldname, newname); | ||||
kmem_free(newname, MAXPATHLEN); | kmem_free(newname, ZFS_MAX_DATASET_NAME_LEN); | ||||
kmem_free(oldname, MAXPATHLEN); | kmem_free(oldname, ZFS_MAX_DATASET_NAME_LEN); | ||||
#endif | #endif | ||||
#endif | #endif | ||||
dsl_dataset_rele(ds, FTAG); | dsl_dataset_rele(ds, FTAG); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 533 Lines • ▼ Show 20 Lines | if (dsl_dir_phys(dd)->dd_clones == 0) { | ||||
zap_create(dp->dp_meta_objset, DMU_OT_DSL_CLONES, | zap_create(dp->dp_meta_objset, DMU_OT_DSL_CLONES, | ||||
DMU_OT_NONE, 0, tx); | DMU_OT_NONE, 0, tx); | ||||
} | } | ||||
VERIFY0(zap_add_int(dp->dp_meta_objset, | VERIFY0(zap_add_int(dp->dp_meta_objset, | ||||
dsl_dir_phys(dd)->dd_clones, origin_head->ds_object, tx)); | dsl_dir_phys(dd)->dd_clones, origin_head->ds_object, tx)); | ||||
} | } | ||||
#if defined(__FreeBSD__) && defined(_KERNEL) | #if defined(__FreeBSD__) && defined(_KERNEL) | ||||
/* Take the spa_namespace_lock early so zvol renames don't deadlock. */ | oldname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); | ||||
mutex_enter(&spa_namespace_lock); | newname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); | ||||
oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | |||||
newname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | |||||
#endif | #endif | ||||
/* move snapshots to this dir */ | /* move snapshots to this dir */ | ||||
for (snap = list_head(&ddpa->shared_snaps); snap; | for (snap = list_head(&ddpa->shared_snaps); snap; | ||||
snap = list_next(&ddpa->shared_snaps, snap)) { | snap = list_next(&ddpa->shared_snaps, snap)) { | ||||
dsl_dataset_t *ds = snap->ds; | dsl_dataset_t *ds = snap->ds; | ||||
/* | /* | ||||
* Property callbacks are registered to a particular | * Property callbacks are registered to a particular | ||||
* dsl_dir. Since ours is changing, evict the objset | * dsl_dir. Since ours is changing, evict the objset | ||||
* so that they will be unregistered from the old dsl_dir. | * so that they will be unregistered from the old dsl_dir. | ||||
*/ | */ | ||||
if (ds->ds_objset) { | if (ds->ds_objset) { | ||||
dmu_objset_evict(ds->ds_objset); | dmu_objset_evict(ds->ds_objset); | ||||
ds->ds_objset = NULL; | ds->ds_objset = NULL; | ||||
} | } | ||||
#if defined(__FreeBSD__) && defined(_KERNEL) | |||||
dsl_dataset_name(ds, oldname); | |||||
#endif | |||||
/* move snap name entry */ | /* move snap name entry */ | ||||
VERIFY0(dsl_dataset_get_snapname(ds)); | VERIFY0(dsl_dataset_get_snapname(ds)); | ||||
VERIFY0(dsl_dataset_snap_remove(origin_head, | VERIFY0(dsl_dataset_snap_remove(origin_head, | ||||
ds->ds_snapname, tx, B_TRUE)); | ds->ds_snapname, tx, B_TRUE)); | ||||
VERIFY0(zap_add(dp->dp_meta_objset, | VERIFY0(zap_add(dp->dp_meta_objset, | ||||
dsl_dataset_phys(hds)->ds_snapnames_zapobj, ds->ds_snapname, | dsl_dataset_phys(hds)->ds_snapnames_zapobj, ds->ds_snapname, | ||||
8, 1, &ds->ds_object, tx)); | 8, 1, &ds->ds_object, tx)); | ||||
dsl_fs_ss_count_adjust(hds->ds_dir, 1, | dsl_fs_ss_count_adjust(hds->ds_dir, 1, | ||||
DD_FIELD_SNAPSHOT_COUNT, tx); | DD_FIELD_SNAPSHOT_COUNT, tx); | ||||
/* change containing dsl_dir */ | /* change containing dsl_dir */ | ||||
dmu_buf_will_dirty(ds->ds_dbuf, tx); | dmu_buf_will_dirty(ds->ds_dbuf, tx); | ||||
ASSERT3U(dsl_dataset_phys(ds)->ds_dir_obj, ==, odd->dd_object); | ASSERT3U(dsl_dataset_phys(ds)->ds_dir_obj, ==, odd->dd_object); | ||||
dsl_dataset_phys(ds)->ds_dir_obj = dd->dd_object; | dsl_dataset_phys(ds)->ds_dir_obj = dd->dd_object; | ||||
ASSERT3P(ds->ds_dir, ==, odd); | ASSERT3P(ds->ds_dir, ==, odd); | ||||
dsl_dir_rele(ds->ds_dir, ds); | dsl_dir_rele(ds->ds_dir, ds); | ||||
VERIFY0(dsl_dir_hold_obj(dp, dd->dd_object, | VERIFY0(dsl_dir_hold_obj(dp, dd->dd_object, | ||||
NULL, ds, &ds->ds_dir)); | NULL, ds, &ds->ds_dir)); | ||||
#if defined(__FreeBSD__) && defined(_KERNEL) | #if defined(__FreeBSD__) && defined(_KERNEL) | ||||
dsl_dataset_name(ds, newname); | dsl_dataset_name(ds, newname); | ||||
zfsvfs_update_fromname(oldname, newname); | zfsvfs_update_fromname(oldname, newname); | ||||
zvol_rename_minors(oldname, newname); | zvol_rename_minors(dp->dp_spa, oldname, newname); | ||||
#endif | #endif | ||||
/* move any clone references */ | /* move any clone references */ | ||||
if (dsl_dataset_phys(ds)->ds_next_clones_obj && | if (dsl_dataset_phys(ds)->ds_next_clones_obj && | ||||
spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) { | spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) { | ||||
zap_cursor_t zc; | zap_cursor_t zc; | ||||
zap_attribute_t za; | zap_attribute_t za; | ||||
Show All 25 Lines | if (dsl_dataset_phys(ds)->ds_next_clones_obj && | ||||
} | } | ||||
zap_cursor_fini(&zc); | zap_cursor_fini(&zc); | ||||
} | } | ||||
ASSERT(!dsl_prop_hascb(ds)); | ASSERT(!dsl_prop_hascb(ds)); | ||||
} | } | ||||
#if defined(__FreeBSD__) && defined(_KERNEL) | #if defined(__FreeBSD__) && defined(_KERNEL) | ||||
mutex_exit(&spa_namespace_lock); | kmem_free(newname, ZFS_MAX_DATASET_NAME_LEN); | ||||
kmem_free(oldname, ZFS_MAX_DATASET_NAME_LEN); | |||||
kmem_free(newname, MAXPATHLEN); | |||||
kmem_free(oldname, MAXPATHLEN); | |||||
#endif | #endif | ||||
/* | /* | ||||
* Change space accounting. | * Change space accounting. | ||||
* Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either | * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either | ||||
* both be valid, or both be 0 (resulting in delta == 0). This | * both be valid, or both be 0 (resulting in delta == 0). This | ||||
* is true for each of {clone,origin} independently. | * is true for each of {clone,origin} independently. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,074 Lines • Show Last 20 Lines |