Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsclient/nfs_clvfsops.c
Show First 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | |||||
static int nfs_mountroot(struct mount *); | static int nfs_mountroot(struct mount *); | ||||
static void nfs_sec_name(char *, int *); | static void nfs_sec_name(char *, int *); | ||||
static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, | static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, | ||||
struct nfs_args *argp, const char *, struct ucred *, | struct nfs_args *argp, const char *, struct ucred *, | ||||
struct thread *); | struct thread *); | ||||
static int mountnfs(struct nfs_args *, struct mount *, | static int mountnfs(struct nfs_args *, struct mount *, | ||||
struct sockaddr *, char *, u_char *, int, u_char *, int, | struct sockaddr *, char *, u_char *, int, u_char *, int, | ||||
u_char *, int, struct vnode **, struct ucred *, | u_char *, int, struct vnode **, struct ucred *, | ||||
struct thread *, int, int, int, uint32_t, char *); | struct thread *, int, int, int, uint32_t, char *, int); | ||||
static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *, | static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *, | ||||
struct sockaddr_storage *, int *, off_t *, | struct sockaddr_storage *, int *, off_t *, | ||||
struct timeval *); | struct timeval *); | ||||
static vfs_mount_t nfs_mount; | static vfs_mount_t nfs_mount; | ||||
static vfs_cmount_t nfs_cmount; | static vfs_cmount_t nfs_cmount; | ||||
static vfs_unmount_t nfs_unmount; | static vfs_unmount_t nfs_unmount; | ||||
static vfs_root_t nfs_root; | static vfs_root_t nfs_root; | ||||
static vfs_statfs_t nfs_statfs; | static vfs_statfs_t nfs_statfs; | ||||
▲ Show 20 Lines • Show All 413 Lines • ▼ Show 20 Lines | nfs_mountdiskless(char *path, | ||||
dirpath = strchr(path, ':'); | dirpath = strchr(path, ':'); | ||||
if (dirpath != NULL) | if (dirpath != NULL) | ||||
dirlen = strlen(++dirpath); | dirlen = strlen(++dirpath); | ||||
else | else | ||||
dirlen = 0; | dirlen = 0; | ||||
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); | nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); | ||||
if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen, | if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen, | ||||
NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO, | NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO, | ||||
NFS_DEFAULT_NEGNAMETIMEO, 0, 0, NULL)) != 0) { | NFS_DEFAULT_NEGNAMETIMEO, 0, 0, NULL, 0)) != 0) { | ||||
printf("nfs_mountroot: mount %s on /: %d\n", path, error); | printf("nfs_mountroot: mount %s on /: %d\n", path, error); | ||||
return (error); | return (error); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
nfs_sec_name(char *sec, int *flagsp) | nfs_sec_name(char *sec, int *flagsp) | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | if (nmp->nm_client != NULL && adjsock) { | ||||
int haslock = 0, error = 0; | int haslock = 0, error = 0; | ||||
if (nmp->nm_sotype == SOCK_STREAM) { | if (nmp->nm_sotype == SOCK_STREAM) { | ||||
error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock); | error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock); | ||||
if (!error) | if (!error) | ||||
haslock = 1; | haslock = 1; | ||||
} | } | ||||
if (!error) { | if (!error) { | ||||
newnfs_disconnect(&nmp->nm_sockreq); | newnfs_disconnect(nmp, &nmp->nm_sockreq); | ||||
if (haslock) | if (haslock) | ||||
newnfs_sndunlock(&nmp->nm_sockreq.nr_lock); | newnfs_sndunlock(&nmp->nm_sockreq.nr_lock); | ||||
nmp->nm_sotype = argp->sotype; | nmp->nm_sotype = argp->sotype; | ||||
nmp->nm_soproto = argp->proto; | nmp->nm_soproto = argp->proto; | ||||
if (nmp->nm_sotype == SOCK_DGRAM) | if (nmp->nm_sotype == SOCK_DGRAM) | ||||
while (newnfs_connect(nmp, &nmp->nm_sockreq, | while (newnfs_connect(nmp, &nmp->nm_sockreq, | ||||
cred, td, 0, false)) { | cred, td, 0, false, &nmp->nm_sockreq.nr_client)) { | ||||
printf("newnfs_args: retrying connect\n"); | printf("newnfs_args: retrying connect\n"); | ||||
(void) nfs_catnap(PSOCK, 0, "nfscon"); | (void) nfs_catnap(PSOCK, 0, "nfscon"); | ||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
nmp->nm_sotype = argp->sotype; | nmp->nm_sotype = argp->sotype; | ||||
nmp->nm_soproto = argp->proto; | nmp->nm_soproto = argp->proto; | ||||
} | } | ||||
Show All 11 Lines | static const char *nfs_opts[] = { "from", "nfs_args", | ||||
"noac", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union", | "noac", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union", | ||||
"noclusterr", "noclusterw", "multilabel", "acls", "force", "update", | "noclusterr", "noclusterw", "multilabel", "acls", "force", "update", | ||||
"async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus", | "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus", | ||||
"readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize", | "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize", | ||||
"retrans", "actimeo", "acregmin", "acregmax", "acdirmin", "acdirmax", | "retrans", "actimeo", "acregmin", "acregmax", "acdirmin", "acdirmax", | ||||
"resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh", | "resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh", | ||||
"nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath", | "nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath", | ||||
"minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr", | "minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr", | ||||
"pnfs", "wcommitsize", "oneopenown", "tls", "tlscertname", | "pnfs", "wcommitsize", "oneopenown", "tls", "tlscertname", "nconnect", | ||||
NULL }; | NULL }; | ||||
/* | /* | ||||
* Parse the "from" mountarg, passed by the generic mount(8) program | * Parse the "from" mountarg, passed by the generic mount(8) program | ||||
* or the mountroot code. This is used when rerooting into NFS. | * or the mountroot code. This is used when rerooting into NFS. | ||||
* | * | ||||
* Note that the "hostname" is actually a "hostname:/share/path" string. | * Note that the "hostname" is actually a "hostname:/share/path" string. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | nfs_mount(struct mount *mp) | ||||
char *cp, *opt, *name, *secname, *tlscertname; | char *cp, *opt, *name, *secname, *tlscertname; | ||||
int nametimeo = NFS_DEFAULT_NAMETIMEO; | int nametimeo = NFS_DEFAULT_NAMETIMEO; | ||||
int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; | int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; | ||||
int minvers = -1; | int minvers = -1; | ||||
int dirlen, has_nfs_args_opt, has_nfs_from_opt, | int dirlen, has_nfs_args_opt, has_nfs_from_opt, | ||||
krbnamelen, srvkrbnamelen; | krbnamelen, srvkrbnamelen; | ||||
size_t hstlen; | size_t hstlen; | ||||
uint32_t newflag; | uint32_t newflag; | ||||
int aconn = 0; | |||||
has_nfs_args_opt = 0; | has_nfs_args_opt = 0; | ||||
has_nfs_from_opt = 0; | has_nfs_from_opt = 0; | ||||
newflag = 0; | newflag = 0; | ||||
tlscertname = NULL; | tlscertname = NULL; | ||||
hst = malloc(MNAMELEN, M_TEMP, M_WAITOK); | hst = malloc(MNAMELEN, M_TEMP, M_WAITOK); | ||||
if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { | if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
▲ Show 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) == | ||||
ret = sscanf(opt, "%d", &minvers); | ret = sscanf(opt, "%d", &minvers); | ||||
if (ret != 1 || minvers < 0 || minvers > 2 || | if (ret != 1 || minvers < 0 || minvers > 2 || | ||||
(args.flags & NFSMNT_NFSV4) == 0) { | (args.flags & NFSMNT_NFSV4) == 0) { | ||||
vfs_mount_error(mp, "illegal minorversion: %s", opt); | vfs_mount_error(mp, "illegal minorversion: %s", opt); | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
if (vfs_getopt(mp->mnt_optnew, "nconnect", (void **)&opt, NULL) == | |||||
0) { | |||||
ret = sscanf(opt, "%d", &aconn); | |||||
if (ret != 1 || aconn < 1 || aconn > NFS_MAXNCONN) { | |||||
vfs_mount_error(mp, "illegal nconnect: %s", opt); | |||||
error = EINVAL; | |||||
goto out; | |||||
} | |||||
/* | |||||
markj: Am I right that a mount -u which tries to modify `nconnect` is effectively ignored? Should it… | |||||
Done Inline ActionsThe tradition for "mount -u" for the NFS client is to silently ignore options This tradition has been around for a long time, predating the new NFS client. rmacklem: The tradition for "mount -u" for the NFS client is to silently ignore options
that cannot be… | |||||
Not Done Inline ActionsI see, thanks for the explanation. markj: I see, thanks for the explanation. | |||||
* Setting nconnect=1 is a no-op, allowed so that | |||||
* the option can be used in a Linux compatible way. | |||||
*/ | |||||
aconn--; | |||||
} | |||||
if (vfs_getopt(mp->mnt_optnew, "sec", | if (vfs_getopt(mp->mnt_optnew, "sec", | ||||
(void **) &secname, NULL) == 0) | (void **) &secname, NULL) == 0) | ||||
nfs_sec_name(secname, &args.flags); | nfs_sec_name(secname, &args.flags); | ||||
if (mp->mnt_flag & MNT_UPDATE) { | if (mp->mnt_flag & MNT_UPDATE) { | ||||
struct nfsmount *nmp = VFSTONFS(mp); | struct nfsmount *nmp = VFSTONFS(mp); | ||||
if (nmp == NULL) { | if (nmp == NULL) { | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | if (vfs_getopt(mp->mnt_optnew, "addr", | ||||
nam->sa_len = args.addrlen; | nam->sa_len = args.addrlen; | ||||
} else { | } else { | ||||
vfs_mount_error(mp, "No server address"); | vfs_mount_error(mp, "No server address"); | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
if (aconn > 0 && (args.sotype != SOCK_STREAM || | |||||
(args.flags & NFSMNT_NFSV4) == 0 || minvers == 0)) { | |||||
/* | |||||
* RFC 5661 requires that an NFSv4.1/4.2 server | |||||
* send an RPC reply on the same TCP connection | |||||
* as the one it received the request on. | |||||
* This property in required for "nconnect" and | |||||
* might not be the case for NFSv3 or NFSv4.0 servers. | |||||
*/ | |||||
vfs_mount_error(mp, "nconnect should only be used " | |||||
"for NFSv4.1/4.2 mounts"); | |||||
error = EINVAL; | |||||
goto out; | |||||
} | |||||
args.fh = nfh; | args.fh = nfh; | ||||
error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath, | error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath, | ||||
dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td, | dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td, | ||||
nametimeo, negnametimeo, minvers, newflag, tlscertname); | nametimeo, negnametimeo, minvers, newflag, tlscertname, aconn); | ||||
out: | out: | ||||
if (!error) { | if (!error) { | ||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF | | mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF | | ||||
MNTK_USES_BCACHE; | MNTK_USES_BCACHE; | ||||
if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0) | if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0) | ||||
mp->mnt_kern_flag |= MNTK_NULL_NOCACHE; | mp->mnt_kern_flag |= MNTK_NULL_NOCACHE; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
Show All 31 Lines | |||||
/* | /* | ||||
* Common code for mount and mountroot | * Common code for mount and mountroot | ||||
*/ | */ | ||||
static int | static int | ||||
mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, | mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, | ||||
char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen, | char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen, | ||||
u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp, | u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp, | ||||
struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo, | struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo, | ||||
int minvers, uint32_t newflag, char *tlscertname) | int minvers, uint32_t newflag, char *tlscertname, int aconn) | ||||
{ | { | ||||
struct nfsmount *nmp; | struct nfsmount *nmp; | ||||
struct nfsnode *np; | struct nfsnode *np; | ||||
int error, trycnt, ret; | int error, trycnt, ret; | ||||
struct nfsvattr nfsva; | struct nfsvattr nfsva; | ||||
struct nfsclclient *clp; | struct nfsclclient *clp; | ||||
struct nfsclds *dsp, *tdsp; | struct nfsclds *dsp, *tdsp; | ||||
uint32_t lease; | uint32_t lease; | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | #endif | ||||
nmp->nm_sockreq.nr_prog = NFS_PROG; | nmp->nm_sockreq.nr_prog = NFS_PROG; | ||||
if ((argp->flags & NFSMNT_NFSV4)) | if ((argp->flags & NFSMNT_NFSV4)) | ||||
nmp->nm_sockreq.nr_vers = NFS_VER4; | nmp->nm_sockreq.nr_vers = NFS_VER4; | ||||
else if ((argp->flags & NFSMNT_NFSV3)) | else if ((argp->flags & NFSMNT_NFSV3)) | ||||
nmp->nm_sockreq.nr_vers = NFS_VER3; | nmp->nm_sockreq.nr_vers = NFS_VER3; | ||||
else | else | ||||
nmp->nm_sockreq.nr_vers = NFS_VER2; | nmp->nm_sockreq.nr_vers = NFS_VER2; | ||||
if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false))) | if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false, | ||||
&nmp->nm_sockreq.nr_client))) | |||||
goto bad; | goto bad; | ||||
/* For NFSv4, get the clientid now. */ | /* For NFSv4, get the clientid now. */ | ||||
if ((argp->flags & NFSMNT_NFSV4) != 0) { | if ((argp->flags & NFSMNT_NFSV4) != 0) { | ||||
NFSCL_DEBUG(3, "at getcl\n"); | NFSCL_DEBUG(3, "at getcl\n"); | ||||
error = nfscl_getcl(mp, cred, td, tryminvers, &clp); | error = nfscl_getcl(mp, cred, td, tryminvers, &clp); | ||||
NFSCL_DEBUG(3, "aft getcl=%d\n", error); | NFSCL_DEBUG(3, "aft getcl=%d\n", error); | ||||
if (error != 0) | if (error != 0) | ||||
goto bad; | goto bad; | ||||
if (aconn > 0 && nmp->nm_minorvers == 0) { | |||||
vfs_mount_error(mp, "nconnect should only be used " | |||||
"for NFSv4.1/4.2 mounts"); | |||||
error = EINVAL; | |||||
goto bad; | |||||
} | } | ||||
} | |||||
if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) && | if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) && | ||||
nmp->nm_dirpathlen > 0) { | nmp->nm_dirpathlen > 0) { | ||||
NFSCL_DEBUG(3, "in dirp\n"); | NFSCL_DEBUG(3, "in dirp\n"); | ||||
/* | /* | ||||
* If the fhsize on the mount point == 0 for V4, the mount | * If the fhsize on the mount point == 0 for V4, the mount | ||||
* path needs to be looked up. | * path needs to be looked up. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | if (nmp->nm_fhsize > 0) { | ||||
if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 && | if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 && | ||||
ret == 0 && | ret == 0 && | ||||
NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) { | NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) { | ||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_flag |= MNT_NFS4ACLS; | mp->mnt_flag |= MNT_NFS4ACLS; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
} | } | ||||
/* Can now allow additional connections. */ | |||||
if (aconn > 0) | |||||
nmp->nm_aconnect = aconn; | |||||
/* | /* | ||||
* Lose the lock but keep the ref. | * Lose the lock but keep the ref. | ||||
*/ | */ | ||||
NFSVOPUNLOCK(*vpp); | NFSVOPUNLOCK(*vpp); | ||||
vfs_cache_root_set(mp, *vpp); | vfs_cache_root_set(mp, *vpp); | ||||
return (0); | return (0); | ||||
} | } | ||||
error = EIO; | error = EIO; | ||||
bad: | bad: | ||||
if (clp != NULL) | if (clp != NULL) | ||||
nfscl_clientrelease(clp); | nfscl_clientrelease(clp); | ||||
newnfs_disconnect(&nmp->nm_sockreq); | newnfs_disconnect(NULL, &nmp->nm_sockreq); | ||||
crfree(nmp->nm_sockreq.nr_cred); | crfree(nmp->nm_sockreq.nr_cred); | ||||
if (nmp->nm_sockreq.nr_auth != NULL) | if (nmp->nm_sockreq.nr_auth != NULL) | ||||
AUTH_DESTROY(nmp->nm_sockreq.nr_auth); | AUTH_DESTROY(nmp->nm_sockreq.nr_auth); | ||||
mtx_destroy(&nmp->nm_sockreq.nr_mtx); | mtx_destroy(&nmp->nm_sockreq.nr_mtx); | ||||
mtx_destroy(&nmp->nm_mtx); | mtx_destroy(&nmp->nm_mtx); | ||||
if (nmp->nm_clp != NULL) { | if (nmp->nm_clp != NULL) { | ||||
NFSLOCKCLSTATE(); | NFSLOCKCLSTATE(); | ||||
LIST_REMOVE(nmp->nm_clp, nfsc_list); | LIST_REMOVE(nmp->nm_clp, nfsc_list); | ||||
NFSUNLOCKCLSTATE(); | NFSUNLOCKCLSTATE(); | ||||
free(nmp->nm_clp, M_NFSCLCLIENT); | free(nmp->nm_clp, M_NFSCLCLIENT); | ||||
} | } | ||||
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) { | TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) { | ||||
if (dsp != TAILQ_FIRST(&nmp->nm_sess) && | if (dsp != TAILQ_FIRST(&nmp->nm_sess) && | ||||
dsp->nfsclds_sockp != NULL) | dsp->nfsclds_sockp != NULL) | ||||
newnfs_disconnect(dsp->nfsclds_sockp); | newnfs_disconnect(NULL, dsp->nfsclds_sockp); | ||||
nfscl_freenfsclds(dsp); | nfscl_freenfsclds(dsp); | ||||
} | } | ||||
free(nmp->nm_tlscertname, M_NEWNFSMNT); | free(nmp->nm_tlscertname, M_NEWNFSMNT); | ||||
free(nmp, M_NEWNFSMNT); | free(nmp, M_NEWNFSMNT); | ||||
free(nam, M_SONAME); | free(nam, M_SONAME); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | nfs_unmount(struct mount *mp, int mntflags) | ||||
mtx_lock(&mountlist_mtx); | mtx_lock(&mountlist_mtx); | ||||
mtx_lock(&nmp->nm_mtx); | mtx_lock(&nmp->nm_mtx); | ||||
mp->mnt_data = NULL; | mp->mnt_data = NULL; | ||||
mtx_unlock(&mountlist_mtx); | mtx_unlock(&mountlist_mtx); | ||||
while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0) | while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0) | ||||
msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0); | msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0); | ||||
mtx_unlock(&nmp->nm_mtx); | mtx_unlock(&nmp->nm_mtx); | ||||
newnfs_disconnect(&nmp->nm_sockreq); | newnfs_disconnect(nmp, &nmp->nm_sockreq); | ||||
crfree(nmp->nm_sockreq.nr_cred); | crfree(nmp->nm_sockreq.nr_cred); | ||||
free(nmp->nm_nam, M_SONAME); | free(nmp->nm_nam, M_SONAME); | ||||
if (nmp->nm_sockreq.nr_auth != NULL) | if (nmp->nm_sockreq.nr_auth != NULL) | ||||
AUTH_DESTROY(nmp->nm_sockreq.nr_auth); | AUTH_DESTROY(nmp->nm_sockreq.nr_auth); | ||||
mtx_destroy(&nmp->nm_sockreq.nr_mtx); | mtx_destroy(&nmp->nm_sockreq.nr_mtx); | ||||
mtx_destroy(&nmp->nm_mtx); | mtx_destroy(&nmp->nm_mtx); | ||||
TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) { | TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) { | ||||
if (dsp != TAILQ_FIRST(&nmp->nm_sess) && | if (dsp != TAILQ_FIRST(&nmp->nm_sess) && | ||||
dsp->nfsclds_sockp != NULL) | dsp->nfsclds_sockp != NULL) | ||||
newnfs_disconnect(dsp->nfsclds_sockp); | newnfs_disconnect(NULL, dsp->nfsclds_sockp); | ||||
nfscl_freenfsclds(dsp); | nfscl_freenfsclds(dsp); | ||||
} | } | ||||
free(nmp->nm_tlscertname, M_NEWNFSMNT); | free(nmp->nm_tlscertname, M_NEWNFSMNT); | ||||
free(nmp, M_NEWNFSMNT); | free(nmp, M_NEWNFSMNT); | ||||
out: | out: | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen) | ||||
nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen); | nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen); | ||||
nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen); | nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport", | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport", | ||||
&buf, &blen); | &buf, &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf, | nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf, | ||||
&blen); | &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn", | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn", | ||||
&buf, &blen); | &buf, &blen); | ||||
nfscl_printoptval(nmp, nmp->nm_aconnect + 1, ",nconnect", &buf, &blen); | |||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf, | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf, | ||||
&blen); | &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf, | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf, | ||||
&blen); | &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf, | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf, | ||||
&blen); | &blen); | ||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf, | nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf, | ||||
&blen); | &blen); | ||||
Show All 37 Lines |
Am I right that a mount -u which tries to modify nconnect is effectively ignored? Should it be an explicit error? Or is it worth trying to handle that?