usr/src/uts/common/fs/zfs/dsl_dataset.c
changeset 13524 f0e12b33f77c
parent 13512 060607df0c9d
child 13686 4bc0783f6064
equal deleted inserted replaced
13523:6763769941d2 13524:f0e12b33f77c
   900 	}
   900 	}
   901 
   901 
   902 	return (dsobj);
   902 	return (dsobj);
   903 }
   903 }
   904 
   904 
   905 struct destroyarg {
   905 /*
   906 	dsl_sync_task_group_t *dstg;
   906  * The snapshots must all be in the same pool.
   907 	char *snapname;
   907  */
   908 	char *failed;
   908 int
   909 	boolean_t defer;
   909 dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed)
   910 };
   910 {
   911 
       
   912 static int
       
   913 dsl_snapshot_destroy_one(const char *name, void *arg)
       
   914 {
       
   915 	struct destroyarg *da = arg;
       
   916 	dsl_dataset_t *ds;
       
   917 	int err;
   911 	int err;
   918 	char *dsname;
       
   919 
       
   920 	dsname = kmem_asprintf("%s@%s", name, da->snapname);
       
   921 	err = dsl_dataset_own(dsname, B_TRUE, da->dstg, &ds);
       
   922 	strfree(dsname);
       
   923 	if (err == 0) {
       
   924 		struct dsl_ds_destroyarg *dsda;
       
   925 
       
   926 		dsl_dataset_make_exclusive(ds, da->dstg);
       
   927 		dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg), KM_SLEEP);
       
   928 		dsda->ds = ds;
       
   929 		dsda->defer = da->defer;
       
   930 		dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check,
       
   931 		    dsl_dataset_destroy_sync, dsda, da->dstg, 0);
       
   932 	} else if (err == ENOENT) {
       
   933 		err = 0;
       
   934 	} else {
       
   935 		(void) strcpy(da->failed, name);
       
   936 	}
       
   937 	return (err);
       
   938 }
       
   939 
       
   940 /*
       
   941  * Destroy 'snapname' in all descendants of 'fsname'.
       
   942  */
       
   943 #pragma weak dmu_snapshots_destroy = dsl_snapshots_destroy
       
   944 int
       
   945 dsl_snapshots_destroy(char *fsname, char *snapname, boolean_t defer)
       
   946 {
       
   947 	int err;
       
   948 	struct destroyarg da;
       
   949 	dsl_sync_task_t *dst;
   912 	dsl_sync_task_t *dst;
   950 	spa_t *spa;
   913 	spa_t *spa;
   951 
   914 	nvpair_t *pair;
   952 	err = spa_open(fsname, &spa, FTAG);
   915 	dsl_sync_task_group_t *dstg;
       
   916 
       
   917 	pair = nvlist_next_nvpair(snaps, NULL);
       
   918 	if (pair == NULL)
       
   919 		return (0);
       
   920 
       
   921 	err = spa_open(nvpair_name(pair), &spa, FTAG);
   953 	if (err)
   922 	if (err)
   954 		return (err);
   923 		return (err);
   955 	da.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
   924 	dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
   956 	da.snapname = snapname;
   925 
   957 	da.failed = fsname;
   926 	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
   958 	da.defer = defer;
   927 	    pair = nvlist_next_nvpair(snaps, pair)) {
   959 
   928 		dsl_dataset_t *ds;
   960 	err = dmu_objset_find(fsname,
   929 		int err;
   961 	    dsl_snapshot_destroy_one, &da, DS_FIND_CHILDREN);
   930 
       
   931 		err = dsl_dataset_own(nvpair_name(pair), B_TRUE, dstg, &ds);
       
   932 		if (err == 0) {
       
   933 			struct dsl_ds_destroyarg *dsda;
       
   934 
       
   935 			dsl_dataset_make_exclusive(ds, dstg);
       
   936 			dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg),
       
   937 			    KM_SLEEP);
       
   938 			dsda->ds = ds;
       
   939 			dsda->defer = defer;
       
   940 			dsl_sync_task_create(dstg, dsl_dataset_destroy_check,
       
   941 			    dsl_dataset_destroy_sync, dsda, dstg, 0);
       
   942 		} else if (err == ENOENT) {
       
   943 			err = 0;
       
   944 		} else {
       
   945 			(void) strcpy(failed, nvpair_name(pair));
       
   946 			break;
       
   947 		}
       
   948 	}
   962 
   949 
   963 	if (err == 0)
   950 	if (err == 0)
   964 		err = dsl_sync_task_group_wait(da.dstg);
   951 		err = dsl_sync_task_group_wait(dstg);
   965 
   952 
   966 	for (dst = list_head(&da.dstg->dstg_tasks); dst;
   953 	for (dst = list_head(&dstg->dstg_tasks); dst;
   967 	    dst = list_next(&da.dstg->dstg_tasks, dst)) {
   954 	    dst = list_next(&dstg->dstg_tasks, dst)) {
   968 		struct dsl_ds_destroyarg *dsda = dst->dst_arg1;
   955 		struct dsl_ds_destroyarg *dsda = dst->dst_arg1;
   969 		dsl_dataset_t *ds = dsda->ds;
   956 		dsl_dataset_t *ds = dsda->ds;
   970 
   957 
   971 		/*
   958 		/*
   972 		 * Return the file system name that triggered the error
   959 		 * Return the file system name that triggered the error
   973 		 */
   960 		 */
   974 		if (dst->dst_err) {
   961 		if (dst->dst_err) {
   975 			dsl_dataset_name(ds, fsname);
   962 			dsl_dataset_name(ds, failed);
   976 			*strchr(fsname, '@') = '\0';
       
   977 		}
   963 		}
   978 		ASSERT3P(dsda->rm_origin, ==, NULL);
   964 		ASSERT3P(dsda->rm_origin, ==, NULL);
   979 		dsl_dataset_disown(ds, da.dstg);
   965 		dsl_dataset_disown(ds, dstg);
   980 		kmem_free(dsda, sizeof (struct dsl_ds_destroyarg));
   966 		kmem_free(dsda, sizeof (struct dsl_ds_destroyarg));
   981 	}
   967 	}
   982 
   968 
   983 	dsl_sync_task_group_destroy(da.dstg);
   969 	dsl_sync_task_group_destroy(dstg);
   984 	spa_close(spa, FTAG);
   970 	spa_close(spa, FTAG);
   985 	return (err);
   971 	return (err);
       
   972 
   986 }
   973 }
   987 
   974 
   988 static boolean_t
   975 static boolean_t
   989 dsl_dataset_might_destroy_origin(dsl_dataset_t *ds)
   976 dsl_dataset_might_destroy_origin(dsl_dataset_t *ds)
   990 {
   977 {
  2141 
  2128 
  2142 	dsl_dir_dirty(ds->ds_dir, tx);
  2129 	dsl_dir_dirty(ds->ds_dir, tx);
  2143 	dmu_objset_sync(ds->ds_objset, zio, tx);
  2130 	dmu_objset_sync(ds->ds_objset, zio, tx);
  2144 }
  2131 }
  2145 
  2132 
       
  2133 static void
       
  2134 get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
       
  2135 {
       
  2136 	uint64_t count = 0;
       
  2137 	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
       
  2138 	zap_cursor_t zc;
       
  2139 	zap_attribute_t za;
       
  2140 	nvlist_t *propval;
       
  2141 	nvlist_t *val;
       
  2142 
       
  2143 	rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
       
  2144 	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
       
  2145 	VERIFY(nvlist_alloc(&val, NV_UNIQUE_NAME, KM_SLEEP) == 0);
       
  2146 
       
  2147 	/*
       
  2148 	 * There may me missing entries in ds_next_clones_obj
       
  2149 	 * due to a bug in a previous version of the code.
       
  2150 	 * Only trust it if it has the right number of entries.
       
  2151 	 */
       
  2152 	if (ds->ds_phys->ds_next_clones_obj != 0) {
       
  2153 		ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
       
  2154 		    &count));
       
  2155 	}
       
  2156 	if (count != ds->ds_phys->ds_num_children - 1) {
       
  2157 		goto fail;
       
  2158 	}
       
  2159 	for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
       
  2160 	    zap_cursor_retrieve(&zc, &za) == 0;
       
  2161 	    zap_cursor_advance(&zc)) {
       
  2162 		dsl_dataset_t *clone;
       
  2163 		char buf[ZFS_MAXNAMELEN];
       
  2164 		if (dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
       
  2165 		    za.za_first_integer, FTAG, &clone) != 0) {
       
  2166 			goto fail;
       
  2167 		}
       
  2168 		dsl_dir_name(clone->ds_dir, buf);
       
  2169 		VERIFY(nvlist_add_boolean(val, buf) == 0);
       
  2170 		dsl_dataset_rele(clone, FTAG);
       
  2171 	}
       
  2172 	zap_cursor_fini(&zc);
       
  2173 	VERIFY(nvlist_add_nvlist(propval, ZPROP_VALUE, val) == 0);
       
  2174 	VERIFY(nvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES),
       
  2175 	    propval) == 0);
       
  2176 fail:
       
  2177 	nvlist_free(val);
       
  2178 	nvlist_free(propval);
       
  2179 	rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
       
  2180 }
       
  2181 
  2146 void
  2182 void
  2147 dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
  2183 dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
  2148 {
  2184 {
  2149 	uint64_t refd, avail, uobjs, aobjs, ratio;
  2185 	uint64_t refd, avail, uobjs, aobjs, ratio;
  2150 
  2186 
  2171 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS,
  2207 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS,
  2172 	    ds->ds_userrefs);
  2208 	    ds->ds_userrefs);
  2173 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
  2209 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
  2174 	    DS_IS_DEFER_DESTROY(ds) ? 1 : 0);
  2210 	    DS_IS_DEFER_DESTROY(ds) ? 1 : 0);
  2175 
  2211 
       
  2212 	if (ds->ds_phys->ds_prev_snap_obj != 0) {
       
  2213 		uint64_t written, comp, uncomp;
       
  2214 		dsl_pool_t *dp = ds->ds_dir->dd_pool;
       
  2215 		dsl_dataset_t *prev;
       
  2216 
       
  2217 		rw_enter(&dp->dp_config_rwlock, RW_READER);
       
  2218 		int err = dsl_dataset_hold_obj(dp,
       
  2219 		    ds->ds_phys->ds_prev_snap_obj, FTAG, &prev);
       
  2220 		rw_exit(&dp->dp_config_rwlock);
       
  2221 		if (err == 0) {
       
  2222 			err = dsl_dataset_space_written(prev, ds, &written,
       
  2223 			    &comp, &uncomp);
       
  2224 			dsl_dataset_rele(prev, FTAG);
       
  2225 			if (err == 0) {
       
  2226 				dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
       
  2227 				    written);
       
  2228 			}
       
  2229 		}
       
  2230 	}
       
  2231 
  2176 	ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
  2232 	ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
  2177 	    (ds->ds_phys->ds_uncompressed_bytes * 100 /
  2233 	    (ds->ds_phys->ds_uncompressed_bytes * 100 /
  2178 	    ds->ds_phys->ds_compressed_bytes);
  2234 	    ds->ds_phys->ds_compressed_bytes);
  2179 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
  2235 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
  2180 
  2236 
  2184 		 * our unique space and compression ratio.
  2240 		 * our unique space and compression ratio.
  2185 		 */
  2241 		 */
  2186 		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
  2242 		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
  2187 		    ds->ds_phys->ds_unique_bytes);
  2243 		    ds->ds_phys->ds_unique_bytes);
  2188 		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
  2244 		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
       
  2245 
       
  2246 		get_clones_stat(ds, nv);
  2189 	}
  2247 	}
  2190 }
  2248 }
  2191 
  2249 
  2192 void
  2250 void
  2193 dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat)
  2251 dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat)
  4010 	dsl_dataset_rele(ds, FTAG);
  4068 	dsl_dataset_rele(ds, FTAG);
  4011 	return (0);
  4069 	return (0);
  4012 }
  4070 }
  4013 
  4071 
  4014 /*
  4072 /*
  4015  * Note, this fuction is used as the callback for dmu_objset_find().  We
  4073  * Note, this function is used as the callback for dmu_objset_find().  We
  4016  * always return 0 so that we will continue to find and process
  4074  * always return 0 so that we will continue to find and process
  4017  * inconsistent datasets, even if we encounter an error trying to
  4075  * inconsistent datasets, even if we encounter an error trying to
  4018  * process one of them.
  4076  * process one of them.
  4019  */
  4077  */
  4020 /* ARGSUSED */
  4078 /* ARGSUSED */
  4029 		else
  4087 		else
  4030 			dsl_dataset_disown(ds, FTAG);
  4088 			dsl_dataset_disown(ds, FTAG);
  4031 	}
  4089 	}
  4032 	return (0);
  4090 	return (0);
  4033 }
  4091 }
       
  4092 
       
  4093 /*
       
  4094  * Return (in *usedp) the amount of space written in new that is not
       
  4095  * present in oldsnap.  New may be a snapshot or the head.  Old must be
       
  4096  * a snapshot before new, in new's filesystem (or its origin).  If not then
       
  4097  * fail and return EINVAL.
       
  4098  *
       
  4099  * The written space is calculated by considering two components:  First, we
       
  4100  * ignore any freed space, and calculate the written as new's used space
       
  4101  * minus old's used space.  Next, we add in the amount of space that was freed
       
  4102  * between the two snapshots, thus reducing new's used space relative to old's.
       
  4103  * Specifically, this is the space that was born before old->ds_creation_txg,
       
  4104  * and freed before new (ie. on new's deadlist or a previous deadlist).
       
  4105  *
       
  4106  * space freed                         [---------------------]
       
  4107  * snapshots                       ---O-------O--------O-------O------
       
  4108  *                                         oldsnap            new
       
  4109  */
       
  4110 int
       
  4111 dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
       
  4112     uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
       
  4113 {
       
  4114 	int err = 0;
       
  4115 	uint64_t snapobj;
       
  4116 	dsl_pool_t *dp = new->ds_dir->dd_pool;
       
  4117 
       
  4118 	*usedp = 0;
       
  4119 	*usedp += new->ds_phys->ds_used_bytes;
       
  4120 	*usedp -= oldsnap->ds_phys->ds_used_bytes;
       
  4121 
       
  4122 	*compp = 0;
       
  4123 	*compp += new->ds_phys->ds_compressed_bytes;
       
  4124 	*compp -= oldsnap->ds_phys->ds_compressed_bytes;
       
  4125 
       
  4126 	*uncompp = 0;
       
  4127 	*uncompp += new->ds_phys->ds_uncompressed_bytes;
       
  4128 	*uncompp -= oldsnap->ds_phys->ds_uncompressed_bytes;
       
  4129 
       
  4130 	rw_enter(&dp->dp_config_rwlock, RW_READER);
       
  4131 	snapobj = new->ds_object;
       
  4132 	while (snapobj != oldsnap->ds_object) {
       
  4133 		dsl_dataset_t *snap;
       
  4134 		uint64_t used, comp, uncomp;
       
  4135 
       
  4136 		err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
       
  4137 		if (err != 0)
       
  4138 			break;
       
  4139 
       
  4140 		if (snap->ds_phys->ds_prev_snap_txg ==
       
  4141 		    oldsnap->ds_phys->ds_creation_txg) {
       
  4142 			/*
       
  4143 			 * The blocks in the deadlist can not be born after
       
  4144 			 * ds_prev_snap_txg, so get the whole deadlist space,
       
  4145 			 * which is more efficient (especially for old-format
       
  4146 			 * deadlists).  Unfortunately the deadlist code
       
  4147 			 * doesn't have enough information to make this
       
  4148 			 * optimization itself.
       
  4149 			 */
       
  4150 			dsl_deadlist_space(&snap->ds_deadlist,
       
  4151 			    &used, &comp, &uncomp);
       
  4152 		} else {
       
  4153 			dsl_deadlist_space_range(&snap->ds_deadlist,
       
  4154 			    0, oldsnap->ds_phys->ds_creation_txg,
       
  4155 			    &used, &comp, &uncomp);
       
  4156 		}
       
  4157 		*usedp += used;
       
  4158 		*compp += comp;
       
  4159 		*uncompp += uncomp;
       
  4160 
       
  4161 		/*
       
  4162 		 * If we get to the beginning of the chain of snapshots
       
  4163 		 * (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
       
  4164 		 * was not a snapshot of/before new.
       
  4165 		 */
       
  4166 		snapobj = snap->ds_phys->ds_prev_snap_obj;
       
  4167 		dsl_dataset_rele(snap, FTAG);
       
  4168 		if (snapobj == 0) {
       
  4169 			err = EINVAL;
       
  4170 			break;
       
  4171 		}
       
  4172 
       
  4173 	}
       
  4174 	rw_exit(&dp->dp_config_rwlock);
       
  4175 	return (err);
       
  4176 }
       
  4177 
       
  4178 /*
       
  4179  * Return (in *usedp) the amount of space that will be reclaimed if firstsnap,
       
  4180  * lastsnap, and all snapshots in between are deleted.
       
  4181  *
       
  4182  * blocks that would be freed            [---------------------------]
       
  4183  * snapshots                       ---O-------O--------O-------O--------O
       
  4184  *                                        firstsnap        lastsnap
       
  4185  *
       
  4186  * This is the set of blocks that were born after the snap before firstsnap,
       
  4187  * (birth > firstsnap->prev_snap_txg) and died before the snap after the
       
  4188  * last snap (ie, is on lastsnap->ds_next->ds_deadlist or an earlier deadlist).
       
  4189  * We calculate this by iterating over the relevant deadlists (from the snap
       
  4190  * after lastsnap, backward to the snap after firstsnap), summing up the
       
  4191  * space on the deadlist that was born after the snap before firstsnap.
       
  4192  */
       
  4193 int
       
  4194 dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap,
       
  4195     dsl_dataset_t *lastsnap,
       
  4196     uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
       
  4197 {
       
  4198 	int err = 0;
       
  4199 	uint64_t snapobj;
       
  4200 	dsl_pool_t *dp = firstsnap->ds_dir->dd_pool;
       
  4201 
       
  4202 	ASSERT(dsl_dataset_is_snapshot(firstsnap));
       
  4203 	ASSERT(dsl_dataset_is_snapshot(lastsnap));
       
  4204 
       
  4205 	/*
       
  4206 	 * Check that the snapshots are in the same dsl_dir, and firstsnap
       
  4207 	 * is before lastsnap.
       
  4208 	 */
       
  4209 	if (firstsnap->ds_dir != lastsnap->ds_dir ||
       
  4210 	    firstsnap->ds_phys->ds_creation_txg >
       
  4211 	    lastsnap->ds_phys->ds_creation_txg)
       
  4212 		return (EINVAL);
       
  4213 
       
  4214 	*usedp = *compp = *uncompp = 0;
       
  4215 
       
  4216 	rw_enter(&dp->dp_config_rwlock, RW_READER);
       
  4217 	snapobj = lastsnap->ds_phys->ds_next_snap_obj;
       
  4218 	while (snapobj != firstsnap->ds_object) {
       
  4219 		dsl_dataset_t *ds;
       
  4220 		uint64_t used, comp, uncomp;
       
  4221 
       
  4222 		err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &ds);
       
  4223 		if (err != 0)
       
  4224 			break;
       
  4225 
       
  4226 		dsl_deadlist_space_range(&ds->ds_deadlist,
       
  4227 		    firstsnap->ds_phys->ds_prev_snap_txg, UINT64_MAX,
       
  4228 		    &used, &comp, &uncomp);
       
  4229 		*usedp += used;
       
  4230 		*compp += comp;
       
  4231 		*uncompp += uncomp;
       
  4232 
       
  4233 		snapobj = ds->ds_phys->ds_prev_snap_obj;
       
  4234 		ASSERT3U(snapobj, !=, 0);
       
  4235 		dsl_dataset_rele(ds, FTAG);
       
  4236 	}
       
  4237 	rw_exit(&dp->dp_config_rwlock);
       
  4238 	return (err);
       
  4239 }