Implemented sharing datasets via NFS using libshare.
[zfs.git] / module / zfs / zfs_ioctl.c
index 994d65f..efb6bf5 100644 (file)
@@ -1107,8 +1107,9 @@ get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
 
        mutex_enter(&os->os_user_ptr_lock);
        *zsbp = dmu_objset_get_user(os);
-       if (*zsbp) {
-               mntget((*zsbp)->z_vfs);
+       if (*zsbp && (*zsbp)->z_sb) {
+               if (atomic_inc_not_zero(&((*zsbp)->z_sb->s_active)))
+                       error = ESRCH;
        } else {
                error = ESRCH;
        }
@@ -1119,7 +1120,7 @@ get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
 
 /*
  * Find a zfs_sb_t for a mounted filesystem, or create our own, in which
- * case its z_vfs will be NULL, and it will be opened as the owner.
+ * case its z_sb will be NULL, and it will be opened as the owner.
  */
 static int
 zfs_sb_hold(const char *name, void *tag, zfs_sb_t **zsbp, boolean_t writer)
@@ -1149,8 +1150,8 @@ zfs_sb_rele(zfs_sb_t *zsb, void *tag)
 {
        rrw_exit(&zsb->z_teardown_lock, tag);
 
-       if (zsb->z_vfs) {
-               mntput(zsb->z_vfs);
+       if (zsb->z_sb) {
+               deactivate_super(zsb->z_sb);
        } else {
                dmu_objset_disown(zsb->z_os, zsb);
                zfs_sb_free(zsb);
@@ -1441,7 +1442,7 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
                return (ENOTSUP);
        }
 
-       hist_buf = kmem_alloc(size, KM_SLEEP);
+       hist_buf = vmem_alloc(size, KM_SLEEP);
        if ((error = spa_history_get(spa, &zc->zc_history_offset,
            &zc->zc_history_len, hist_buf)) == 0) {
                error = ddi_copyout(hist_buf,
@@ -1450,7 +1451,7 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
        }
 
        spa_close(spa, FTAG);
-       kmem_free(hist_buf, size);
+       vmem_free(hist_buf, size);
        return (error);
 }
 
@@ -3239,7 +3240,7 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
                        resume_err = zfs_resume_fs(zsb, zc->zc_name);
                        error = error ? error : resume_err;
                }
-               mntput(zsb->z_vfs);
+               deactivate_super(zsb->z_sb);
        } else {
                if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
                        error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
@@ -3455,7 +3456,7 @@ zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
 
        VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
 
-       zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
+       zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG);
        (void) strcpy(zc->zc_name, dataset);
        pair = nvlist_next_nvpair(props, NULL);
        while (pair != NULL) {
@@ -3724,7 +3725,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
                        if (error == 0)
                                error = zfs_resume_fs(zsb, tofs);
                        error = error ? error : end_err;
-                       mntput(zsb->z_vfs);
+                       deactivate_super(zsb->z_sb);
                } else {
                        error = dmu_recv_end(&drc);
                }
@@ -4094,7 +4095,7 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
        if (error)
                return (error);
 
-       buf = kmem_alloc(bufsize, KM_SLEEP);
+       buf = vmem_alloc(bufsize, KM_SLEEP);
 
        error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie,
            buf, &zc->zc_nvlist_dst_size);
@@ -4104,7 +4105,7 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
                    (void *)(uintptr_t)zc->zc_nvlist_dst,
                    zc->zc_nvlist_dst_size);
        }
-       kmem_free(buf, bufsize);
+       vmem_free(buf, bufsize);
        zfs_sb_rele(zsb, FTAG);
 
        return (error);
@@ -4137,7 +4138,7 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
                }
                if (error == 0)
                        error = dmu_objset_userspace_upgrade(zsb->z_os);
-               mntput(zsb->z_vfs);
+               deactivate_super(zsb->z_sb);
        } else {
                /* XXX kind of reading contents without owning */
                error = dmu_objset_hold(zc->zc_name, FTAG, &os);
@@ -4151,143 +4152,10 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
        return (error);
 }
 
-/*
- * We don't want to have a hard dependency
- * against some special symbols in sharefs
- * nfs, and smbsrv.  Determine them if needed when
- * the first file system is shared.
- * Neither sharefs, nfs or smbsrv are unloadable modules.
- */
-#ifdef HAVE_SHARE
-int (*znfsexport_fs)(void *arg);
-int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
-int (*zsmbexport_fs)(void *arg, boolean_t add_share);
-
-int zfs_nfsshare_inited;
-int zfs_smbshare_inited;
-
-ddi_modhandle_t nfs_mod;
-ddi_modhandle_t sharefs_mod;
-ddi_modhandle_t smbsrv_mod;
-kmutex_t zfs_share_lock;
-
-static int
-zfs_init_sharefs()
-{
-       int error;
-
-       ASSERT(MUTEX_HELD(&zfs_share_lock));
-       /* Both NFS and SMB shares also require sharetab support. */
-       if (sharefs_mod == NULL && ((sharefs_mod =
-           ddi_modopen("fs/sharefs",
-           KRTLD_MODE_FIRST, &error)) == NULL)) {
-               return (ENOSYS);
-       }
-       if (zshare_fs == NULL && ((zshare_fs =
-           (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
-           ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
-               return (ENOSYS);
-       }
-       return (0);
-}
-#endif /* HAVE_SHARE */
-
 static int
 zfs_ioc_share(zfs_cmd_t *zc)
 {
-#ifdef HAVE_SHARE
-       int error;
-       int opcode;
-
-       switch (zc->zc_share.z_sharetype) {
-       case ZFS_SHARE_NFS:
-       case ZFS_UNSHARE_NFS:
-               if (zfs_nfsshare_inited == 0) {
-                       mutex_enter(&zfs_share_lock);
-                       if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
-                           KRTLD_MODE_FIRST, &error)) == NULL)) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       if (znfsexport_fs == NULL &&
-                           ((znfsexport_fs = (int (*)(void *))
-                           ddi_modsym(nfs_mod,
-                           "nfs_export", &error)) == NULL)) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       error = zfs_init_sharefs();
-                       if (error) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       zfs_nfsshare_inited = 1;
-                       mutex_exit(&zfs_share_lock);
-               }
-               break;
-       case ZFS_SHARE_SMB:
-       case ZFS_UNSHARE_SMB:
-               if (zfs_smbshare_inited == 0) {
-                       mutex_enter(&zfs_share_lock);
-                       if (smbsrv_mod == NULL && ((smbsrv_mod =
-                           ddi_modopen("drv/smbsrv",
-                           KRTLD_MODE_FIRST, &error)) == NULL)) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       if (zsmbexport_fs == NULL && ((zsmbexport_fs =
-                           (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
-                           "smb_server_share", &error)) == NULL)) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       error = zfs_init_sharefs();
-                       if (error) {
-                               mutex_exit(&zfs_share_lock);
-                               return (ENOSYS);
-                       }
-                       zfs_smbshare_inited = 1;
-                       mutex_exit(&zfs_share_lock);
-               }
-               break;
-       default:
-               return (EINVAL);
-       }
-
-       switch (zc->zc_share.z_sharetype) {
-       case ZFS_SHARE_NFS:
-       case ZFS_UNSHARE_NFS:
-               if (error =
-                   znfsexport_fs((void *)
-                   (uintptr_t)zc->zc_share.z_exportdata))
-                       return (error);
-               break;
-       case ZFS_SHARE_SMB:
-       case ZFS_UNSHARE_SMB:
-               if (error = zsmbexport_fs((void *)
-                   (uintptr_t)zc->zc_share.z_exportdata,
-                   zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
-                   B_TRUE: B_FALSE)) {
-                       return (error);
-               }
-               break;
-       }
-
-       opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
-           zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
-           SHAREFS_ADD : SHAREFS_REMOVE;
-
-       /*
-        * Add or remove share from sharetab
-        */
-       error = zshare_fs(opcode,
-           (void *)(uintptr_t)zc->zc_share.z_sharedata,
-           zc->zc_share.z_sharemax);
-
-       return (error);
-#else
-       return (ENOTSUP);
-#endif /* HAVE_SHARE */
+       return (ENOSYS);
 }
 
 ace_t full_access[] = {
@@ -5047,7 +4915,7 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
                error = EFAULT;
 
        if ((error == 0) && !(flag & FKIOCTL))
-               error = zfs_ioc_vec[vec].zvec_secpolicy(zc, NULL);
+               error = zfs_ioc_vec[vec].zvec_secpolicy(zc, CRED());
 
        /*
         * Ensure that all pool/dataset names are valid before we pass down to
@@ -5174,12 +5042,10 @@ _init(void)
        tsd_create(&zfs_fsyncer_key, NULL);
        tsd_create(&rrw_tsd_key, NULL);
 
-#ifdef HAVE_SHARE
-       mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
-#endif /* HAVE_SHARE */
-
-       printk(KERN_NOTICE "ZFS: Loaded ZFS Filesystem v%s%s\n",
-              ZFS_META_VERSION, ZFS_DEBUG_STR);
+       printk(KERN_NOTICE "ZFS: Loaded module v%s%s, "
+              "ZFS pool version %s, ZFS filesystem version %s\n",
+              ZFS_META_VERSION, ZFS_DEBUG_STR,
+              SPA_VERSION_STRING, ZPL_VERSION_STRING);
 
        return (0);
 
@@ -5201,20 +5067,11 @@ _fini(void)
        zvol_fini();
        zfs_fini();
        spa_fini();
-#ifdef HAVE_SHARE
-       if (zfs_nfsshare_inited)
-               (void) ddi_modclose(nfs_mod);
-       if (zfs_smbshare_inited)
-               (void) ddi_modclose(smbsrv_mod);
-       if (zfs_nfsshare_inited || zfs_smbshare_inited)
-               (void) ddi_modclose(sharefs_mod);
-
-       mutex_destroy(&zfs_share_lock);
-#endif /* HAVE_SHARE */
+
        tsd_destroy(&zfs_fsyncer_key);
        tsd_destroy(&rrw_tsd_key);
 
-       printk(KERN_NOTICE "ZFS: Unloaded ZFS Filesystem v%s%s\n",
+       printk(KERN_NOTICE "ZFS: Unloaded module v%s%s\n",
               ZFS_META_VERSION, ZFS_DEBUG_STR);
 
        return (0);