Skip to content

Commit

Permalink
Remove ZFC_IOC_*_MINOR ioctl()s
Browse files Browse the repository at this point in the history
Early versions of ZFS coordinated the creation and destruction
of device minors from userspace.  This was inherently racy and
in late 2009 these ioctl()s were removed leaving everything up
to the kernel.  This significantly simplified the code.

However, we never picked up these changes in ZoL since we'd
already significantly adjusted this code for Linux.  This patch
aims to rectify that by finally removing ZFC_IOC_*_MINOR ioctl()s
and moving all the functionality down in to the kernel.  Since
this cleanup will change the kernel/user ABI it's being done
in the same tag as the previous libzfs_core ABI changes.  This
will minimize, but not eliminate, the disruption to end users.

Once merged ZoL, Illumos, and FreeBSD will basically be back
in sync in regards to handling ZVOLs in the common code.  While
each platform must have its own custom zvol.c implemenation the
interfaces provided are consistent.

NOTES:

1) This patch introduces one subtle change in behavior which
   could not be easily avoided.  Prior to this change callers
   of 'zfs create -V ...' were guaranteed that upon exit the
   /dev/zvol/ block device link would be created or an error
   returned.  That's no longer the case.  The utilities will no
   longer block waiting for the symlink to be created.  Callers
   are now responsible for blocking, this is why a 'udev_wait'
   call was added to the 'label' function in scripts/common.sh.

2) The read-only behavior of a ZVOL now solely depends on if
   the ZVOL_RDONLY bit is set in zv->zv_flags.  The redundant
   policy setting in the gendisk structure was removed.  This
   both simplifies the code and allows us to safely leverage
   set_disk_ro() to issue a KOBJ_CHANGE uevent.  See the
   comment in the code for futher details on this.

3) Because __zvol_create_minor() and zvol_alloc() may now be
   called in a sync task they must use KM_PUSHPAGE.

References:
  illumos/illumos-gate@681d976

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Signed-off-by: Tim Chase <tim@chase2k.com>
Closes #1969
  • Loading branch information
behlendorf committed Dec 16, 2013
1 parent dda12da commit ba6a240
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 456 deletions.
2 changes: 0 additions & 2 deletions include/libzfs_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);

int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);

int zvol_create_link(libzfs_handle_t *, const char *);
int zvol_remove_link(libzfs_handle_t *, const char *);
boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);

int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
Expand Down
2 changes: 0 additions & 2 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,8 +793,6 @@ typedef enum zfs_ioc {
ZFS_IOC_DATASET_LIST_NEXT,
ZFS_IOC_SNAPSHOT_LIST_NEXT,
ZFS_IOC_SET_PROP,
ZFS_IOC_CREATE_MINOR,
ZFS_IOC_REMOVE_MINOR,
ZFS_IOC_CREATE,
ZFS_IOC_DESTROY,
ZFS_IOC_ROLLBACK,
Expand Down
2 changes: 2 additions & 0 deletions include/sys/zfs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
extern int zfs_unmount_snap(const char *);
extern void zfs_destroy_unmount_origin(const char *);

extern boolean_t dataset_name_hidden(const char *name);

enum zfsdev_state_type {
ZST_ONEXIT,
ZST_ZEVENT,
Expand Down
9 changes: 5 additions & 4 deletions include/sys/zvol.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ extern int zvol_check_volblocksize(uint64_t volblocksize);
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
extern boolean_t zvol_is_zvol(const char *);
extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
extern int zvol_create_minor(const char *);
extern int zvol_create_minors(char *);
extern int zvol_remove_minor(const char *);
extern void zvol_remove_minors(const char *);
extern int zvol_create_minor(const char *name);
extern int zvol_create_minors(const char *name);
extern int zvol_remove_minor(const char *name);
extern void zvol_remove_minors(const char *name);
extern void zvol_rename_minors(const char *oldname, const char *newname);
extern int zvol_set_volsize(const char *, uint64_t);
extern int zvol_set_volblocksize(const char *, uint64_t);
extern int zvol_set_snapdev(const char *, uint64_t);
Expand Down
18 changes: 5 additions & 13 deletions lib/libzfs/libzfs_changelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,30 +291,22 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)

for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
zfs_handle_t *hdl;

hdl = cn->cn_handle;

/*
* Do not rename a clone that's not in the source hierarchy.
*/
if (!isa_child_of(hdl->zfs_name, src))
if (!isa_child_of(cn->cn_handle->zfs_name, src))
continue;

/*
* Destroy the previous mountpoint if needed.
*/
remove_mountpoint(hdl);
remove_mountpoint(cn->cn_handle);

(void) strlcpy(newname, dst, sizeof (newname));
(void) strcat(newname, hdl->zfs_name + strlen(src));

if (ZFS_IS_VOLUME(hdl)) {
(void) zvol_remove_link(hdl->zfs_hdl, hdl->zfs_name);
(void) zvol_create_link(hdl->zfs_hdl, newname);
}
(void) strcat(newname, cn->cn_handle->zfs_name + strlen(src));

(void) strlcpy(hdl->zfs_name, newname, sizeof (hdl->zfs_name));
(void) strlcpy(cn->cn_handle->zfs_name, newname,
sizeof (cn->cn_handle->zfs_name));
}
}

Expand Down
Loading

0 comments on commit ba6a240

Please sign in to comment.