Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143418820
D21795.id62751.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D21795.id62751.diff
View Options
Index: cddl/contrib/opensolaris/cmd/zfs/zfs.8
===================================================================
--- cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -105,6 +105,9 @@
.Ar snapshot snapshot
.Nm
.Cm rename
+.Ar bookmark bookmark
+.Nm
+.Cm rename
.Fl u
.Op Fl p
.Ar filesystem filesystem
@@ -2092,6 +2095,16 @@
.Pp
Recursively rename the snapshots of all descendent datasets. Snapshots are the
only dataset that can be renamed recursively.
+.It Xo
+.Nm
+.Cm rename
+.Ar bookmark bookmark
+.Xc
+.Pp
+Renames the given bookmark.
+Bookmarks can only be renamed within the parent file system or volume.
+When renaming a bookmark, the parent file system or volume of the bookmark
+does not need to be specified as part of the second argument.
.It Xo
.Nm
.Cm list
Index: cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
===================================================================
--- cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -284,6 +284,7 @@
"<filesystem|volume|snapshot>\n"
"\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
"\trename -r <snapshot> <snapshot>\n"
+ "\trename <bookmark> <bookmark>\n"
"\trename -u [-p] <filesystem> <filesystem>"));
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
@@ -3254,6 +3255,7 @@
* zfs rename [-f] <fs | snap | vol> <fs | snap | vol>
* zfs rename [-f] -p <fs | vol> <fs | vol>
* zfs rename -r <snap> <snap>
+ * zfs rename <bmark> <bmark>
* zfs rename -u [-p] <fs> <fs>
*
* Renames the given dataset to another of the same type.
@@ -3270,6 +3272,7 @@
int ret = 0;
int types;
boolean_t parents = B_FALSE;
+ boolean_t bookmarks = B_FALSE;
char *snapshot = NULL;
/* check options */
@@ -3320,7 +3323,7 @@
usage(B_FALSE);
}
- if (flags.recurse && strchr(argv[0], '@') == 0) {
+ if (flags.recurse && strchr(argv[0], '@') == NULL) {
(void) fprintf(stderr, gettext("source dataset for recursive "
"rename must be a snapshot\n"));
usage(B_FALSE);
@@ -3332,10 +3335,22 @@
usage(B_FALSE);
}
+ if (strchr(argv[0], '#') != NULL)
+ bookmarks = B_TRUE;
+
+ if (bookmarks && (flags.nounmount || flags.recurse ||
+ flags.forceunmount || parents)) {
+ (void) fprintf(stderr, gettext("options are not supported "
+ "for renaming bookmarks\n"));
+ usage(B_FALSE);
+ }
+
if (flags.nounmount)
types = ZFS_TYPE_FILESYSTEM;
else if (parents)
types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+ else if (bookmarks)
+ types = ZFS_TYPE_BOOKMARK;
else
types = ZFS_TYPE_DATASET;
Index: cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
===================================================================
--- cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -4291,17 +4291,18 @@
/*
* Make sure the target name is valid
*/
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- if ((strchr(target, '@') == NULL) ||
- *target == '@') {
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT ||
+ zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
+ const char sep = zhp->zfs_type == ZFS_TYPE_SNAPSHOT ? '@' : '#';
+
+ if ((strchr(target, sep) == NULL) || *target == sep) {
/*
* Snapshot target name is abbreviated,
* reconstruct full dataset name
*/
- (void) strlcpy(parent, zhp->zfs_name,
- sizeof (parent));
- delim = strchr(parent, '@');
- if (strchr(target, '@') == NULL)
+ (void) strlcpy(parent, zhp->zfs_name, sizeof (parent));
+ delim = strchr(parent, sep);
+ if (strchr(target, sep) == NULL)
*(++delim) = '\0';
else
*delim = '\0';
@@ -4311,12 +4312,13 @@
/*
* Make sure we're renaming within the same dataset.
*/
- delim = strchr(target, '@');
+ delim = strchr(target, sep);
if (strncmp(zhp->zfs_name, target, delim - target)
- != 0 || zhp->zfs_name[delim - target] != '@') {
+ != 0 || zhp->zfs_name[delim - target] != sep) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots must be part of same "
- "dataset"));
+ "%s must be part of same dataset"),
+ zhp->zfs_type == ZFS_TYPE_SNAPSHOT ?
+ "snapshots" : "bookmarks");
return (zfs_error(hdl, EZFS_CROSSTARGET,
errbuf));
}
@@ -4379,7 +4381,6 @@
flags.nounmount = B_TRUE;
}
if (flags.recurse) {
-
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
if (parentname == NULL) {
ret = -1;
@@ -4392,7 +4393,8 @@
ret = -1;
goto error;
}
- } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
+ } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT &&
+ zhp->zfs_type != ZFS_TYPE_BOOKMARK) {
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
flags.nounmount ? CL_GATHER_DONT_UNMOUNT : 0,
flags.forceunmount ? MS_FORCE : 0)) == NULL) {
@@ -4437,6 +4439,8 @@
"a child dataset already has a snapshot "
"with the new name"));
(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
+ } else if (errno == EINVAL) {
+ (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
} else {
(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
}
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c
@@ -459,3 +459,108 @@
fnvlist_free(dbda.dbda_success);
return (rv);
}
+
+typedef struct dsl_bookmark_rename_arg {
+ const char *dbra_fsname;
+ const char *dbra_oldname;
+ const char *dbra_newname;
+} dsl_bookmark_rename_arg_t;
+
+static int
+dsl_bookmark_rename_check(void *arg, dmu_tx_t *tx)
+{
+ dsl_bookmark_rename_arg_t *dbra = arg;
+ dsl_pool_t *dp = dmu_tx_pool(tx);
+ dsl_dataset_t *ds;
+ zfs_bookmark_phys_t bmark_phys;
+ int error;
+
+ if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARKS))
+ return (SET_ERROR(ENOTSUP));
+
+ /* Check validity and the full length of the new bookmark name. */
+ if (zfs_component_namecheck(dbra->dbra_newname, NULL, NULL))
+ return (SET_ERROR(EINVAL));
+ if (strlen(dbra->dbra_fsname) + strlen(dbra->dbra_newname) + 1 >=
+ ZFS_MAX_DATASET_NAME_LEN)
+ return (SET_ERROR(ENAMETOOLONG));
+
+ error = dsl_dataset_hold(dp, dbra->dbra_fsname, FTAG, &ds);
+ if (error != 0)
+ return (error);
+ if (ds->ds_is_snapshot) {
+ dsl_dataset_rele(ds, FTAG);
+ return (SET_ERROR(EINVAL));
+ }
+ error = dsl_dataset_bmark_lookup(ds, dbra->dbra_oldname, &bmark_phys);
+ if (error != 0) {
+ dsl_dataset_rele(ds, FTAG);
+ return (error);
+ }
+
+ error = dsl_dataset_bmark_lookup(ds, dbra->dbra_newname, &bmark_phys);
+ dsl_dataset_rele(ds, FTAG);
+ if (error == 0)
+ return (SET_ERROR(EEXIST));
+ if (error != ESRCH)
+ return (error);
+ return (0);
+}
+
+static void
+dsl_bookmark_rename_sync(void *arg, dmu_tx_t *tx)
+{
+ zfs_bookmark_phys_t bmark_phys;
+ dsl_bookmark_rename_arg_t *dbra = arg;
+ dsl_pool_t *dp = dmu_tx_pool(tx);
+ objset_t *mos;
+ dsl_dataset_t *ds;
+ uint64_t bmark_zapobj;
+ uint64_t int_size, num_ints;
+ matchtype_t mt = 0;
+ int error;
+
+ ASSERT(spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARKS));
+ VERIFY0(dsl_dataset_hold(dp, dbra->dbra_fsname, FTAG, &ds));
+
+ mos = ds->ds_dir->dd_pool->dp_meta_objset;
+ bmark_zapobj = ds->ds_bookmarks;
+
+ if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+ mt = MT_NORMALIZE;
+
+ VERIFY0(zap_length(mos, bmark_zapobj, dbra->dbra_oldname,
+ &int_size, &num_ints));
+ ASSERT3U(int_size, ==, sizeof (uint64_t));
+ VERIFY0(zap_lookup_norm(mos, bmark_zapobj, dbra->dbra_oldname, int_size,
+ num_ints, &bmark_phys, mt, NULL, 0, NULL));
+ VERIFY0(zap_remove_norm(mos, bmark_zapobj, dbra->dbra_oldname, mt, tx));
+
+ VERIFY0(zap_add(mos, bmark_zapobj, dbra->dbra_newname, int_size,
+ num_ints, &bmark_phys, tx));
+
+ spa_history_log_internal_ds(ds, "rename bookmark", tx,
+ "#%s -> #%s creation_txg=%llu",
+ dbra->dbra_oldname, dbra->dbra_newname,
+ (longlong_t)bmark_phys.zbm_creation_txg);
+
+ dsl_dataset_rele(ds, FTAG);
+}
+
+/*
+ * The bookmarks must all be in the same pool.
+ */
+int
+dsl_bookmark_rename(const char *fsname, const char *oldbmark,
+ const char *newbmark)
+{
+ dsl_bookmark_rename_arg_t dbra;
+
+ dbra.dbra_fsname = fsname;
+ dbra.dbra_oldname = oldbmark;
+ dbra.dbra_newname = newbmark;
+
+ return (dsl_sync_task(fsname, dsl_bookmark_rename_check,
+ dsl_bookmark_rename_sync, &dbra, 1, ZFS_SPACE_CHECK_NORMAL));
+}
+
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_bookmark.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_bookmark.h
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_bookmark.h
@@ -41,6 +41,7 @@
int dsl_get_bookmarks(const char *, nvlist_t *, nvlist_t *);
int dsl_get_bookmarks_impl(dsl_dataset_t *, nvlist_t *, nvlist_t *);
int dsl_bookmark_destroy(nvlist_t *, nvlist_t *);
+int dsl_bookmark_rename(const char *fs, const char *from, const char *to);
int dsl_bookmark_lookup(struct dsl_pool *, const char *,
struct dsl_dataset *, zfs_bookmark_phys_t *);
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -224,7 +224,8 @@
typedef enum {
NO_NAME,
POOL_NAME,
- DATASET_NAME
+ DATASET_NAME,
+ ENTITY_NAME
} zfs_ioc_namecheck_t;
typedef enum {
@@ -922,8 +923,21 @@
zfs_secpolicy_rename(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
{
char *at = NULL;
+ char *pound;
int error;
+ if ((pound = strchr(zc->zc_name, '#')) != NULL) {
+ *pound = '\0';
+ error = zfs_secpolicy_write_perms(zc->zc_name,
+ ZFS_DELEG_PERM_RENAME, cr);
+ if (error == 0) {
+ error = zfs_secpolicy_write_perms(zc->zc_name,
+ ZFS_DELEG_PERM_BOOKMARK, cr);
+ }
+ *pound = '#';
+ return (error);
+ }
+
if ((zc->zc_cookie & 1) != 0) {
/*
* This is recursive rename, so the starting snapshot might
@@ -4020,8 +4034,8 @@
/*
* inputs:
- * zc_name old name of dataset
- * zc_value new name of dataset
+ * zc_name old name of dataset or bookmark
+ * zc_value new name of dataset or bookmark
* zc_cookie recursive flag (only valid for snapshots)
*
* outputs: none
@@ -4032,7 +4046,7 @@
objset_t *os;
dmu_objset_type_t ost;
boolean_t recursive = zc->zc_cookie & 1;
- char *at;
+ char *pos, *pos2;
boolean_t allow_mounted = B_TRUE;
int err;
@@ -4040,9 +4054,34 @@
allow_mounted = (zc->zc_cookie & 2) != 0;
#endif
- /* "zfs rename" from and to ...%recv datasets should both fail */
zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
+
+ pos = strchr(zc->zc_name, '#');
+ if (pos != NULL) {
+ /* Bookmarks must be in same fs. */
+ pos2 = strchr(zc->zc_value, '#');
+ if (pos2 == NULL)
+ return (SET_ERROR(EINVAL));
+
+ /* Recursive flag is not supported yet. */
+ if (recursive)
+ return (SET_ERROR(ENOTSUP));
+
+ *pos = '\0';
+ *pos2 = '\0';
+ if (strcmp(zc->zc_name, zc->zc_value) == 0) {
+ err = dsl_bookmark_rename(zc->zc_name,
+ pos + 1, pos2 + 1);
+ } else {
+ err = SET_ERROR(EXDEV);
+ }
+ *pos = '#';
+ *pos2 = '#';
+ return (err);
+ }
+
+ /* "zfs rename" from and to ...%recv datasets should both fail */
if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0 ||
dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
strchr(zc->zc_name, '%') || strchr(zc->zc_value, '%'))
@@ -4054,28 +4093,30 @@
ost = dmu_objset_type(os);
dmu_objset_rele(os, FTAG);
- at = strchr(zc->zc_name, '@');
- if (at != NULL) {
- /* snaps must be in same fs */
- int error;
-
- if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
- return (SET_ERROR(EXDEV));
- *at = '\0';
- if (ost == DMU_OST_ZFS && !allow_mounted) {
- error = dmu_objset_find(zc->zc_name,
- recursive_unmount, at + 1,
- recursive ? DS_FIND_CHILDREN : 0);
- if (error != 0) {
- *at = '@';
- return (error);
+ pos = strchr(zc->zc_name, '@');
+ if (pos != NULL) {
+ /* Snapshots must be in same fs. */
+ pos2 = strchr(zc->zc_value, '@');
+ if (pos2 == NULL)
+ return (SET_ERROR(EINVAL));
+ *pos = '\0';
+ *pos2 = '\0';
+ if (strcmp(zc->zc_name, zc->zc_value) != 0) {
+ err = SET_ERROR(EXDEV);
+ } else {
+ if (ost == DMU_OST_ZFS && !allow_mounted) {
+ err = dmu_objset_find(zc->zc_name,
+ recursive_unmount, pos + 1,
+ recursive ? DS_FIND_CHILDREN : 0);
}
+ if (err == 0) {
+ err = dsl_dataset_rename_snapshot(zc->zc_name,
+ pos + 1, pos2 + 1, recursive);
+ }
}
- error = dsl_dataset_rename_snapshot(zc->zc_name,
- at + 1, strchr(zc->zc_value, '@') + 1, recursive);
- *at = '@';
-
- return (error);
+ *pos = '@';
+ *pos2 = '@';
+ return (err);
} else {
#ifdef illumos
if (ost == DMU_OST_ZVOL)
@@ -6352,8 +6393,6 @@
zfs_secpolicy_none);
zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
zfs_secpolicy_destroy);
- zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
- zfs_secpolicy_rename);
zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
zfs_secpolicy_recv);
zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
@@ -6363,6 +6402,14 @@
zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
zfs_secpolicy_set_fsacl);
+ /*
+ * Not using zfs_ioctl_register_dataset_modify as DATASET_NAME check
+ * won't allow a bookmark name.
+ */
+ zfs_ioctl_register_legacy(ZFS_IOC_RENAME, zfs_ioc_rename,
+ zfs_secpolicy_rename, ENTITY_NAME, B_TRUE,
+ POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
+
zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
zfs_secpolicy_share, POOL_CHECK_NONE);
zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
@@ -6392,7 +6439,8 @@
spa_t *spa;
int error;
- ASSERT(type == POOL_NAME || type == DATASET_NAME);
+ ASSERT(type == POOL_NAME || type == DATASET_NAME ||
+ type == ENTITY_NAME);
if (check & POOL_CHECK_NONE)
return (0);
@@ -6723,6 +6771,15 @@
else
error = pool_status_check(zc->zc_name,
vec->zvec_namecheck, vec->zvec_pool_check);
+ break;
+
+ case ENTITY_NAME:
+ if (entity_namecheck(zc->zc_name, NULL, NULL) != 0) {
+ error = SET_ERROR(EINVAL);
+ } else {
+ error = pool_status_check(zc->zc_name,
+ vec->zvec_namecheck, vec->zvec_pool_check);
+ }
break;
case NO_NAME:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 31, 6:11 AM (8 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28109177
Default Alt Text
D21795.id62751.diff (14 KB)
Attached To
Mode
D21795: ZFS: add bookmark renaming
Attached
Detach File
Event Timeline
Log In to Comment