Skip to content
Permalink
Browse files

move zvol_{init, fini} to platform code

Requires-builders: build
  • Loading branch information...
mattmacy committed Sep 11, 2019
1 parent 93a7fb0 commit f47469bff904e9ece38277e0c8cfc4016dd1a6af
Showing with 58 additions and 59 deletions.
  1. +12 −11 include/sys/zvol_impl.h
  2. +19 −11 module/os/linux/zfs/zvol_os.c
  3. +1 −1 module/zfs/zfs_ioctl.c
  4. +26 −36 module/zfs/zvol.c
@@ -70,10 +70,10 @@ extern zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE];
extern unsigned int zvol_volmode;
extern unsigned int zvol_inhibit_dev;
extern unsigned int zvol_threads;

/*
* platform independent functions exported to platform code
*/

zvol_state_t *zvol_find_by_name_hash(const char *name, uint64_t hash, int mode);
int zvol_first_open(zvol_state_t *zv, boolean_t readonly);
uint64_t zvol_name_hash(const char *name);
@@ -86,21 +86,22 @@ void zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
uint64_t size, int sync);
int zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb,
zio_t *zio);
int zvol_init_impl(void);
void zvol_fini_impl(void);

/*
* platform dependent functions exported to platform independent code
*/

typedef struct zvol_platform_ops {
int (*zvol_setup_zv)(zvol_state_t *);
void (*zvol_free)(void *);
void (*zvol_rename_minor)(zvol_state_t *, const char *);
int (*zvol_create_minor_impl)(const char *);
int (*zvol_os_update_volsize)(zvol_state_t *, uint64_t);
void (*zvol_os_clear_private)(zvol_state_t *);
boolean_t (*zvol_is_zvol)(const char *);
int (*zv_setup_zv)(zvol_state_t *);
void (*zv_free)(void *);
void (*zv_rename_minor)(zvol_state_t *, const char *);
int (*zv_create_minor_impl)(const char *);
int (*zv_os_update_volsize)(zvol_state_t *, uint64_t);
void (*zv_os_clear_private)(zvol_state_t *);
boolean_t (*zv_is_zvol)(const char *);
} zvol_platform_ops_t;

extern int zvol_os_init(zvol_platform_ops_t *ops);
extern void zvol_os_fini(void);
void zvol_register_ops(const zvol_platform_ops_t *ops);

#endif
@@ -1131,18 +1131,18 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname)
set_disk_ro(zv->zv_disk, readonly);
}

static zvol_platform_ops_t linux_ops = {
zvol_setup_zv,
zvol_free,
zvol_rename_minor,
zvol_create_minor_impl,
zvol_os_update_volsize,
zvol_os_clear_private,
linux_zvol_is_zvol
const static zvol_platform_ops_t zvol_linux_ops = {
.zv_setup_zv = zvol_setup_zv,
.zv_free = zvol_free,
.zv_rename_minor = zvol_rename_minor,
.zv_create_minor_impl = zvol_create_minor_impl,
.zv_os_update_volsize = zvol_os_update_volsize,
.zv_os_clear_private = zvol_os_clear_private,
.zv_is_zvol = linux_zvol_is_zvol
};

int
zvol_os_init(zvol_platform_ops_t *ops)
zvol_init(void)
{
int error;

@@ -1151,19 +1151,27 @@ zvol_os_init(zvol_platform_ops_t *ops)
printk(KERN_INFO "ZFS: register_blkdev() failed %d\n", error);
return (error);
}
error = zvol_init_impl();
if (error) {
printk(KERN_INFO "ZFS: zvol_init_impl() failed %d\n", error);
unregister_blkdev(zvol_major, ZVOL_DRIVER);
return (-error);
}

blk_register_region(MKDEV(zvol_major, 0), 1UL << MINORBITS,
THIS_MODULE, zvol_probe, NULL, NULL);

ida_init(&zvol_ida);
*ops = linux_ops;
zvol_register_ops(&zvol_linux_ops);
return (0);
}

void
zvol_os_fini(void)
zvol_fini(void)
{
zvol_remove_minors_impl(NULL);

zvol_fini_impl();
blk_unregister_region(MKDEV(zvol_major, 0), 1UL << MINORBITS);
unregister_blkdev(zvol_major, ZVOL_DRIVER);

@@ -7616,7 +7616,7 @@ _init(void)
{
int error;

if ((error = -zvol_init()) != 0)
if ((error = zvol_init()) != 0)
return (error);

spa_init(FREAD | FWRITE);
@@ -108,7 +108,7 @@ struct hlist_head *zvol_htable;
list_t zvol_state_list;
taskq_t *zvol_taskq;
krwlock_t zvol_state_lock;
zvol_platform_ops_t ops;
const zvol_platform_ops_t *ops;

typedef enum {
ZVOL_ASYNC_CREATE_MINORS,
@@ -384,7 +384,7 @@ zvol_set_volsize(const char *name, uint64_t volsize)
mutex_exit(&zv->zv_state_lock);

if (error == 0 && zv != NULL)
ops.zvol_os_update_volsize(zv, volsize);
ops->zv_os_update_volsize(zv, volsize);

return (SET_ERROR(error));
}
@@ -848,7 +848,7 @@ zvol_resume(zvol_state_t *zv)
VERIFY(dsl_dataset_long_held(zv->zv_objset->os_dsl_dataset));
dmu_objset_rele(zv->zv_objset, zv);

error = ops.zvol_setup_zv(zv);
error = ops->zv_setup_zv(zv);
}

mutex_exit(&zv->zv_state_lock);
@@ -906,7 +906,7 @@ zvol_first_open(zvol_state_t *zv, boolean_t readonly)

zv->zv_objset = os;

error = ops.zvol_setup_zv(zv);
error = ops->zv_setup_zv(zv);

if (error) {
dmu_objset_disown(os, 1, zv);
@@ -1105,7 +1105,7 @@ zvol_create_minors_impl(const char *name)
&snapdev, NULL);

if (error == 0 && snapdev == ZFS_SNAPDEV_VISIBLE)
error = ops.zvol_create_minor_impl(name);
error = ops->zv_create_minor_impl(name);
} else {
cookie = spl_fstrans_mark();
error = dmu_objset_find(parent, zvol_create_minors_cb,
@@ -1123,7 +1123,7 @@ zvol_create_minors_impl(const char *name)
while ((job = list_head(&minors_list)) != NULL) {
list_remove(&minors_list, job);
if (!job->error)
ops.zvol_create_minor_impl(job->name);
ops->zv_create_minor_impl(job->name);
strfree(job->name);
kmem_free(job, sizeof (minors_job_t));
}
@@ -1175,13 +1175,13 @@ zvol_remove_minors_impl(const char *name)

zvol_remove(zv);

ops.zvol_os_clear_private(zv);
ops->zv_os_clear_private(zv);

/* Drop zv_state_lock before zvol_free() */
mutex_exit(&zv->zv_state_lock);

/* Try parallel zv_free, if failed do it in place */
t = taskq_dispatch(system_taskq, ops.zvol_free, zv,
t = taskq_dispatch(system_taskq, ops->zv_free, zv,
TQ_SLEEP);
if (t == TASKQID_INVALID)
list_insert_head(&free_list, zv);
@@ -1196,7 +1196,7 @@ zvol_remove_minors_impl(const char *name)
/* Drop zvol_state_lock before calling zvol_free() */
while ((zv = list_head(&free_list)) != NULL) {
list_remove(&free_list, zv);
ops.zvol_free(zv);
ops->zv_free(zv);
}

if (tid != TASKQID_INVALID)
@@ -1232,7 +1232,7 @@ zvol_remove_minor_impl(const char *name)
}
zvol_remove(zv);

ops.zvol_os_clear_private(zv);
ops->zv_os_clear_private(zv);
mutex_exit(&zv->zv_state_lock);
break;
} else {
@@ -1244,7 +1244,7 @@ zvol_remove_minor_impl(const char *name)
rw_exit(&zvol_state_lock);

if (zv != NULL)
ops.zvol_free(zv);
ops->zv_free(zv);
}

/*
@@ -1270,14 +1270,14 @@ zvol_rename_minors_impl(const char *oldname, const char *newname)
mutex_enter(&zv->zv_state_lock);

if (strcmp(zv->zv_name, oldname) == 0) {
ops.zvol_rename_minor(zv, newname);
ops->zv_rename_minor(zv, newname);
} else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 &&
(zv->zv_name[oldnamelen] == '/' ||
zv->zv_name[oldnamelen] == '@')) {
char *name = kmem_asprintf("%s%c%s", newname,
zv->zv_name[oldnamelen],
zv->zv_name + oldnamelen + 1);
ops.zvol_rename_minor(zv, name);
ops->zv_rename_minor(zv, name);
strfree(name);
}

@@ -1301,7 +1301,7 @@ zvol_set_snapdev_cb(const char *dsname, void *param)

switch (arg->snapdev) {
case ZFS_SNAPDEV_VISIBLE:
(void) ops.zvol_create_minor_impl(dsname);
(void) ops->zv_create_minor_impl(dsname);
break;
case ZFS_SNAPDEV_HIDDEN:
(void) zvol_remove_minor_impl(dsname);
@@ -1351,14 +1351,14 @@ zvol_set_volmode_impl(char *name, uint64_t volmode)
case ZFS_VOLMODE_GEOM:
case ZFS_VOLMODE_DEV:
(void) zvol_remove_minor_impl(name);
(void) ops.zvol_create_minor_impl(name);
(void) ops->zv_create_minor_impl(name);
break;
case ZFS_VOLMODE_DEFAULT:
(void) zvol_remove_minor_impl(name);
if (zvol_volmode == ZFS_VOLMODE_NONE)
break;
else /* if zvol_volmode is invalid defaults to "geom" */
(void) ops.zvol_create_minor_impl(name);
(void) ops->zv_create_minor_impl(name);
break;
}

@@ -1657,11 +1657,17 @@ boolean_t
zvol_is_zvol(const char *name)
{

return (ops.zvol_is_zvol(name));
return (ops->zv_is_zvol(name));
}

void
zvol_register_ops(const zvol_platform_ops_t *zvol_ops)
{
ops = zvol_ops;
};

int
zvol_init(void)
zvol_init_impl(void)
{
int threads = MIN(MAX(zvol_threads, 1), 1024);
int i, error;
@@ -1673,29 +1679,17 @@ zvol_init(void)
zvol_taskq = taskq_create(ZVOL_DRIVER, threads, maxclsyspri,
threads * 2, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
if (zvol_taskq == NULL) {
// printk(KERN_INFO "ZFS: taskq_create() failed\n");
error = -ENOMEM;
error = ENOMEM;
goto out;
}

zvol_htable = kmem_alloc(ZVOL_HT_SIZE * sizeof (struct hlist_head),
KM_SLEEP);
if (!zvol_htable) {
error = -ENOMEM;
goto out_taskq;
}
for (i = 0; i < ZVOL_HT_SIZE; i++)
INIT_HLIST_HEAD(&zvol_htable[i]);

if ((error = zvol_os_init(&ops)))
goto out_free;

return (0);

out_free:
kmem_free(zvol_htable, ZVOL_HT_SIZE * sizeof (struct hlist_head));
out_taskq:
taskq_destroy(zvol_taskq);
out:
rw_destroy(&zvol_state_lock);
list_destroy(&zvol_state_list);
@@ -1704,14 +1698,10 @@ zvol_init(void)
}

void
zvol_fini(void)
zvol_fini_impl(void)
{
zvol_remove_minors_impl(NULL);

kmem_free(zvol_htable, ZVOL_HT_SIZE * sizeof (struct hlist_head));

taskq_destroy(zvol_taskq);
list_destroy(&zvol_state_list);
rw_destroy(&zvol_state_lock);
zvol_os_fini();
}

0 comments on commit f47469b

Please sign in to comment.
You can’t perform that action at this time.