From 155272b34173e814a1936bdb1fb66e41225225c6 Mon Sep 17 00:00:00 2001 From: Jason King Date: Fri, 21 Feb 2020 20:37:24 -0600 Subject: OS-8115 Add support for zfs.sync.change-key channel program (#264) Reviewed by: Jerry Jelinek Approved by: Jerry Jelinek --- usr/src/uts/common/fs/zfs/dsl_crypt.c | 9 +- usr/src/uts/common/fs/zfs/sys/dsl_crypt.h | 7 ++ usr/src/uts/common/fs/zfs/sys/zcp_change_key.h | 41 +++++++ usr/src/uts/common/fs/zfs/zcp_change_key.c | 144 +++++++++++++++++++++++++ usr/src/uts/common/fs/zfs/zcp_synctask.c | 71 ++++++++++++ usr/src/uts/common/fs/zfs/zfs_ioctl.c | 11 ++ 6 files changed, 276 insertions(+), 7 deletions(-) create mode 100644 usr/src/uts/common/fs/zfs/sys/zcp_change_key.h create mode 100644 usr/src/uts/common/fs/zfs/zcp_change_key.c (limited to 'usr/src/uts/common/fs') diff --git a/usr/src/uts/common/fs/zfs/dsl_crypt.c b/usr/src/uts/common/fs/zfs/dsl_crypt.c index c9d02e1c57..a092326a9c 100644 --- a/usr/src/uts/common/fs/zfs/dsl_crypt.c +++ b/usr/src/uts/common/fs/zfs/dsl_crypt.c @@ -1220,12 +1220,7 @@ dsl_crypto_key_sync(dsl_crypto_key_t *dck, dmu_tx_t *tx) tx); } -typedef struct spa_keystore_change_key_args { - const char *skcka_dsname; - dsl_crypto_params_t *skcka_cp; -} spa_keystore_change_key_args_t; - -static int +int spa_keystore_change_key_check(void *arg, dmu_tx_t *tx) { int ret; @@ -1469,7 +1464,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj, dsl_dir_rele(dd, FTAG); } -static void +void spa_keystore_change_key_sync(void *arg, dmu_tx_t *tx) { dsl_dataset_t *ds; diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h index cf19665aae..5b7c1a9510 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h @@ -164,6 +164,11 @@ typedef struct spa_keystore { avl_tree_t sk_wkeys; } spa_keystore_t; +typedef struct spa_keystore_change_key_args { + const char *skcka_dsname; + dsl_crypto_params_t *skcka_cp; +} spa_keystore_change_key_args_t; + int dsl_crypto_params_create_nvlist(dcp_cmd_t cmd, nvlist_t *props, nvlist_t *crypto_args, dsl_crypto_params_t **dcp_out); void dsl_crypto_params_free(dsl_crypto_params_t *dcp, boolean_t unload); @@ -199,6 +204,8 @@ int dsl_crypto_recv_raw(const char *poolname, uint64_t dsobj, uint64_t fromobj, dmu_objset_type_t ostype, nvlist_t *nvl, boolean_t do_key); int spa_keystore_change_key(const char *dsname, dsl_crypto_params_t *dcp); +int spa_keystore_change_key_check(void *arg, dmu_tx_t *tx); +void spa_keystore_change_key_sync(void *arg, dmu_tx_t *tx); int dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent); int dsl_dataset_promote_crypt_check(dsl_dir_t *target, dsl_dir_t *origin); void dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin, diff --git a/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h b/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h new file mode 100644 index 0000000000..fea520455f --- /dev/null +++ b/usr/src/uts/common/fs/zfs/sys/zcp_change_key.h @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +#ifndef _SYS_ZCP_CHANGE_KEY_H +#define _SYS_ZCP_CHANGE_KEY_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void zcp_synctask_change_key_cleanup(void *arg); +int zcp_synctask_change_key_check(void *arg, dmu_tx_t *tx); +void zcp_synctask_change_key_sync(void *arg, dmu_tx_t *tx); +int zcp_synctask_change_key_create_params(const char *key, size_t keylen, + zfs_keyformat_t keyformat, dsl_crypto_params_t **dcpp); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_CHANGE_KEY_H */ diff --git a/usr/src/uts/common/fs/zfs/zcp_change_key.c b/usr/src/uts/common/fs/zfs/zcp_change_key.c new file mode 100644 index 0000000000..be16a8d5c6 --- /dev/null +++ b/usr/src/uts/common/fs/zfs/zcp_change_key.c @@ -0,0 +1,144 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright 2020 Joyent, Inc. + */ + +#include +#include +#include + +static uint8_t +hexval(char c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + else if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + return (c - 'A' + 10); + + panic("invalid hex value"); +} + +static int +hex_to_raw(const char *key, uint8_t *buf, size_t buflen) +{ + uint8_t *p; + size_t srclen = strlen(key); + size_t i; + + if (buflen * 2 != srclen) + return (SET_ERROR(EINVAL)); + + for (i = 0, p = buf; i < srclen; i += 2, p++) { + if (!isxdigit(key[i]) || !isxdigit(key[i + 1])) + return (SET_ERROR(EINVAL)); + + *p = hexval(key[i]) << 4 | hexval(key[i + 1]); + } + + return (0); +} + +int +zcp_synctask_change_key_create_params(const char *key, size_t keylen, + zfs_keyformat_t keyformat, dsl_crypto_params_t **dcpp) +{ + nvlist_t *args = fnvlist_alloc(); + nvlist_t *hidden_args = fnvlist_alloc(); + uint8_t rawkey[WRAPPING_KEY_LEN]; + uint_t rawlen = 0; + int err = 0; + + /* + * Currently, only raw and hex keys are supported in channel + * programs (there is no pbkdf2 support in the kernel to convert + * a passphrase). + */ + switch (keyformat) { + case ZFS_KEYFORMAT_RAW: + /* + * dsl_crypto_params_create_nvlist() also verifies the + * raw key is WRAPPING_KEY_LEN bytes, so this is + * _almost_ redundant -- however we still want to + * guarantee we won't overflow rawkey when copying + * the contents over. + */ + if (keylen != WRAPPING_KEY_LEN) { + err = SET_ERROR(EINVAL); + goto done; + } + + bcopy(key, rawkey, keylen); + rawlen = keylen; + break; + case ZFS_KEYFORMAT_HEX: + /* + * hex_to_raw() will reject any input that doesn't exactly + * fit into rawkey + */ + err = hex_to_raw(key, rawkey, sizeof (rawkey)); + if (err != 0) + goto done; + rawlen = sizeof (rawkey); + break; + default: + err = SET_ERROR(EINVAL); + goto done; + } + + fnvlist_add_uint64(args, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), + (uint64_t)keyformat); + fnvlist_add_uint8_array(hidden_args, "wkeydata", rawkey, rawlen); + + err = dsl_crypto_params_create_nvlist(DCP_CMD_NEW_KEY, args, + hidden_args, dcpp); + +done: + fnvlist_free(args); + fnvlist_free(hidden_args); + bzero(rawkey, sizeof (rawkey)); + + return (err); +} + +void +zcp_synctask_change_key_cleanup(void *arg) +{ + spa_keystore_change_key_args_t *skcka = arg; + + dsl_crypto_params_free(skcka->skcka_cp, B_TRUE); +} + +int +zcp_synctask_change_key_check(void *arg, dmu_tx_t *tx) +{ + /* + * zcp_synctask_change_key_create_params() already validates that + * the new key is in an acceptable format and size for a channel + * program. Any future channel program specific checks would go here. + * For now, we just perform all the same checks done for + * 'zfs change-key' by calling spa_keystore_change_key_check(). + */ + return (spa_keystore_change_key_check(arg, tx)); +} + +void +zcp_synctask_change_key_sync(void *arg, dmu_tx_t *tx) +{ + spa_keystore_change_key_sync(arg, tx); +} diff --git a/usr/src/uts/common/fs/zfs/zcp_synctask.c b/usr/src/uts/common/fs/zfs/zcp_synctask.c index 09af25c1c9..9a1dceb044 100644 --- a/usr/src/uts/common/fs/zfs/zcp_synctask.c +++ b/usr/src/uts/common/fs/zfs/zcp_synctask.c @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include #include @@ -399,6 +401,74 @@ zcp_synctask_set_prop(lua_State *state, boolean_t sync, nvlist_t *err_details) return (err); } +static int zcp_synctask_change_key(lua_State *, boolean_t, nvlist_t *); +static zcp_synctask_info_t zcp_synctask_change_key_info = { + .name = "change_key", + .func = zcp_synctask_change_key, + .pargs = { + { .za_name = "dataset", .za_lua_type = LUA_TSTRING }, + { .za_name = "key", .za_lua_type = LUA_TSTRING }, + { .za_name = "format", .za_lua_type = LUA_TSTRING }, + { NULL, 0 }, + }, + .kwargs = { + { NULL, 0 } + }, + .space_check = ZFS_SPACE_CHECK_RESERVED, + /* + * This is the same value that is used when zfs change-key is run. + * See spa_keystore_change_key() in dsl_crypt.c + */ + .blocks_modified = 15 +}; + +static int +zcp_synctask_change_key(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + spa_keystore_change_key_args_t skcka = { 0 }; + dsl_crypto_params_t *dcp = NULL; + const char *dsname; + const char *key; + const char *format; + size_t keylen; + uint64_t keyformat; + + dsname = lua_tostring(state, 1); + + /* + * The key may be raw key, which could contain NUL within it. + * Use lua_tolstring() instead of lua_tostring() to obtain the length. + */ + key = lua_tolstring(state, 2, &keylen); + + format = lua_tostring(state, 3); + + if (zfs_prop_string_to_index(ZFS_PROP_KEYFORMAT, format, + &keyformat) != 0) + return (SET_ERROR(EINVAL)); + + err = zcp_synctask_change_key_create_params(key, keylen, keyformat, + &dcp); + if (err != 0) + goto done; + + skcka.skcka_dsname = dsname; + skcka.skcka_cp = dcp; + + zcp_cleanup_handler_t *zch = zcp_register_cleanup(state, + (zcp_cleanup_t *)&zcp_synctask_change_key_cleanup, &skcka); + + err = zcp_sync_task(state, zcp_synctask_change_key_check, + zcp_synctask_change_key_sync, &skcka, sync, dsname); + + zcp_deregister_cleanup(state, zch); + +done: + dsl_crypto_params_free(dcp, (err != 0 || !sync) ? B_TRUE : B_FALSE); + return (err); +} + static int zcp_synctask_wrapper(lua_State *state) { @@ -468,6 +538,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync) &zcp_synctask_snapshot_info, &zcp_synctask_inherit_prop_info, &zcp_synctask_set_prop_info, + &zcp_synctask_change_key_info, NULL }; diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c index 2b4c1d55e7..153dcf1502 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c @@ -3767,6 +3767,7 @@ zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, uint64_t instrlimit, memlimit; boolean_t sync_flag; nvpair_t *nvarg = NULL; + nvlist_t *hidden_args = NULL; if (0 != nvlist_lookup_string(innvl, ZCP_ARG_PROGRAM, &program)) { return (EINVAL); @@ -3784,6 +3785,16 @@ zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, return (EINVAL); } + /* hidden args are optional */ + if (nvlist_lookup_nvlist(innvl, ZPOOL_HIDDEN_ARGS, &hidden_args) == 0) { + nvlist_t *argnvl = fnvpair_value_nvlist(nvarg); + int ret; + + ret = nvlist_add_nvlist(argnvl, ZPOOL_HIDDEN_ARGS, hidden_args); + if (ret != 0) + return (ret); + } + if (instrlimit == 0 || instrlimit > zfs_lua_max_instrlimit) return (EINVAL); if (memlimit == 0 || memlimit > zfs_lua_max_memlimit) -- cgit v1.2.3 From aaa9aa59eb29d123223ea0b8ebf393049910d9ce Mon Sep 17 00:00:00 2001 From: Jerry Jelinek Date: Fri, 28 Feb 2020 11:07:09 -0700 Subject: 12343 Direct IO support Reviewed by: Toomas Soome Reviewed by: Garrett D'Amore Reviewed by: C Fraire Approved by: Dan McDonald --- usr/src/man/man3c/directio.3c | 5 +++-- usr/src/uts/common/fs/zfs/zfs_vnops.c | 42 ++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) (limited to 'usr/src/uts/common/fs') diff --git a/usr/src/man/man3c/directio.3c b/usr/src/man/man3c/directio.3c index 9ca847bec3..f90bf3dcb7 100644 --- a/usr/src/man/man3c/directio.3c +++ b/usr/src/man/man3c/directio.3c @@ -1,9 +1,10 @@ '\" te .\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2020 Joyent, Inc. .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH DIRECTIO 3C "Apr 9, 2003" +.TH DIRECTIO 3C "Feb 28, 2020" .SH NAME directio \- provide advice to file system .SH SYNOPSIS @@ -130,7 +131,7 @@ when a file is sparse or is being extended and is opened with \fBO_SYNC\fR or \fBO_DSYNC\fR (see \fBopen\fR(2)). .sp .LP -The \fBdirectio()\fR function is supported for the NFS and UFS file system +The \fBdirectio()\fR function is supported for the NFS, UFS and ZFS file system types (see \fBfstyp\fR(1M)). .SH ATTRIBUTES .sp diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 8c84e93240..162c565c45 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -23,7 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. * Copyright 2017 Nexenta Systems, Inc. */ @@ -377,6 +377,46 @@ zfs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred, return (0); } + case _FIODIRECTIO: + { + /* + * ZFS inherently provides the basic semantics for directio. + * This is the summary from the ZFS on Linux support for + * O_DIRECT, which is the common form of directio, and required + * no changes to ZFS. + * + * 1. Minimize cache effects of the I/O. + * + * By design the ARC is already scan-resistant, which helps + * mitigate the need for special O_DIRECT handling. + * + * 2. O_DIRECT _MAY_ impose restrictions on IO alignment and + * length. + * + * No additional alignment or length restrictions are + * imposed by ZFS. + * + * 3. O_DIRECT _MAY_ perform unbuffered IO operations directly + * between user memory and block device. + * + * No unbuffered IO operations are currently supported. In + * order to support features such as compression, encryption, + * and checksumming a copy must be made to transform the + * data. + * + * 4. O_DIRECT _MAY_ imply O_DSYNC (XFS). + * + * O_DIRECT does not imply O_DSYNC for ZFS. + * + * 5. O_DIRECT _MAY_ disable file locking that serializes IO + * operations. + * + * All I/O in ZFS is locked for correctness and this locking + * is not disabled by O_DIRECT. + */ + return (0); + } + case _FIO_SEEK_DATA: case _FIO_SEEK_HOLE: { -- cgit v1.2.3 From 8950e535f42dd006f8cfb2122c94f6b7557757e0 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Sun, 26 Jan 2020 11:58:12 +0000 Subject: 12261 pfiles(1) could show any filesystem endpoints for a door Reviewed by: John Levon Reviewed by: Jason King Approved by: Robert Mustacchi --- usr/src/cmd/ptools/pfiles/pfiles.c | 13 ++++--- usr/src/uts/common/fs/namefs/namevfs.c | 27 +++++++++++++ usr/src/uts/common/fs/proc/prsubr.c | 70 ++++++++++++++++++++++++++++++---- usr/src/uts/common/sys/fs/namenode.h | 8 ++++ usr/src/uts/intel/procfs/Makefile | 3 ++ usr/src/uts/sparc/procfs/Makefile | 20 ++-------- 6 files changed, 111 insertions(+), 30 deletions(-) (limited to 'usr/src/uts/common/fs') diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c index ad74bb72ae..dd5ce4af11 100644 --- a/usr/src/cmd/ptools/pfiles/pfiles.c +++ b/usr/src/cmd/ptools/pfiles/pfiles.c @@ -205,13 +205,19 @@ intr(int sig) /* ------ begin specific code ------ */ +static int +show_paths(uint_t type, const void *data, size_t len, void *arg __unused) +{ + if (type == PR_PATHNAME) + (void) printf(" %.*s\n", len, data); + return (0); +} static int show_file(void *data, const prfdinfo_t *info) { struct ps_prochandle *Pr = data; char unknown[12]; - const char *path; char *s; mode_t mode; @@ -259,8 +265,6 @@ show_file(void *data, const prfdinfo_t *info) (void) printf(" rdev:%u,%u\n", (unsigned)info->pr_rmajor, (unsigned)info->pr_rminor); - path = proc_fdinfo_misc(info, PR_PATHNAME, NULL); - if (!nflag) { dofcntl(Pr, info, (mode & (S_IFMT|S_ENFMT|S_IXGRP)) == (S_IFREG|S_ENFMT), @@ -285,8 +289,7 @@ show_file(void *data, const prfdinfo_t *info) } } - if (path != NULL) - (void) printf(" %s\n", path); + (void) proc_fdinfowalk(info, show_paths, NULL); if (info->pr_offset != -1) { (void) printf(" offset:%lld\n", diff --git a/usr/src/uts/common/fs/namefs/namevfs.c b/usr/src/uts/common/fs/namefs/namevfs.c index 9952f0a742..63e618de11 100644 --- a/usr/src/uts/common/fs/namefs/namevfs.c +++ b/usr/src/uts/common/fs/namefs/namevfs.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017 by Delphix. All rights reserved. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -181,6 +182,31 @@ namefind(vnode_t *vp, vnode_t *mnt) return (np); } +/* + * For each namenode that has nm_filevp == vp, call the provided function + * with the namenode as an argument. This finds all of the namefs entries + * which are mounted on vp; note that there can be more than one. + */ +int +nm_walk_mounts(const vnode_t *vp, nm_walk_mounts_f *func, cred_t *cr, void *arg) +{ + struct namenode *np; + int ret = 0; + + mutex_enter(&ntable_lock); + + for (np = *NM_FILEVP_HASH(vp); np != NULL; np = np->nm_nextp) { + if (np->nm_filevp == vp) { + if ((ret = func(np, cr, arg)) != 0) + break; + } + } + + mutex_exit(&ntable_lock); + + return (ret); +} + /* * Force the unmouting of a file descriptor from ALL of the nodes * that it was mounted to. @@ -480,6 +506,7 @@ nm_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *crp) newvp->v_rdev = filevp->v_rdev; newvp->v_data = (caddr_t)nodep; VFS_HOLD(vfsp); + vn_copypath(mvp, newvp); vn_exists(newvp); /* diff --git a/usr/src/uts/common/fs/proc/prsubr.c b/usr/src/uts/common/fs/proc/prsubr.c index fdb823d7ba..b3b6e57458 100644 --- a/usr/src/uts/common/fs/proc/prsubr.c +++ b/usr/src/uts/common/fs/proc/prsubr.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -2508,7 +2509,11 @@ prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) size_t pathlen; size_t sz = 0; - pathlen = MAXPATHLEN + 1; + /* + * The global zone's path to a file in a non-global zone can exceed + * MAXPATHLEN. + */ + pathlen = MAXPATHLEN * 2 + 1; pathname = kmem_alloc(pathlen, KM_SLEEP); if (vnodetopath(NULL, vp, pathname, pathlen, cred) == 0) { @@ -2517,6 +2522,7 @@ prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) } kmem_free(pathname, pathlen); + return (sz); } @@ -2745,6 +2751,22 @@ prfdinfosockopt(vnode_t *vp, list_t *data, cred_t *cred) return (sz); } +typedef struct prfdinfo_nm_path_cbdata { + proc_t *nmp_p; + u_offset_t nmp_sz; + list_t *nmp_data; +} prfdinfo_nm_path_cbdata_t; + +static int +prfdinfo_nm_path(const struct namenode *np, cred_t *cred, void *arg) +{ + prfdinfo_nm_path_cbdata_t *cb = arg; + + cb->nmp_sz += prfdinfopath(cb->nmp_p, np->nm_vnode, cb->nmp_data, cred); + + return (0); +} + u_offset_t prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) { @@ -2757,8 +2779,23 @@ prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) sz = offsetof(prfdinfo_t, pr_misc) + sizeof (pr_misc_header_t); /* Pathname */ - if (vp->v_type != VSOCK && vp->v_type != VDOOR) + switch (vp->v_type) { + case VDOOR: { + prfdinfo_nm_path_cbdata_t cb = { + .nmp_p = p, + .nmp_data = NULL, + .nmp_sz = 0 + }; + + (void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb); + sz += cb.nmp_sz; + break; + } + case VSOCK: + break; + default: sz += prfdinfopath(p, vp, NULL, cred); + } /* Socket options */ if (vp->v_type == VSOCK) @@ -2902,14 +2939,31 @@ prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred, } } - /* - * Don't attempt to determine the vnode path for a socket or a door - * as it will cause a linear scan of the dnlc table given there is no - * v_path associated with the vnode. - */ - if (vp->v_type != VSOCK && vp->v_type != VDOOR) + /* pathname */ + + switch (vp->v_type) { + case VDOOR: { + prfdinfo_nm_path_cbdata_t cb = { + .nmp_p = p, + .nmp_data = data, + .nmp_sz = 0 + }; + + (void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb); + break; + } + case VSOCK: + /* + * Don't attempt to determine the path for a socket as the + * vnode has no associated v_path. It will cause a linear scan + * of the dnlc table and result in no path being found. + */ + break; + default: (void) prfdinfopath(p, vp, data, cred); + } + /* socket options */ if (vp->v_type == VSOCK) (void) prfdinfosockopt(vp, data, cred); diff --git a/usr/src/uts/common/sys/fs/namenode.h b/usr/src/uts/common/sys/fs/namenode.h index 9ebf2cf1ca..24d276b6c3 100644 --- a/usr/src/uts/common/sys/fs/namenode.h +++ b/usr/src/uts/common/sys/fs/namenode.h @@ -26,6 +26,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ + #ifndef _SYS_FS_NAMENODE_H #define _SYS_FS_NAMENODE_H @@ -93,6 +97,10 @@ extern struct vnodeops *nm_vnodeops; extern const struct fs_operation_def nm_vnodeops_template[]; extern kmutex_t ntable_lock; +typedef int nm_walk_mounts_f(const struct namenode *, cred_t *, void *); +extern int nm_walk_mounts(const vnode_t *, nm_walk_mounts_f *, cred_t *, + void *); + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/usr/src/uts/intel/procfs/Makefile b/usr/src/uts/intel/procfs/Makefile index 1db5848438..630b6a25d3 100644 --- a/usr/src/uts/intel/procfs/Makefile +++ b/usr/src/uts/intel/procfs/Makefile @@ -25,6 +25,7 @@ # Use is subject to license terms. # # Copyright 2019 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # This makefile drives the production of the procfs file system @@ -83,6 +84,8 @@ $(OBJS_DIR)/prsubr.o := SMOFF += all_func_returns $(OBJS_DIR)/prcontrol.o := SMOFF += all_func_returns $(OBJS_DIR)/prioctl.o := SMOFF += signed +LDFLAGS += -dy -Nfs/namefs + # # Default build targets. # diff --git a/usr/src/uts/sparc/procfs/Makefile b/usr/src/uts/sparc/procfs/Makefile index 8dd05fe72b..3226238bd4 100644 --- a/usr/src/uts/sparc/procfs/Makefile +++ b/usr/src/uts/sparc/procfs/Makefile @@ -23,6 +23,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # This makefile drives the production of the procfs file system @@ -41,7 +42,6 @@ UTSBASE = ../.. # MODULE = procfs OBJECTS = $(PROC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(PROC_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE) # @@ -53,7 +53,6 @@ include $(UTSBASE)/sparc/Makefile.sparc # Define targets # ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # @@ -64,19 +63,12 @@ $(MODSTUBS_O) := AS_CPPFLAGS += -DPROC_MODULE CLEANFILES += $(MODSTUBS_O) CFLAGS += $(CCVERBOSE) -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-switch CERRWARN += $(CNOWARN_UNINIT) +LDFLAGS += -dy -Nfs/namefs + # # Default build targets. # @@ -90,12 +82,6 @@ clean: $(CLEAN_DEPS) clobber: $(CLOBBER_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) # -- cgit v1.2.3