X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzfs_ioctl.c;h=532f17aa16afa781c7f1f42ec15a688a0b0aa9b6;hb=d7e398ce1a3e6f9c705af43955a684685a798c32;hp=edfda7656adbc6ea1e6adb17409d8b72ab520f3c;hpb=d247f2a3cc24e8127ec1c5055bf0cd6c39c09add;p=zfs.git diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index edfda76..532f17a 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -119,42 +119,6 @@ static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *, boolean_t *); int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t **); -/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ -void -__dprintf(const char *file, const char *func, int line, const char *fmt, ...) -{ - const char *newfile; - char buf[512]; - va_list adx; - - /* - * Get rid of annoying "../common/" prefix to filename. - */ - newfile = strrchr(file, '/'); - if (newfile != NULL) { - newfile = newfile + 1; /* Get rid of leading / */ - } else { - newfile = file; - } - - va_start(adx, fmt); - (void) vsnprintf(buf, sizeof (buf), fmt, adx); - va_end(adx); - - /* - * To get this data, use the zfs-dprintf probe as so: - * dtrace -q -n 'zfs-dprintf \ - * /stringof(arg0) == "dbuf.c"/ \ - * {printf("%s: %s", stringof(arg1), stringof(arg3))}' - * arg0 = file name - * arg1 = function name - * arg2 = line number - * arg3 = message - */ - DTRACE_PROBE4(zfs__dprintf, - char *, newfile, char *, func, int, line, char *, buf); -} - static void history_str_free(char *buf) { @@ -591,7 +555,7 @@ zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr) return (error); } -#ifdef HAVE_SHARE +#ifdef HAVE_SMB_SHARE static int zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr) { @@ -615,12 +579,12 @@ zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr) return (dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_SHARE, cr)); } -#endif /* HAVE_SHARE */ +#endif /* HAVE_SMB_SHARE */ int zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) { -#ifdef HAVE_SHARE +#ifdef HAVE_SMB_SHARE if (!INGLOBALZONE(curproc)) return (EPERM); @@ -631,13 +595,13 @@ zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) } #else return (ENOTSUP); -#endif /* HAVE_SHARE */ +#endif /* HAVE_SMB_SHARE */ } int zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr) { -#ifdef HAVE_SHARE +#ifdef HAVE_SMB_SHARE if (!INGLOBALZONE(curproc)) return (EPERM); @@ -648,7 +612,7 @@ zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr) } #else return (ENOTSUP); -#endif /* HAVE_SHARE */ +#endif /* HAVE_SMB_SHARE */ } static int @@ -701,6 +665,9 @@ zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr) * and destroying snapshots requires descendent permissions, a successfull * check of the top level snapshot applies to snapshots of all descendent * datasets as well. + * + * The target snapshot may not exist when doing a recursive destroy. + * In this case fallback to permissions of the parent dataset. */ static int zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, cred_t *cr) @@ -711,6 +678,8 @@ zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, cred_t *cr) dsname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value); error = zfs_secpolicy_destroy_perms(dsname, cr); + if (error == ENOENT) + error = zfs_secpolicy_destroy_perms(zc->zc_name, cr); strfree(dsname); return (error); @@ -1107,8 +1076,8 @@ 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) { + atomic_inc(&((*zsbp)->z_sb->s_active)); } else { error = ESRCH; } @@ -1119,7 +1088,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 +1118,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 +1410,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 +1419,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); } @@ -2170,7 +2139,8 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, if (err == 0 && intval >= ZPL_VERSION_USERSPACE) { zfs_cmd_t *zc; - zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); + zc = kmem_zalloc(sizeof (zfs_cmd_t), + KM_SLEEP | KM_NODEBUG); (void) strcpy(zc->zc_name, dsname); (void) zfs_ioc_userspace_upgrade(zc); kmem_free(zc, sizeof (zfs_cmd_t)); @@ -3239,7 +3209,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); @@ -3724,7 +3694,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 +4064,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 +4074,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 +4107,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 +4121,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[] = { @@ -4404,7 +4241,7 @@ zfs_ioc_diff(zfs_cmd_t *zc) /* * Remove all ACL files in shares dir */ -#ifdef HAVE_SHARE +#ifdef HAVE_SMB_SHARE static int zfs_smb_acl_purge(znode_t *dzp) { @@ -4423,12 +4260,12 @@ zfs_smb_acl_purge(znode_t *dzp) zap_cursor_fini(&zc); return (error); } -#endif /* HAVE SHARE */ +#endif /* HAVE_SMB_SHARE */ static int zfs_ioc_smb_acl(zfs_cmd_t *zc) { -#ifdef HAVE_SHARE +#ifdef HAVE_SMB_SHARE vnode_t *vp; znode_t *dzp; vnode_t *resourcevp = NULL; @@ -4552,7 +4389,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) return (error); #else return (ENOTSUP); -#endif /* HAVE_SHARE */ +#endif /* HAVE_SMB_SHARE */ } /* @@ -5047,7 +4884,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,10 +5011,6 @@ _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 module v%s%s, " "ZFS pool version %s, ZFS filesystem version %s\n", ZFS_META_VERSION, ZFS_DEBUG_STR, @@ -5203,16 +5036,7 @@ _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);