diff options
author | dm120769 <none@none> | 2007-04-19 14:39:35 -0700 |
---|---|---|
committer | dm120769 <none@none> | 2007-04-19 14:39:35 -0700 |
commit | 5e1e04ce077ee9badc488dc9562a228f2609823c (patch) | |
tree | a22ae60d03e9552afce8994231d13a0c280716ef /usr/src | |
parent | 6adaf03e130142c9de7b6c050f0d0b1df4e73044 (diff) | |
download | illumos-gate-5e1e04ce077ee9badc488dc9562a228f2609823c.tar.gz |
backout 4689230/6224349: needs more work
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fs.d/autofs/autod_main.c | 102 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/autod_nfs.c | 8 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/autod_xdr.c | 580 | ||||
-rw-r--r-- | usr/src/uts/common/fs/autofs/auto_subr.c | 592 | ||||
-rw-r--r-- | usr/src/uts/common/fs/autofs/auto_xdr.c | 618 |
5 files changed, 353 insertions, 1547 deletions
diff --git a/usr/src/cmd/fs.d/autofs/autod_main.c b/usr/src/cmd/fs.d/autofs/autod_main.c index cee127cb9b..5d9a109c7a 100644 --- a/usr/src/cmd/fs.d/autofs/autod_main.c +++ b/usr/src/cmd/fs.d/autofs/autod_main.c @@ -80,7 +80,6 @@ static void free_action_list(); static int start_autofs_svcs(); static void automountd_wait_for_cleanup(pid_t); - /* * Private autofs system call */ @@ -455,9 +454,8 @@ autofs_mntinfo_1_r( m->path, m->isdirect); } - bzero(res, sizeof (*res)); status = do_mount1(m->map, m->name, m->subdir, m->opts, m->path, - (uint_t)m->isdirect, m->uid, &alp, DOMOUNT_KERNEL); + (uint_t)m->isdirect, m->uid, &alp, DOMOUNT_USER); if (status != 0) { /* * An error occurred, free action list if allocated. @@ -468,6 +466,9 @@ autofs_mntinfo_1_r( } } if (alp != NULL) { + /* + * Return action list to kernel. + */ res->mr_type.status = AUTOFS_ACTION; res->mr_type.mount_result_type_u.list = alp; } else { @@ -730,7 +731,7 @@ autofs_doorfunc( failed_res.res_status = error; failed_res.xdr_len = 0; res = (caddr_t)&failed_res; - res_size = sizeof (autofs_door_res_t); + res_size = 0; break; } bzero(&lookup_res, sizeof (autofs_lookupres)); @@ -739,19 +740,14 @@ autofs_doorfunc( autofs_lookup_1_free_args(xdrargs); free(xdrargs); - door_res = NULL; + if (!encode_res(xdr_autofs_lookupres, &door_res, (caddr_t)&lookup_res, &res_size)) { - res_size = sizeof (autofs_door_res_t); - if (door_res == NULL) { - syslog(LOG_ERR, "error allocating lookup" - "results buffer"); - failed_res.res_status = ENOMEM; - failed_res.xdr_len = 0; - res = (caddr_t)&failed_res; - } else { - res = (caddr_t)door_res; - } + syslog(LOG_ERR, "error allocating lookup" + "results buffer"); + failed_res.res_status = EINVAL; + failed_res.xdr_len = 0; + res = (caddr_t)&failed_res; } else { door_res->res_status = 0; res = (caddr_t)door_res; @@ -767,13 +763,11 @@ autofs_doorfunc( failed_res.res_status = error; failed_res.xdr_len = 0; res = (caddr_t)&failed_res; - res_size = sizeof (autofs_door_res_t); + res_size = 0; break; } - bzero(&mount_res, sizeof (struct autofs_mountres)); - autofs_mntinfo_1_r((autofs_lookupargs *)xdrargs, - &mount_res); + autofs_mntinfo_1_r((autofs_lookupargs *)xdrargs, &mount_res); autofs_lookup_1_free_args(xdrargs); free(xdrargs); @@ -781,26 +775,20 @@ autofs_doorfunc( /* * Only reason we would get a NULL res is because * we could not allocate a results buffer. Use - * a local result buffer to return ENOMEM. + * a local one to return the error EAGAIN as has + * always been done when memory allocations fail. */ - door_res = NULL; if (!encode_res(xdr_autofs_mountres, &door_res, (caddr_t)&mount_res, &res_size)) { - res_size = sizeof (autofs_door_res_t); - if (door_res == NULL) { - syslog(LOG_ERR, "error allocating mount" - "results buffer"); - failed_res.res_status = ENOMEM; - failed_res.xdr_len = 0; - res = (caddr_t)&failed_res; - } else { - res = (caddr_t)door_res; - } + syslog(LOG_ERR, "error allocating mount" + "results buffer"); + failed_res.res_status = EAGAIN; + failed_res.xdr_len = 0; + res = (caddr_t)&failed_res; } else { door_res->res_status = 0; res = (caddr_t)door_res; } - autofs_mount_1_free_r(&mount_res); break; @@ -823,19 +811,15 @@ autofs_doorfunc( autofs_unmount_1_free_args(umnt_args); free(umnt_args); - door_res = NULL; + if (!encode_res(xdr_umntres, &door_res, (caddr_t)&umount_res, &res_size)) { + syslog(LOG_ERR, "error allocating unmount" + "results buffer"); + failed_res.res_status = EINVAL; + failed_res.xdr_len = 0; + res = (caddr_t)&failed_res; res_size = sizeof (autofs_door_res_t); - if (door_res == NULL) { - syslog(LOG_ERR, "error allocating unmount" - "results buffer"); - failed_res.res_status = ENOMEM; - failed_res.xdr_len = 0; - res = (caddr_t)&failed_res; - } else { - res = (caddr_t)door_res; - } } else { door_res->res_status = 0; res = (caddr_t)door_res; @@ -860,19 +844,15 @@ autofs_doorfunc( free(rddir_args->rda_map); free(rddir_args); - door_res = NULL; + if (!encode_res(xdr_autofs_rddirres, &door_res, (caddr_t)&rddir_res, &res_size)) { + syslog(LOG_ERR, "error allocating readdir" + "results buffer"); + failed_res.res_status = ENOMEM; + failed_res.xdr_len = 0; + res = (caddr_t)&failed_res; res_size = sizeof (autofs_door_res_t); - if (door_res == NULL) { - syslog(LOG_ERR, "error allocating readdir" - "results buffer"); - failed_res.res_status = ENOMEM; - failed_res.xdr_len = 0; - res = (caddr_t)&failed_res; - } else { - res = (caddr_t)door_res; - } } else { door_res->res_status = 0; res = (caddr_t)door_res; @@ -904,11 +884,8 @@ autofs_doorfunc( /* * If we got here, door_return failed. */ - - syslog(LOG_ERR, - "door_return failed %d, errno: %d, proc: %d," - " buffer %p, buffer size %d", - error, errno, which, (void *)res, res_size); + syslog(LOG_ERR, "door_return failed %d, buffer %p, buffer size %d", + error, (void *)res, res_size); } static int @@ -1012,13 +989,13 @@ encode_res( caddr_t resp, int *size) { - XDR xdrs; - int status; + XDR xdrs; *size = xdr_sizeof((*xdrfunc), resp); *results = autofs_get_buffer( sizeof (autofs_door_res_t) + *size); if (*results == NULL) { + (*results)->res_status = ENOMEM; return (FALSE); } (*results)->xdr_len = *size; @@ -1026,10 +1003,9 @@ encode_res( xdrmem_create(&xdrs, (caddr_t)((*results)->xdr_res), (*results)->xdr_len, XDR_ENCODE); - status = (*xdrfunc)(&xdrs, resp); - if (!status) { - (*results)->res_status = status; - syslog(LOG_ERR, "error encoding results %p", xdrfunc); + if (!(*xdrfunc)(&xdrs, resp)) { + (*results)->res_status = EINVAL; + syslog(LOG_ERR, "error encoding results"); return (FALSE); } (*results)->res_status = 0; diff --git a/usr/src/cmd/fs.d/autofs/autod_nfs.c b/usr/src/cmd/fs.d/autofs/autod_nfs.c index 3a860f6413..2effa3f6c5 100644 --- a/usr/src/cmd/fs.d/autofs/autod_nfs.c +++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c @@ -279,14 +279,6 @@ mount_nfs( trace_prt(1, " Couldn't mount %s:%s, err=%d\n", mfs->mfs_host, mfs->mfs_dir, err); } - /* - * Free Action list as it is not needed here if cached - * because nfsmount would have done the mount. - */ - if (cached && (alp)) { - free(alp); - *alpp = NULL; - } } free_mfs(mfs); return (err); diff --git a/usr/src/cmd/fs.d/autofs/autod_xdr.c b/usr/src/cmd/fs.d/autofs/autod_xdr.c index 17bcef3358..d474378ff6 100644 --- a/usr/src/cmd/fs.d/autofs/autod_xdr.c +++ b/usr/src/cmd/fs.d/autofs/autod_xdr.c @@ -38,28 +38,6 @@ #include <string.h> #include <rpcsvc/autofs_prot.h> #include <rpc/xdr.h> -#include <sys/pathconf.h> -#include <rpc/auth.h> -#include <rpc/rpcsec_gss.h> -#include <nfs/mount.h> -#include <sys/thread.h> -#include <sys/utsname.h> -#include <nfs/rnode.h> - -#define FS_NFS2 2 -#define FS_NFS3 3 -#define FS_NFS4 4 -#define NFS4_FHSIZE 128 - -static bool_t -xdr_nfs_args(XDR *xdrs, struct nfs_args *objp); - -static bool_t -xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp); - -static bool_t -xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp); - bool_t xdr_autofs_stat(register XDR *xdrs, autofs_stat *objp) @@ -127,539 +105,6 @@ xdr_autofs_args(register XDR *xdrs, autofs_args *objp) } bool_t -xdr_knetconfig(xdrs, objp) - XDR *xdrs; -struct knetconfig *objp; -{ - - rpc_inline_t *buf; - - int i; - - if (xdrs->x_op == XDR_ENCODE) { - if (!xdr_u_int(xdrs, &objp->knc_semantics)) - return (FALSE); - if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE)) - return (FALSE); - if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE)) - return (FALSE); - if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev)) - return (FALSE); - buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8, - sizeof (uint_t), (xdrproc_t)xdr_u_int)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - { - uint_t *genp; - - for (i = 0, genp = objp->knc_unused; i < 8; - i++) { - IXDR_PUT_U_INT32(buf, *genp++); - } - } -#else - { - uint_t *genp; - - for (i = 0, genp = objp->knc_unused; i < 8; - i++) { - IXDR_PUT_U_LONG(buf, *genp++); - } - } -#endif - } - return (TRUE); - - } - if (!xdr_u_int(xdrs, &objp->knc_semantics)) - return (FALSE); - if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE)) - return (FALSE); - if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE)) - return (FALSE); - - if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8, - sizeof (uint_t), (xdrproc_t)xdr_u_int)) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_pathcnf(XDR *xdrs, struct pathcnf *objp) -{ - - rpc_inline_t *buf; - - int i; - - if (xdrs->x_op == XDR_ENCODE) { - buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_int(xdrs, &objp->pc_link_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_canon)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_input)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_name_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_path_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_pipe_buf)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - IXDR_PUT_INT32(buf, objp->pc_link_max); - IXDR_PUT_SHORT(buf, objp->pc_max_canon); - IXDR_PUT_SHORT(buf, objp->pc_max_input); - IXDR_PUT_SHORT(buf, objp->pc_name_max); - IXDR_PUT_SHORT(buf, objp->pc_path_max); - IXDR_PUT_SHORT(buf, objp->pc_pipe_buf); -#else - IXDR_PUT_LONG(buf, objp->pc_link_max); - IXDR_PUT_SHORT(buf, objp->pc_max_canon); - IXDR_PUT_SHORT(buf, objp->pc_max_input); - IXDR_PUT_SHORT(buf, objp->pc_name_max); - IXDR_PUT_SHORT(buf, objp->pc_path_max); - IXDR_PUT_SHORT(buf, objp->pc_pipe_buf); -#endif - } - if (!xdr_char(xdrs, (char *)&objp->pc_vdisable)) - return (FALSE); - if (!xdr_char(xdrs, &objp->pc_xxx)) - return (FALSE); - buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N, - sizeof (short), (xdrproc_t)xdr_short)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - short *genp; - - for (i = 0, genp = objp->pc_mask; i < _PC_N; - i++) { - IXDR_PUT_SHORT(buf, *genp++); - } -#else - short *genp; - - for (i = 0, genp = objp->pc_mask; i < _PC_N; - i++) { - IXDR_PUT_SHORT(buf, *genp++); - } -#endif - } - return (TRUE); - } else if (xdrs->x_op == XDR_DECODE) { - buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_int(xdrs, &objp->pc_link_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_canon)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_input)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_name_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_path_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_pipe_buf)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - objp->pc_link_max = IXDR_GET_INT32(buf); - objp->pc_max_canon = IXDR_GET_SHORT(buf); - objp->pc_max_input = IXDR_GET_SHORT(buf); - objp->pc_name_max = IXDR_GET_SHORT(buf); - objp->pc_path_max = IXDR_GET_SHORT(buf); - objp->pc_pipe_buf = IXDR_GET_SHORT(buf); -#else - objp->pc_link_max = IXDR_GET_LONG(buf); - objp->pc_max_canon = IXDR_GET_SHORT(buf); - objp->pc_max_input = IXDR_GET_SHORT(buf); - objp->pc_name_max = IXDR_GET_SHORT(buf); - objp->pc_path_max = IXDR_GET_SHORT(buf); - objp->pc_pipe_buf = IXDR_GET_SHORT(buf); -#endif - } - if (!xdr_char(xdrs, (char *)&objp->pc_vdisable)) - return (FALSE); - if (!xdr_char(xdrs, &objp->pc_xxx)) - return (FALSE); - buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N, - sizeof (short), (xdrproc_t)xdr_short)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - short *genp; - - for (i = 0, genp = objp->pc_mask; i < _PC_N; - i++) { - *genp++ = IXDR_GET_SHORT(buf); - } -#else - short *genp; - - for (i = 0, genp = objp->pc_mask; - i < _PC_N; i++) { - *genp++ = IXDR_GET_SHORT(buf); - } -#endif - } - return (TRUE); - } - - if (!xdr_int(xdrs, &objp->pc_link_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_canon)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_input)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_name_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_path_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_pipe_buf)) - return (FALSE); - if (!xdr_char(xdrs, (char *)&objp->pc_vdisable)) - return (FALSE); - if (!xdr_char(xdrs, &objp->pc_xxx)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N, - sizeof (short), (xdrproc_t)xdr_short)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_des_clnt_data(XDR *xdrs, dh_k4_clntdata_t *objp) -{ - - rpc_inline_t *buf; - - if (!xdr_autofs_netbuf(xdrs, &objp->syncaddr)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_string(xdrs, &objp->netname, SYS_NMLN)) - return (FALSE); - if (!xdr_int(xdrs, &objp->netnamelen)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_gss_clnt_data(XDR *xdrs, struct gss_clnt_data *objp) -{ - - rpc_inline_t *buf; - - - if (!xdr_u_int(xdrs, &objp->mechanism.length)) - return (FALSE); - if (!xdr_enum(xdrs, (enum_t *)&objp->service)) - return (FALSE); - if (!xdr_opaque(xdrs, objp->mechanism.elements, - objp->mechanism.length)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->uname, MAX_NAME_LEN, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->inst, MAX_NAME_LEN, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_vector(xdrs, (char *)objp->realm, MAX_NAME_LEN, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->qop)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_sec_data(XDR *xdrs, struct sec_data *objp) -{ - - rpc_inline_t *buf; - - if (!xdr_u_int(xdrs, &objp->secmod)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->rpcflavor)) - return (FALSE); - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_uid_t(xdrs, &objp->uid)) - return (FALSE); - - switch (objp->rpcflavor) { - case AUTH_NONE: - case AUTH_UNIX: - case AUTH_LOOPBACK: - break; - case AUTH_DES: - if (!xdr_pointer(xdrs, (char **)&objp->data, - sizeof (dh_k4_clntdata_t), - (xdrproc_t)xdr_des_clnt_data)) - return (FALSE); - break; - case RPCSEC_GSS: - if (!xdr_pointer(xdrs, (char **)&objp->data, - sizeof (gss_clntdata_t), - (xdrproc_t)xdr_gss_clnt_data)) - return (FALSE); - break; - default: - return (FALSE); - } - - return (TRUE); -} - -bool_t -xdr_nfs2_fh(XDR *xdrs, void *objp) -{ - if (!xdr_opaque(xdrs, (char *)objp, NFS_FHSIZE)) - return (B_FALSE); - return (B_TRUE); -} - -bool_t -xdr_nfs3_fhandle(XDR *xdrs, nfs_fhandle *objp) -{ - if (!xdr_int(xdrs, &objp->fh_len)) - return (B_FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, objp->fh_len)) - return (B_FALSE); - return (B_TRUE); -} - -bool_t -xdr_nfs(XDR *xdrs, struct nfs_args *objp, int nfsv) -{ - - rpc_inline_t *buf; - - if (objp == NULL) - return (TRUE); - - if (xdrs->x_op == XDR_ENCODE) { - if (!xdr_pointer(xdrs, (char **)&objp->addr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->syncaddr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN)) - return (FALSE); - if (!xdr_string(xdrs, &objp->netname, SYS_NMLN)) - return (FALSE); - if (nfsv == FS_NFS4) { - if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE)) - return (B_FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs3_fhandle)) - return (B_FALSE); - } else { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - NFS_FHSIZE, - (xdrproc_t)xdr_nfs2_fh)) - return (B_FALSE); - } - buf = XDR_INLINE(xdrs, 9 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_int(xdrs, &objp->wsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->rsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->timeo)) - return (FALSE); - if (!xdr_int(xdrs, &objp->retrans)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmax)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmax)) - return (FALSE); - } else { -#if defined(_LP64) || defined(_KERNEL) - IXDR_PUT_INT32(buf, objp->flags); - IXDR_PUT_INT32(buf, objp->wsize); - IXDR_PUT_INT32(buf, objp->rsize); - IXDR_PUT_INT32(buf, objp->timeo); - IXDR_PUT_INT32(buf, objp->retrans); - IXDR_PUT_INT32(buf, objp->acregmin); - IXDR_PUT_INT32(buf, objp->acregmax); - IXDR_PUT_INT32(buf, objp->acdirmin); - IXDR_PUT_INT32(buf, objp->acdirmax); -#else - IXDR_PUT_LONG(buf, objp->flags); - IXDR_PUT_LONG(buf, objp->wsize); - IXDR_PUT_LONG(buf, objp->rsize); - IXDR_PUT_LONG(buf, objp->timeo); - IXDR_PUT_LONG(buf, objp->retrans); - IXDR_PUT_LONG(buf, objp->acregmin); - IXDR_PUT_LONG(buf, objp->acregmax); - IXDR_PUT_LONG(buf, objp->acdirmin); - IXDR_PUT_LONG(buf, objp->acdirmax); -#endif - } - if (!xdr_pointer(xdrs, (char **)&objp->pathconf, - sizeof (struct pathcnf), - (xdrproc_t)xdr_pathcnf)) - return (FALSE); - if (!xdr_int(xdrs, &objp->nfs_args_ext)) - return (FALSE); - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extA.secdata, - sizeof (struct sec_data), - (xdrproc_t)xdr_sec_data)) - return (FALSE); - if (objp->nfs_args_ext == NFS_ARGS_EXTB) { - if (nfsv == FS_NFS4) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - } else { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs_args)) - return (FALSE); - } - } - return (TRUE); - } - - /* Not a DECODE operation */ - if (!xdr_pointer(xdrs, (char **)&objp->addr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->syncaddr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->hostname, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->netname, - sizeof (char), (xdrproc_t)xdr_char)) - return (FALSE); - if (nfsv == FS_NFS4) { - if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE)) - return (B_FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs3_fhandle)) - return (B_FALSE); - } else { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - NFS_FHSIZE, - (xdrproc_t)xdr_nfs2_fh)) - return (B_FALSE); - } - - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_int(xdrs, &objp->wsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->rsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->timeo)) - return (FALSE); - if (!xdr_int(xdrs, &objp->retrans)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmax)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmax)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->pathconf, - sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf)) - return (FALSE); - if (!xdr_int(xdrs, &objp->nfs_args_ext)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->nfs_ext_u.nfs_extA.secdata, - sizeof (struct sec_data), (xdrproc_t)xdr_sec_data)) - return (FALSE); - if (objp->nfs_args_ext == NFS_ARGS_EXTB) { - if (nfsv == FS_NFS4) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - } else { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs_args)) - return (FALSE); - } - - } - return (TRUE); -} - -static bool_t -xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS4)); -} - -static bool_t -xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS3)); -} - -static bool_t -xdr_nfs_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS2)); -} - - -bool_t xdr_mounta(register XDR *xdrs, struct mounta *objp) { if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN)) @@ -670,30 +115,11 @@ xdr_mounta(register XDR *xdrs, struct mounta *objp) return (FALSE); if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN)) return (FALSE); - if (strncmp(objp->fstype, "autofs", 6) == 0) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (autofs_args), - (xdrproc_t)xdr_autofs_args)) - return (FALSE); - } else if (strncmp(objp->fstype, "nfs4", 4) == 0) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - } else if (strncmp(objp->fstype, "nfs3", 4) == 0) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - } else { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs_args)) - return (FALSE); - } + if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args), + (xdrproc_t)xdr_autofs_args)) + return (FALSE); if (!xdr_int(xdrs, &objp->datalen)) return (FALSE); - if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN)) return (FALSE); if (!xdr_int(xdrs, &objp->optlen)) diff --git a/usr/src/uts/common/fs/autofs/auto_subr.c b/usr/src/uts/common/fs/autofs/auto_subr.c index 3201e8ce6c..41cfd3c5cd 100644 --- a/usr/src/uts/common/fs/autofs/auto_subr.c +++ b/usr/src/uts/common/fs/autofs/auto_subr.c @@ -775,6 +775,56 @@ auto_perform_link(fnnode_t *fnp, struct linka *linkp, cred_t *cred) return (0); } +static void +auto_free_autofs_args(struct mounta *m) +{ + autofs_args *aargs = (autofs_args *)m->dataptr; + + if (aargs->addr.buf) + kmem_free(aargs->addr.buf, aargs->addr.len); + if (aargs->path) + kmem_free(aargs->path, strlen(aargs->path) + 1); + if (aargs->opts) + kmem_free(aargs->opts, strlen(aargs->opts) + 1); + if (aargs->map) + kmem_free(aargs->map, strlen(aargs->map) + 1); + if (aargs->subdir) + kmem_free(aargs->subdir, strlen(aargs->subdir) + 1); + if (aargs->key) + kmem_free(aargs->key, strlen(aargs->key) + 1); + kmem_free(aargs, sizeof (*aargs)); +} + +static void +auto_free_action_list(action_list *alp) +{ + struct mounta *m; + action_list *lastalp; + char *fstype; + + m = &alp->action.action_list_entry_u.mounta; + while (alp != NULL) { + fstype = alp->action.action_list_entry_u.mounta.fstype; + m = &alp->action.action_list_entry_u.mounta; + if (m->dataptr) { + if (strcmp(fstype, "autofs") == 0) { + auto_free_autofs_args(m); + } + } + if (m->spec) + kmem_free(m->spec, strlen(m->spec) + 1); + if (m->dir) + kmem_free(m->dir, strlen(m->dir) + 1); + if (m->fstype) + kmem_free(m->fstype, strlen(m->fstype) + 1); + if (m->optptr) + kmem_free(m->optptr, m->optlen); + lastalp = alp; + alp = alp->next; + kmem_free(lastalp, sizeof (*lastalp)); + } +} + static boolean_t auto_invalid_autofs(fninfo_t *dfnip, fnnode_t *dfnp, action_list *p) { @@ -784,6 +834,7 @@ auto_invalid_autofs(fninfo_t *dfnip, fnnode_t *dfnp, action_list *p) char buff[AUTOFS_MAXPATHLEN]; size_t len; struct autofs_globals *fngp; + fngp = dfnp->fn_globals; dvp = fntovn(dfnp); @@ -795,10 +846,10 @@ auto_invalid_autofs(fninfo_t *dfnip, fnnode_t *dfnp, action_list *p) * We also only want to perform autofs mounts, so make sure * no-one is trying to trick us into doing anything else. */ - if (m->dir[0] != '.' || + if (m->spec == NULL || m->dir == NULL || m->dir[0] != '.' || (m->dir[1] != '/' && m->dir[1] != '\0') || - strcmp(m->fstype, "autofs") != 0 || - m->datalen != sizeof (struct autofs_args) || + m->fstype == NULL || strcmp(m->fstype, "autofs") != 0 || + m->dataptr == NULL || m->datalen != sizeof (struct autofs_args) || m->optptr == NULL) return (B_TRUE); /* @@ -853,47 +904,19 @@ auto_invalid_autofs(fninfo_t *dfnip, fnnode_t *dfnp, action_list *p) /* * auto_invalid_action will validate the action_list received. If all is good - * this function returns FALSE, if there is a problem it returned TRUE. - * Based on the mount type, autofs or nfs, it dispatchs to auto_invalid_autofs - * or validates the fstype is nfs. For nfs mounts, the spec, dir, datalen - * etc should all either be good here, or have already been checked. + * this function returns FALSE, if there is a problem it returns TRUE. */ - static boolean_t auto_invalid_action(fninfo_t *dfnip, fnnode_t *dfnp, action_list *alistpp) { - struct mounta *m; /* * Before we go any further, this better be a mount request. */ if (alistpp->action.action != AUTOFS_MOUNT_RQ) return (B_TRUE); + return (auto_invalid_autofs(dfnip, dfnp, alistpp)); - m = &alistpp->action.action_list_entry_u.mounta; - /* - * Make sure we aren't geting passed NULL values or a "dir" that - * isn't "." and doesn't begin with "./". - * - * We also only want to perform autofs mounts, so make sure - * no-one is trying to trick us into doing anything else. - */ - if (m->spec == NULL || m->dir == NULL || - m->fstype == NULL || m->dataptr == NULL) - return (B_TRUE); - - /* - * Dispatch to the appropriate validation routine based - * on the filesystem type. - */ - if (strncmp(alistpp->action.action_list_entry_u.mounta.fstype, - "autofs", 6) == 0) { - return (auto_invalid_autofs(dfnip, dfnp, alistpp)); - } else if (strncmp(alistpp->action.action_list_entry_u.mounta.fstype, - "nfs", 3) == 0) { - return (B_FALSE); - } - return (B_TRUE); } static int @@ -946,7 +969,6 @@ auto_perform_actions( * This conversation is over. */ xdr_free(xdr_action_list, (char *)alp); - kmem_free(alp, sizeof (*alp)); return (EINVAL); } } @@ -954,21 +976,6 @@ auto_perform_actions( zcred = zone_get_kcred(getzoneid()); ASSERT(zcred != NULL); - /* - * Clear MF_MOUNTPOINT, if the NFS mount is required and - * completes successfully, we will then set MF_MOUNTPOINT. - */ - mutex_enter(&dfnp->fn_lock); - if (dfnp->fn_flags & MF_MOUNTPOINT) { - AUTOFS_DPRINT((10, "autofs: clearing mountpoint " - "flag on %s.", dfnp->fn_name)); - ASSERT(dfnp->fn_dirents == NULL); - ASSERT(dfnp->fn_trigger == NULL); - } - dfnp->fn_flags &= ~MF_MOUNTPOINT; - mutex_exit(&dfnp->fn_lock); - - if (vn_mountedvfs(dvp) != NULL) { /* * The daemon successfully mounted a filesystem @@ -1003,300 +1010,261 @@ auto_perform_actions( m = &p->action.action_list_entry_u.mounta; argsp = (struct autofs_args *)m->dataptr; - if (strncmp(m->fstype, "nfs", 3) == 0) { - if (vn_mountedvfs(dvp) != NULL) { - /* - * Its possible that the filesystem is - * already mounted if nfs because we are - * being called from unmount_tree when - * if failed to unmount a node from a - * trigger point, and is remounting again and - * this particular filesystem was not - * unmounted. - */ - mutex_enter(&dfnp->fn_lock); - dfnp->fn_flags |= MF_MOUNTPOINT; - mutex_exit(&dfnp->fn_lock); - } else { - m->flags |= MS_SYSSPACE; - VN_HOLD(dvp); - error = domount(NULL, m, dvp, zcred, &vfsp); - if (!error) { - VFS_RELE(vfsp); - mutex_enter(&dfnp->fn_lock); - dfnp->fn_flags |= MF_MOUNTPOINT; - ASSERT(dfnp->fn_dirents == NULL); - mutex_exit(&dfnp->fn_lock); - success++; - } - VN_RELE(dvp); - } - } else { - ASSERT(strcmp(m->fstype, "autofs") == 0); + ASSERT(strcmp(m->fstype, "autofs") == 0); + /* + * use the parent directory's timeout since it's the + * one specified/inherited by automount. + */ + argsp->mount_to = dfnip->fi_mount_to; + /* + * The mountpoint is relative, and it is guaranteed to + * begin with "." + * + */ + ASSERT(m->dir[0] == '.'); + if (m->dir[0] == '.' && m->dir[1] == '\0') { /* - * use the parent directory's timeout since it's the - * one specified/inherited by automount. + * mounting on the trigger node */ - argsp->mount_to = dfnip->fi_mount_to; + mvp = dvp; + VN_HOLD(mvp); + goto mount; + } + /* + * ignore "./" in front of mountpoint + */ + ASSERT(m->dir[1] == '/'); + mntpnt = m->dir + 2; + + AUTOFS_DPRINT((10, "\tdfnip->fi_path=%s\n", dfnip->fi_path)); + AUTOFS_DPRINT((10, "\tdfnip->fi_flags=%x\n", dfnip->fi_flags)); + AUTOFS_DPRINT((10, "\tmntpnt=%s\n", mntpnt)); + + if (dfnip->fi_flags & MF_DIRECT) { + AUTOFS_DPRINT((10, "\tDIRECT\n")); + (void) sprintf(buff, "%s/%s", dfnip->fi_path, + mntpnt); + } else { + AUTOFS_DPRINT((10, "\tINDIRECT\n")); + (void) sprintf(buff, "%s/%s/%s", + dfnip->fi_path, + dfnp->fn_name, mntpnt); + } + + if (vn_mountedvfs(dvp) == NULL) { /* - * The mountpoint is relative, and it is guaranteed to - * begin with "." + * Daemon didn't mount anything on the root + * We have to create the mountpoint if it + * doesn't exist already * + * We use the caller's credentials in case a + * UID-match is required + * (MF_THISUID_MATCH_RQD). */ - ASSERT(m->dir[0] == '.'); - if (m->dir[0] == '.' && m->dir[1] == '\0') { + rw_enter(&dfnp->fn_rwlock, RW_WRITER); + error = auto_search(dfnp, mntpnt, &mfnp, cred); + if (error == 0) { /* - * mounting on the trigger node + * AUTOFS mountpoint exists */ - mvp = dvp; - VN_HOLD(mvp); - goto mount; - } - /* - * ignore "./" in front of mountpoint - */ - ASSERT(m->dir[1] == '/'); - mntpnt = m->dir + 2; - - AUTOFS_DPRINT((10, "\tdfnip->fi_path=%s\n", - dfnip->fi_path)); - AUTOFS_DPRINT((10, "\tdfnip->fi_flags=%x\n", - dfnip->fi_flags)); - AUTOFS_DPRINT((10, "\tmntpnt=%s\n", mntpnt)); - - if (dfnip->fi_flags & MF_DIRECT) { - AUTOFS_DPRINT((10, "\tDIRECT\n")); - (void) sprintf(buff, "%s/%s", dfnip->fi_path, - mntpnt); + if (vn_mountedvfs(fntovn(mfnp)) != NULL) { + cmn_err(CE_PANIC, + "auto_perform_actions:" + " mfnp=%p covered", + (void *)mfnp); + } } else { - AUTOFS_DPRINT((10, "\tINDIRECT\n")); - (void) sprintf(buff, "%s/%s/%s", - dfnip->fi_path, - dfnp->fn_name, mntpnt); - } - - if (vn_mountedvfs(dvp) == NULL) { /* - * Daemon didn't mount anything on the root - * We have to create the mountpoint if it - * doesn't exist already - * - * We use the caller's credentials in case a - * UID-match is required - * (MF_THISUID_MATCH_RQD). + * Create AUTOFS mountpoint */ - rw_enter(&dfnp->fn_rwlock, RW_WRITER); - error = auto_search(dfnp, mntpnt, &mfnp, cred); - if (error == 0) { - /* - * AUTOFS mountpoint exists - */ - if (vn_mountedvfs(fntovn(mfnp)) - != NULL) { - cmn_err(CE_PANIC, - "auto_perform_actions:" - " mfnp=%p covered", - (void *)mfnp); - } - } else { - /* - * Create AUTOFS mountpoint - */ - ASSERT((dfnp->fn_flags & - MF_MOUNTPOINT) == 0); - error = auto_enter(dfnp, mntpnt, - &mfnp, cred); - ASSERT(mfnp->fn_linkcnt == 1); - mfnp->fn_linkcnt++; - } - if (!error) - update_times = 1; - rw_exit(&dfnp->fn_rwlock); - ASSERT(error != EEXIST); - if (!error) { - /* - * mfnp is already held. - */ - mvp = fntovn(mfnp); - } else { - auto_log(fngp->fng_verbose, - fngp->fng_zoneid, - CE_WARN, "autofs: mount of %s " - "failed - can't create" - " mountpoint.", buff); - continue; - } - } else { + ASSERT((dfnp->fn_flags & MF_MOUNTPOINT) == 0); + error = auto_enter(dfnp, mntpnt, &mfnp, cred); + ASSERT(mfnp->fn_linkcnt == 1); + mfnp->fn_linkcnt++; + } + if (!error) + update_times = 1; + rw_exit(&dfnp->fn_rwlock); + ASSERT(error != EEXIST); + if (!error) { /* - * Find mountpoint in VFS mounted here. If not - * found, fail the submount, though the overall - * mount has succeeded since the root is - * mounted. + * mfnp is already held. */ - if (error = auto_getmntpnt(dvp, mntpnt, &mvp, - kcred)) { - auto_log(fngp->fng_verbose, - fngp->fng_zoneid, - CE_WARN, "autofs: mount of %s " - "failed - mountpoint doesn't" - " exist.", buff); - continue; - } - if (mvp->v_type == VLNK) { - auto_log(fngp->fng_verbose, - fngp->fng_zoneid, - CE_WARN, "autofs: %s symbolic " - "link: not a valid mountpoint " - "- mount failed", buff); - VN_RELE(mvp); - error = ENOENT; + mvp = fntovn(mfnp); + } else { + auto_log(fngp->fng_verbose, fngp->fng_zoneid, + CE_WARN, "autofs: mount of %s " + "failed - can't create" + " mountpoint.", buff); continue; - } } -mount: - m->flags |= MS_SYSSPACE | MS_OPTIONSTR; - - /* - * Copy mounta struct here so we can substitute a - * buffer that is large enough to hold the returned - * option string, if that string is longer than the - * input option string. - * This can happen if there are default options enabled - * that were not in the input option string. - */ - bcopy(m, &margs, sizeof (*m)); - margs.optptr = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP); - margs.optlen = MAX_MNTOPT_STR; - (void) strcpy(margs.optptr, m->optptr); - margs.dir = argsp->path; - + } else { /* - * We use the zone's kcred because we don't want the - * zone to be able to thus do something it wouldn't - * normally be able to. + * Find mountpoint in VFS mounted here. If not + * found, fail the submount, though the overall + * mount has succeeded since the root is + * mounted. */ - error = domount(NULL, &margs, mvp, zcred, &vfsp); - kmem_free(margs.optptr, MAX_MNTOPT_STR); - if (error != 0) { - auto_log(fngp->fng_verbose, fngp->fng_zoneid, - CE_WARN, - "autofs: domount of %s failed " - "error=%d", buff, error); + if (error = auto_getmntpnt(dvp, mntpnt, &mvp, + kcred)) { + auto_log(fngp->fng_verbose, + fngp->fng_zoneid, + CE_WARN, "autofs: mount of %s " + "failed - mountpoint doesn't" + " exist.", buff); + continue; + } + if (mvp->v_type == VLNK) { + auto_log(fngp->fng_verbose, + fngp->fng_zoneid, + CE_WARN, "autofs: %s symbolic " + "link: not a valid mountpoint " + "- mount failed", buff); VN_RELE(mvp); + error = ENOENT; continue; } - VFS_RELE(vfsp); + } +mount: + m->flags |= MS_SYSSPACE | MS_OPTIONSTR; - /* - * If mountpoint is an AUTOFS node, then I'm going to - * flag it that the Filesystem mounted on top was - * mounted in the kernel so that the unmount can be - * done inside the kernel as well. - * I don't care to flag non-AUTOFS mountpoints when an - * AUTOFS in-kernel mount was done on top, because the - * unmount routine already knows that such case was - * done in the kernel. - */ - if (vfs_matchops(dvp->v_vfsp, - vfs_getops(mvp->v_vfsp))) { - mfnp = vntofn(mvp); - mutex_enter(&mfnp->fn_lock); - mfnp->fn_flags |= MF_IK_MOUNT; - mutex_exit(&mfnp->fn_lock); - } + /* + * Copy mounta struct here so we can substitute a + * buffer that is large enough to hold the returned + * option string, if that string is longer than the + * input option string. + * This can happen if there are default options enabled + * that were not in the input option string. + */ + bcopy(m, &margs, sizeof (*m)); + margs.optptr = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP); + margs.optlen = MAX_MNTOPT_STR; + (void) strcpy(margs.optptr, m->optptr); + margs.dir = argsp->path; - (void) vn_vfswlock_wait(mvp); - mvfsp = vn_mountedvfs(mvp); - if (mvfsp != NULL) { - vfs_lock_wait(mvfsp); - vn_vfsunlock(mvp); - error = VFS_ROOT(mvfsp, &newvp); - vfs_unlock(mvfsp); - if (error) { - /* - * We've dropped the locks, so let's - * get the mounted vfs again in case - * it changed. - */ - (void) vn_vfswlock_wait(mvp); - mvfsp = vn_mountedvfs(mvp); - if (mvfsp != NULL) { - error = dounmount(mvfsp, 0, - CRED()); - if (error) { - cmn_err(CE_WARN, - "autofs: could" - " not unmount" - " vfs=%p", - (void *)mvfsp); - } - } else - vn_vfsunlock(mvp); - VN_RELE(mvp); - continue; - } - } else { - vn_vfsunlock(mvp); + /* + * We use the zone's kcred because we don't want the + * zone to be able to thus do something it wouldn't + * normally be able to. + */ + error = domount(NULL, &margs, mvp, zcred, &vfsp); + kmem_free(margs.optptr, MAX_MNTOPT_STR); + if (error != 0) { + auto_log(fngp->fng_verbose, fngp->fng_zoneid, + CE_WARN, "autofs: domount of %s failed " + "error=%d", buff, error); + VN_RELE(mvp); + continue; + } + VFS_RELE(vfsp); + + /* + * If mountpoint is an AUTOFS node, then I'm going to + * flag it that the Filesystem mounted on top was + * mounted in the kernel so that the unmount can be + * done inside the kernel as well. + * I don't care to flag non-AUTOFS mountpoints when an + * AUTOFS in-kernel mount was done on top, because the + * unmount routine already knows that such case was + * done in the kernel. + */ + if (vfs_matchops(dvp->v_vfsp, + vfs_getops(mvp->v_vfsp))) { + mfnp = vntofn(mvp); + mutex_enter(&mfnp->fn_lock); + mfnp->fn_flags |= MF_IK_MOUNT; + mutex_exit(&mfnp->fn_lock); + } + + (void) vn_vfswlock_wait(mvp); + mvfsp = vn_mountedvfs(mvp); + if (mvfsp != NULL) { + vfs_lock_wait(mvfsp); + vn_vfsunlock(mvp); + error = VFS_ROOT(mvfsp, &newvp); + vfs_unlock(mvfsp); + if (error) { + /* + * We've dropped the locks, so let's + * get the mounted vfs again in case + * it changed. + */ + (void) vn_vfswlock_wait(mvp); + mvfsp = vn_mountedvfs(mvp); + if (mvfsp != NULL) { + error = dounmount(mvfsp, 0, CRED()); + if (error) { + cmn_err(CE_WARN, + "autofs: could" + " not unmount" + " vfs=%p", + (void *)mvfsp); + } + } else + vn_vfsunlock(mvp); VN_RELE(mvp); continue; } + } else { + vn_vfsunlock(mvp); + VN_RELE(mvp); + continue; + } - auto_mount = vfs_matchops(dvp->v_vfsp, - vfs_getops(newvp->v_vfsp)); - newfnp = vntofn(newvp); - newfnp->fn_parent = dfnp; + auto_mount = vfs_matchops(dvp->v_vfsp, + vfs_getops(newvp->v_vfsp)); + newfnp = vntofn(newvp); + newfnp->fn_parent = dfnp; + /* + * At this time we want to save the AUTOFS filesystem + * as a trigger node. (We only do this if the mount + * occurred on a node different from the root. + * We look at the trigger nodes during + * the automatic unmounting to make sure we remove them + * as a unit and remount them as a unit if the + * filesystem mounted at the root could not be + * unmounted. + */ + if (auto_mount && (error == 0) && (mvp != dvp)) { + save_triggers++; /* - * At this time we want to save the AUTOFS filesystem - * as a trigger node. (We only do this if the mount - * occurred on a node different from the root. - * We look at the trigger nodes during - * the automatic unmounting to make sure we remove them - * as a unit and remount them as a unit if the - * filesystem mounted at the root could not be - * unmounted. + * Add AUTOFS mount to hierarchy */ - if (auto_mount && (error == 0) && (mvp != dvp)) { - save_triggers++; - /* - * Add AUTOFS mount to hierarchy - */ - newfnp->fn_flags |= MF_TRIGGER; - rw_enter(&newfnp->fn_rwlock, RW_WRITER); - newfnp->fn_next = dfnp->fn_trigger; - rw_exit(&newfnp->fn_rwlock); - rw_enter(&dfnp->fn_rwlock, RW_WRITER); - dfnp->fn_trigger = newfnp; - rw_exit(&dfnp->fn_rwlock); - /* - * Don't VN_RELE(newvp) here since dfnp now - * holds reference to it as its trigger node. - */ - AUTOFS_DPRINT((10, - "\tadding trigger %s to %s\n", + newfnp->fn_flags |= MF_TRIGGER; + rw_enter(&newfnp->fn_rwlock, RW_WRITER); + newfnp->fn_next = dfnp->fn_trigger; + rw_exit(&newfnp->fn_rwlock); + rw_enter(&dfnp->fn_rwlock, RW_WRITER); + dfnp->fn_trigger = newfnp; + rw_exit(&dfnp->fn_rwlock); + /* + * Don't VN_RELE(newvp) here since dfnp now + * holds reference to it as its trigger node. + */ + AUTOFS_DPRINT((10, "\tadding trigger %s to %s\n", newfnp->fn_name, dfnp->fn_name)); - AUTOFS_DPRINT((10, "\tfirst trigger is %s\n", - dfnp->fn_trigger->fn_name)); - if (newfnp->fn_next != NULL) - AUTOFS_DPRINT((10, - "\tnext trigger is %s\n", - newfnp->fn_next->fn_name)); - else - AUTOFS_DPRINT((10, - "\tno next trigger\n")); - } else - VN_RELE(newvp); - - if (!error) - success++; + AUTOFS_DPRINT((10, "\tfirst trigger is %s\n", + dfnp->fn_trigger->fn_name)); + if (newfnp->fn_next != NULL) + AUTOFS_DPRINT((10, + "\tnext trigger is %s\n", + newfnp->fn_next->fn_name)); + else + AUTOFS_DPRINT((10, + "\tno next trigger\n")); + } else + VN_RELE(newvp); - if (update_times) { - gethrestime(&now); - dfnp->fn_atime = dfnp->fn_mtime = now; - } + if (!error) + success++; - VN_RELE(mvp); + if (update_times) { + gethrestime(&now); + dfnp->fn_atime = dfnp->fn_mtime = now; } + + VN_RELE(mvp); } if (save_triggers) { @@ -1333,7 +1301,6 @@ done: * free the action list now, */ xdr_free(xdr_action_list, (char *)alp); - kmem_free(alp, sizeof (*alp)); } } AUTOFS_DPRINT((5, "auto_perform_actions: error=%d\n", error)); @@ -2471,7 +2438,6 @@ top: */ if (alp != NULL) { xdr_free(xdr_action_list, (char *)alp); - kmem_free(alp, sizeof (*alp)); alp = NULL; } } diff --git a/usr/src/uts/common/fs/autofs/auto_xdr.c b/usr/src/uts/common/fs/autofs/auto_xdr.c index 6717b3b99a..dd657e4310 100644 --- a/usr/src/uts/common/fs/autofs/auto_xdr.c +++ b/usr/src/uts/common/fs/autofs/auto_xdr.c @@ -45,7 +45,6 @@ #include <sys/cmn_err.h> #include <sys/debug.h> #include <sys/systm.h> -#include <sys/utsname.h> #include <rpc/types.h> #include <rpc/xdr.h> #include <rpc/auth.h> @@ -55,33 +54,11 @@ #include <sys/sysmacros.h> #include <fs/fs_subr.h> #include <sys/fs/autofs.h> -#include <sys/pathconf.h> -#include <rpc/auth.h> -#include <rpc/rpcsec_gss.h> -#include <nfs/mount.h> -#include <sys/thread.h> -#include <nfs/rnode.h> - -#define FS_NFS2 2 -#define FS_NFS3 3 -#define FS_NFS4 4 -#define FS_AUTOFS 1 - -#define NFS4_FHSIZE 128 bool_t xdr_autofs_netbuf(XDR *, struct netbuf *); bool_t xdr_mounta(XDR *, struct mounta *); bool_t -xdr_nfs2_args(XDR *xdrs, struct nfs_args *objp); - -bool_t -xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp); - -bool_t -xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp); - -bool_t xdr_umntrequest(XDR *xdrs, umntrequest *objp) { bool_t more_data; @@ -143,452 +120,6 @@ xdr_linka(XDR *xdrs, linka *objp) return (TRUE); } - - -bool_t -xdr_knetconfig(XDR *xdrs, struct knetconfig *objp) -{ - - rpc_inline_t *buf; - char *knstring; - uint_t d; - - int i; - - if (xdrs->x_op == XDR_DECODE) { - if (!xdr_u_int(xdrs, &objp->knc_semantics)) - return (FALSE); - /* - * The knc_protofmly and knc_proto strings will - * be freed as a size of KNC_STRSIZE, make sure the - * buffer allocated is also this size, and not just - * the string size. - */ - if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE)) - return (FALSE); - knstring = kmem_zalloc(KNC_STRSIZE, KM_SLEEP); - bcopy(objp->knc_protofmly, knstring, - strlen(objp->knc_protofmly)); - kmem_free(objp->knc_protofmly, strlen(objp->knc_protofmly) + 1); - objp->knc_protofmly = knstring; - - if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE)) - return (FALSE); - knstring = kmem_zalloc(KNC_STRSIZE, KM_SLEEP); - bcopy(objp->knc_proto, knstring, strlen(objp->knc_proto)); - kmem_free(objp->knc_proto, strlen(objp->knc_proto) + 1); - objp->knc_proto = knstring; - - if (!xdr_u_int(xdrs, &d)) - return (FALSE); - objp->knc_rdev = expldev(d); - - buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_opaque(xdrs, (char *)&objp->knc_unused, - sizeof (objp->knc_unused))) - return (FALSE); - } else { - uint_t *genp; - - for (i = 0, genp = objp->knc_unused; i < 8; - i++) { - *genp++ = IXDR_GET_U_INT32(buf); - } - } - return (TRUE); - } - - if (!xdr_u_int(xdrs, &objp->knc_semantics)) - return (FALSE); - if (xdrs->x_op == XDR_FREE) { - kmem_free(objp->knc_protofmly, KNC_STRSIZE); - kmem_free(objp->knc_proto, KNC_STRSIZE); - } else { - if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE)) - return (FALSE); - if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE)) - return (FALSE); - } - if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev)) - return (FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->knc_unused, - sizeof (objp->knc_unused))) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_pathcnf(XDR *xdrs, struct pathcnf *objp) -{ - - rpc_inline_t *buf; - - int i; - - - if (xdrs->x_op == XDR_DECODE) { - buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_int(xdrs, &objp->pc_link_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_canon)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_input)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_name_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_path_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_pipe_buf)) - return (FALSE); - } else { - objp->pc_link_max = IXDR_GET_INT32(buf); - objp->pc_max_canon = IXDR_GET_SHORT(buf); - objp->pc_max_input = IXDR_GET_SHORT(buf); - objp->pc_name_max = IXDR_GET_SHORT(buf); - objp->pc_path_max = IXDR_GET_SHORT(buf); - objp->pc_pipe_buf = IXDR_GET_SHORT(buf); - } - if (!xdr_char(xdrs, (char *)&objp->pc_vdisable)) - return (FALSE); - if (!xdr_char(xdrs, &objp->pc_xxx)) - return (FALSE); - buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_opaque(xdrs, (char *)objp->pc_mask, - sizeof (objp->pc_mask))) - return (FALSE); - } else { - { - short *genp; - - for (i = 0, genp = objp->pc_mask; i < _PC_N; - i++) { - *genp++ = IXDR_GET_SHORT(buf); - } - } - - } - return (TRUE); - } - - if (!xdr_int(xdrs, &objp->pc_link_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_canon)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_max_input)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_name_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_path_max)) - return (FALSE); - if (!xdr_short(xdrs, &objp->pc_pipe_buf)) - return (FALSE); - if (!xdr_char(xdrs, (char *)&objp->pc_vdisable)) - return (FALSE); - if (!xdr_char(xdrs, &objp->pc_xxx)) - return (FALSE); - if (!xdr_opaque(xdrs, (char *)objp->pc_mask, - sizeof (objp->pc_mask))) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_des_clnt_data(XDR *xdrs, dh_k4_clntdata_t *objp) -{ - if (!xdr_autofs_netbuf(xdrs, &objp->syncaddr)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_string(xdrs, &objp->netname, SYS_NMLN)) - return (FALSE); - if (!xdr_int(xdrs, &objp->netnamelen)) - return (FALSE); - objp->netnamelen = strlen(objp->netname) + 1; - return (TRUE); -} - -bool_t -xdr_gss_clnt_data(XDR *xdrs, struct gss_clnt_data *objp) -{ - if (!xdr_u_int(xdrs, &objp->mechanism.length)) - return (FALSE); - if (!xdr_enum(xdrs, (enum_t *)&objp->service)) - return (FALSE); - if (!xdr_opaque(xdrs, objp->mechanism.elements, - objp->mechanism.length)) - return (FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->uname, MAX_NAME_LEN)) - return (FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->inst, MAX_NAME_LEN)) - return (FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->realm, MAX_NAME_LEN)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->qop)) - return (FALSE); - return (TRUE); -} - -bool_t -xdr_sec_data(XDR *xdrs, struct sec_data *objp) -{ - if (!xdr_u_int(xdrs, &objp->secmod)) - return (FALSE); - if (!xdr_u_int(xdrs, &objp->rpcflavor)) - return (FALSE); - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_uid_t(xdrs, &objp->uid)) - return (FALSE); - - switch (objp->rpcflavor) { - case AUTH_NONE: - case AUTH_UNIX: - case AUTH_LOOPBACK: - break; - case AUTH_DES: - if (!xdr_pointer(xdrs, (char **)&objp->data, - sizeof (dh_k4_clntdata_t), - (xdrproc_t)xdr_des_clnt_data)) - return (FALSE); - break; - case RPCSEC_GSS: - if (!xdr_pointer(xdrs, (char **)&objp->data, - sizeof (gss_clntdata_t), - (xdrproc_t)xdr_gss_clnt_data)) - return (FALSE); - break; - default: - return (FALSE); - } - - return (TRUE); -} - -bool_t -xdr_nfs2_fh(XDR *xdrs, nfs_fhandle *objp) -{ - objp->fh_len = NFS_FHSIZE; - if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, NFS_FHSIZE)) - return (B_FALSE); - return (B_TRUE); -} - -bool_t -xdr_nfs3_fhandle(XDR *xdrs, nfs_fhandle *objp) -{ - if (!xdr_int(xdrs, &objp->fh_len)) - return (B_FALSE); - if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, objp->fh_len)) - return (B_FALSE); - return (B_TRUE); -} - -bool_t -xdr_nfs(XDR *xdrs, struct nfs_args *objp, int nfsv) -{ - - rpc_inline_t *buf; - - if (objp == NULL) - return (TRUE); - - if (xdrs->x_op == XDR_DECODE) { - if (!xdr_pointer(xdrs, (char **)&objp->addr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->syncaddr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN)) - return (FALSE); - if (!xdr_string(xdrs, &objp->netname, SYS_NMLN)) - return (FALSE); - if (nfsv == FS_NFS4) { - if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE)) - return (B_FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs3_fhandle)) - return (B_FALSE); - } else { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs2_fh)) - return (B_FALSE); - } - buf = XDR_INLINE(xdrs, 9 * BYTES_PER_XDR_UNIT); - if (buf == NULL) { - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_int(xdrs, &objp->wsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->rsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->timeo)) - return (FALSE); - if (!xdr_int(xdrs, &objp->retrans)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmax)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmax)) - return (FALSE); - } else { - objp->flags = IXDR_GET_INT32(buf); - objp->wsize = IXDR_GET_INT32(buf); - objp->rsize = IXDR_GET_INT32(buf); - objp->timeo = IXDR_GET_INT32(buf); - objp->retrans = IXDR_GET_INT32(buf); - objp->acregmin = IXDR_GET_INT32(buf); - objp->acregmax = IXDR_GET_INT32(buf); - objp->acdirmin = IXDR_GET_INT32(buf); - objp->acdirmax = IXDR_GET_INT32(buf); - } - if (!xdr_pointer(xdrs, (char **)&objp->pathconf, - sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf)) - return (FALSE); - if (!xdr_int(xdrs, &objp->nfs_args_ext)) - return (FALSE); - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extA.secdata, - sizeof (struct sec_data), (xdrproc_t)xdr_sec_data)) - return (FALSE); - if (objp->nfs_args_ext == NFS_ARGS_EXTB) { - if (nfsv == FS_NFS4) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - } else { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs2_args)) - return (FALSE); - } - } - return (TRUE); - } - - ASSERT(xdrs->x_op != XDR_DECODE); - if (!xdr_pointer(xdrs, (char **)&objp->addr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->syncaddr, - sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->knconf, - sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig)) - return (FALSE); - if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN)) - return (FALSE); - if (!xdr_string(xdrs, &objp->netname, SYS_NMLN)) - return (FALSE); - if (nfsv == FS_NFS4) { - if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE)) - return (B_FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs3_fhandle)) - return (B_FALSE); - } else { - if (!xdr_pointer(xdrs, (char **)&objp->fh, - sizeof (nfs_fhandle), - (xdrproc_t)xdr_nfs2_fh)) - return (B_FALSE); - } - - if (!xdr_int(xdrs, &objp->flags)) - return (FALSE); - if (!xdr_int(xdrs, &objp->wsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->rsize)) - return (FALSE); - if (!xdr_int(xdrs, &objp->timeo)) - return (FALSE); - if (!xdr_int(xdrs, &objp->retrans)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acregmax)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmin)) - return (FALSE); - if (!xdr_int(xdrs, &objp->acdirmax)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->pathconf, - sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf)) - return (FALSE); - if (!xdr_int(xdrs, &objp->nfs_args_ext)) - return (FALSE); - if (!xdr_pointer(xdrs, (char **)&objp->nfs_ext_u.nfs_extA.secdata, - sizeof (struct sec_data), (xdrproc_t)xdr_sec_data)) - return (FALSE); - if (objp->nfs_args_ext == NFS_ARGS_EXTB) { - if (nfsv == FS_NFS4) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - } else if (nfsv == FS_NFS3) { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - } else { - if (!xdr_pointer(xdrs, - (char **)&objp->nfs_ext_u.nfs_extB.next, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs2_args)) - return (FALSE); - } - } - return (TRUE); -} - -bool_t -xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS4)); -} - -bool_t -xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS3)); -} - -bool_t -xdr_nfs2_args(XDR *xdrs, struct nfs_args *objp) -{ - return (xdr_nfs(xdrs, objp, FS_NFS2)); -} - - - bool_t xdr_autofs_args(XDR *xdrs, autofs_args *objp) { @@ -638,53 +169,47 @@ xdr_action_list(XDR *xdrs, action_list *objp) { bool_t more_data = TRUE; bool_t status = TRUE; - action_list *p, *last; + action_list *p; ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE)); more_data = (objp != NULL); p = objp; - if (xdrs->x_op == XDR_FREE) { - while (p != NULL) { - if (!xdr_action_list_entry(xdrs, &p->action)) - cmn_err(CE_WARN, "xdr_action_list: " - "action_list_entry free failed %p\n", - (void *)&p->action); - last = p; - p = p->next; - /* - * Don't need this kmem_free the first action_list - * as xdr_reference using xdr_action_list will free - * it when called with the XDR_FREE op. - */ - if (last != objp) - kmem_free(last, sizeof (*last)); - } - return (status); - } + if (xdrs->x_op == XDR_FREE) + goto free; while (more_data) { - if (!xdr_action_list_entry(xdrs, &p->action)) { - status = FALSE; - break; - } + if (!xdr_action_list_entry(xdrs, &p->action)) + goto free; - if (!xdr_bool(xdrs, &more_data)) { - status = FALSE; - break; - } + if (!xdr_bool(xdrs, &more_data)) + goto free; if (more_data) { p->next = kmem_zalloc(sizeof (action_list), KM_SLEEP); p = p->next; if (p == NULL) { status = FALSE; - break; + goto free; } } else p->next = NULL; } + return (TRUE); + +free: + for (p = objp; p != NULL; ) { + if (!xdr_action_list_entry(xdrs, &objp->action)) + cmn_err(CE_WARN, "xdr_action_list: " + "action_list_entry free failed %p\n", + (void *)&objp->action); + p = p->next; + kmem_free(objp, sizeof (*objp)); + objp = p; + } + objp = NULL; + return (status); } @@ -703,50 +228,17 @@ xdr_autofs_netbuf(XDR *xdrs, struct netbuf *objp) bool_t xdr_mounta(XDR *xdrs, struct mounta *objp) { - int fstype = 0; if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN)) return (FALSE); if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN)) return (FALSE); if (!xdr_int(xdrs, &objp->flags)) return (FALSE); - /* - * For a free we must first determine the fstype before calling - * xdr_string on it, as the xdr_string will free it. For a - * decode we must first call xdr_string to get the value to - * determine the fstype. - */ - if (xdrs->x_op == XDR_FREE) { - if (strncmp(objp->fstype, "autofs", sizeof ("autofs")) == 0) { - fstype = FS_AUTOFS; - } else if (strncmp(objp->fstype, "nfs4", - sizeof ("nfs4")) == 0) { - fstype = FS_NFS4; - } else if (strncmp(objp->fstype, "nfs3", - sizeof ("nfs3")) == 0) { - fstype = FS_NFS3; - } else { - fstype = FS_NFS2; - } - } - if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN)) return (FALSE); - - if (xdrs->x_op == XDR_DECODE) { - if (strncmp(objp->fstype, "autofs", sizeof ("autofs")) == 0) { - fstype = FS_AUTOFS; - } else if (strncmp(objp->fstype, "nfs4", - sizeof ("nfs4")) == 0) { - fstype = FS_NFS4; - } else if (strncmp(objp->fstype, "nfs3", - sizeof ("nfs3")) == 0) { - fstype = FS_NFS3; - } else { - fstype = FS_NFS2; - } - } - + if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args), + (xdrproc_t)xdr_autofs_args)) + return (FALSE); /* * The length is the original user-land length, not the * length of the native kernel autofs_args structure provided @@ -754,61 +246,15 @@ xdr_mounta(XDR *xdrs, struct mounta *objp) * the length is wrong and we need to stuff the length field with * the length of the native structure. */ - if (fstype == FS_AUTOFS) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (autofs_args), - (xdrproc_t)xdr_autofs_args)) - return (FALSE); - if (!xdr_int(xdrs, &objp->datalen)) - return (FALSE); - if (xdrs->x_op == XDR_DECODE) - objp->datalen = sizeof (struct autofs_args); - } else if (fstype == FS_NFS4) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs4_args)) - return (FALSE); - if (!xdr_int(xdrs, &objp->datalen)) - return (FALSE); - if (xdrs->x_op == XDR_DECODE) - objp->datalen = sizeof (struct nfs_args); - } else if (fstype == FS_NFS3) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs3_args)) - return (FALSE); - if (!xdr_int(xdrs, &objp->datalen)) - return (FALSE); - if (xdrs->x_op == XDR_DECODE) - objp->datalen = sizeof (struct nfs_args); - } else if (fstype == FS_NFS2) { - if (!xdr_pointer(xdrs, (char **)&objp->dataptr, - sizeof (struct nfs_args), - (xdrproc_t)xdr_nfs2_args)) - return (FALSE); - if (!xdr_int(xdrs, &objp->datalen)) - return (FALSE); - if (xdrs->x_op == XDR_DECODE) - objp->datalen = sizeof (struct nfs_args); - } - - /* - * domount's call to vfs_buildoptionstr() can alter the contents - * of the options string, resulting in a shorter string - * length. Thus, xdr_string can not be used to free this - * string as it may be freed using a different size than allocated. - */ - if (xdrs->x_op == XDR_DECODE) { - if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN)) - return (FALSE); - } else { - ASSERT(xdrs->x_op == XDR_FREE); - kmem_free(objp->optptr, objp->optlen); - } - if (!xdr_int(xdrs, &objp->optlen)) + if (!xdr_int(xdrs, &objp->datalen)) return (FALSE); if (xdrs->x_op == XDR_DECODE) - ASSERT((strlen(objp->optptr) + 1) == objp->optlen); + objp->datalen = sizeof (struct autofs_args); + if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN)) + return (FALSE); + if (!xdr_int(xdrs, &objp->optlen)) + return (FALSE); + ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE)); return (TRUE); } |