mirror of
https://github.com/opnsense/src.git
synced 2026-04-22 23:02:02 -04:00
The new NFSv4 client was erroneously using "p" instead of
"p_leader" for the "id" for POSIX byte range locking. I think this would only have affected processes created by rfork(2) with the RFTHREAD flag specified. This patch fixes that by passing the "id" down through the various functions from nfs_advlock(). MFC after: 2 weeks
This commit is contained in:
parent
2301f58fe5
commit
f8f4e256e7
5 changed files with 66 additions and 67 deletions
|
|
@ -401,10 +401,10 @@ int nfsrpc_readdirplus(vnode_t, struct uio *, nfsuint64 *,
|
|||
int nfsrpc_commit(vnode_t, u_quad_t, int, struct ucred *,
|
||||
NFSPROC_T *, u_char *, struct nfsvattr *, int *, void *);
|
||||
int nfsrpc_advlock(vnode_t, off_t, int, struct flock *, int,
|
||||
struct ucred *, NFSPROC_T *);
|
||||
struct ucred *, NFSPROC_T *, void *, int);
|
||||
int nfsrpc_lockt(struct nfsrv_descript *, vnode_t,
|
||||
struct nfsclclient *, u_int64_t, u_int64_t, struct flock *,
|
||||
struct ucred *, NFSPROC_T *);
|
||||
struct ucred *, NFSPROC_T *, void *, int);
|
||||
int nfsrpc_lock(struct nfsrv_descript *, struct nfsmount *, vnode_t,
|
||||
u_int8_t *, int, struct nfscllockowner *, int, int, u_int64_t,
|
||||
u_int64_t, short, struct ucred *, NFSPROC_T *, int);
|
||||
|
|
@ -439,16 +439,16 @@ struct nfsclclient *nfscl_findcl(struct nfsmount *);
|
|||
void nfscl_clientrelease(struct nfsclclient *);
|
||||
void nfscl_freelock(struct nfscllock *, int);
|
||||
int nfscl_getbytelock(vnode_t, u_int64_t, u_int64_t, short,
|
||||
struct ucred *, NFSPROC_T *, struct nfsclclient *, int, u_int8_t *,
|
||||
u_int8_t *, struct nfscllockowner **, int *, int *);
|
||||
struct ucred *, NFSPROC_T *, struct nfsclclient *, int, void *, int,
|
||||
u_int8_t *, u_int8_t *, struct nfscllockowner **, int *, int *);
|
||||
int nfscl_relbytelock(vnode_t, u_int64_t, u_int64_t,
|
||||
struct ucred *, NFSPROC_T *, int, struct nfsclclient *,
|
||||
struct nfscllockowner **, int *);
|
||||
void *, int, struct nfscllockowner **, int *);
|
||||
int nfscl_checkwritelocked(vnode_t, struct flock *,
|
||||
struct ucred *, NFSPROC_T *);
|
||||
struct ucred *, NFSPROC_T *, void *, int);
|
||||
void nfscl_lockrelease(struct nfscllockowner *, int, int);
|
||||
void nfscl_fillclid(u_int64_t, char *, u_int8_t *, u_int16_t);
|
||||
void nfscl_filllockowner(NFSPROC_T *, u_int8_t *);
|
||||
void nfscl_filllockowner(void *, u_int8_t *, int);
|
||||
void nfscl_freeopen(struct nfsclopen *, int);
|
||||
void nfscl_umount(struct nfsmount *, NFSPROC_T *);
|
||||
void nfscl_renewthread(struct nfsclclient *, NFSPROC_T *);
|
||||
|
|
@ -466,9 +466,10 @@ void nfscl_lockexcl(struct nfsv4lock *, void *);
|
|||
void nfscl_lockunlock(struct nfsv4lock *);
|
||||
void nfscl_lockderef(struct nfsv4lock *);
|
||||
void nfscl_docb(struct nfsrv_descript *, NFSPROC_T *);
|
||||
void nfscl_releasealllocks(struct nfsclclient *, vnode_t, NFSPROC_T *);
|
||||
void nfscl_releasealllocks(struct nfsclclient *, vnode_t, NFSPROC_T *, void *,
|
||||
int);
|
||||
int nfscl_lockt(vnode_t, struct nfsclclient *, u_int64_t,
|
||||
u_int64_t, struct flock *, NFSPROC_T *);
|
||||
u_int64_t, struct flock *, NFSPROC_T *, void *, int);
|
||||
int nfscl_mustflush(vnode_t);
|
||||
int nfscl_nodeleg(vnode_t, int);
|
||||
int nfscl_removedeleg(vnode_t, NFSPROC_T *, nfsv4stateid_t *);
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ nfscl_fillclid(u_int64_t clval, char *uuid, u_int8_t *cp, u_int16_t idlen)
|
|||
* Fill in a lock owner name. For now, pid + the process's creation time.
|
||||
*/
|
||||
void
|
||||
nfscl_filllockowner(struct thread *td, u_int8_t *cp)
|
||||
nfscl_filllockowner(void *id, u_int8_t *cp, int flags)
|
||||
{
|
||||
union {
|
||||
u_int32_t lval;
|
||||
|
|
@ -508,37 +508,32 @@ nfscl_filllockowner(struct thread *td, u_int8_t *cp)
|
|||
} tl;
|
||||
struct proc *p;
|
||||
|
||||
if (td == NULL) {
|
||||
printf("NULL td\n");
|
||||
bzero(cp, 12);
|
||||
return;
|
||||
}
|
||||
p = td->td_proc;
|
||||
if (p == NULL) {
|
||||
printf("NULL pid\n");
|
||||
bzero(cp, 12);
|
||||
return;
|
||||
}
|
||||
tl.lval = p->p_pid;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp++ = tl.cval[3];
|
||||
if (p->p_stats == NULL) {
|
||||
printf("pstats null\n");
|
||||
bzero(cp, 8);
|
||||
return;
|
||||
}
|
||||
tl.lval = p->p_stats->p_start.tv_sec;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp++ = tl.cval[3];
|
||||
tl.lval = p->p_stats->p_start.tv_usec;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp = tl.cval[3];
|
||||
if (id == NULL) {
|
||||
printf("NULL id\n");
|
||||
bzero(cp, NFSV4CL_LOCKNAMELEN);
|
||||
return;
|
||||
}
|
||||
if ((flags & F_POSIX) != 0) {
|
||||
p = (struct proc *)id;
|
||||
tl.lval = p->p_pid;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp++ = tl.cval[3];
|
||||
tl.lval = p->p_stats->p_start.tv_sec;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp++ = tl.cval[3];
|
||||
tl.lval = p->p_stats->p_start.tv_usec;
|
||||
*cp++ = tl.cval[0];
|
||||
*cp++ = tl.cval[1];
|
||||
*cp++ = tl.cval[2];
|
||||
*cp = tl.cval[3];
|
||||
} else {
|
||||
printf("nfscl_filllockowner: not F_POSIX\n");
|
||||
bzero(cp, NFSV4CL_LOCKNAMELEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3459,7 +3459,7 @@ nfsmout:
|
|||
*/
|
||||
APPLESTATIC int
|
||||
nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
||||
int reclaim, struct ucred *cred, NFSPROC_T *p)
|
||||
int reclaim, struct ucred *cred, NFSPROC_T *p, void *id, int flags)
|
||||
{
|
||||
struct nfscllockowner *lp;
|
||||
struct nfsclclient *clp;
|
||||
|
|
@ -3511,11 +3511,11 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
|||
error = nfscl_getcl(vp, cred, p, &clp);
|
||||
if (error)
|
||||
return (error);
|
||||
error = nfscl_lockt(vp, clp, off, len, fl, p);
|
||||
error = nfscl_lockt(vp, clp, off, len, fl, p, id, flags);
|
||||
if (!error) {
|
||||
clidrev = clp->nfsc_clientidrev;
|
||||
error = nfsrpc_lockt(nd, vp, clp, off, len, fl, cred,
|
||||
p);
|
||||
p, id, flags);
|
||||
} else if (error == -1) {
|
||||
error = 0;
|
||||
}
|
||||
|
|
@ -3530,7 +3530,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
|||
return (error);
|
||||
do {
|
||||
error = nfscl_relbytelock(vp, off, len, cred, p, callcnt,
|
||||
clp, &lp, &dorpc);
|
||||
clp, id, flags, &lp, &dorpc);
|
||||
/*
|
||||
* If it returns a NULL lp, we're done.
|
||||
*/
|
||||
|
|
@ -3538,7 +3538,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
|||
if (callcnt == 0)
|
||||
nfscl_clientrelease(clp);
|
||||
else
|
||||
nfscl_releasealllocks(clp, vp, p);
|
||||
nfscl_releasealllocks(clp, vp, p, id, flags);
|
||||
return (error);
|
||||
}
|
||||
if (nmp->nm_clp != NULL)
|
||||
|
|
@ -3572,10 +3572,10 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
|||
}
|
||||
callcnt++;
|
||||
} while (error == 0 && nd->nd_repstat == 0);
|
||||
nfscl_releasealllocks(clp, vp, p);
|
||||
nfscl_releasealllocks(clp, vp, p, id, flags);
|
||||
} else if (op == F_SETLK) {
|
||||
error = nfscl_getbytelock(vp, off, len, fl->l_type, cred, p,
|
||||
NULL, 0, NULL, NULL, &lp, &newone, &donelocally);
|
||||
NULL, 0, id, flags, NULL, NULL, &lp, &newone, &donelocally);
|
||||
if (error || donelocally) {
|
||||
return (error);
|
||||
}
|
||||
|
|
@ -3625,7 +3625,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
|||
APPLESTATIC int
|
||||
nfsrpc_lockt(struct nfsrv_descript *nd, vnode_t vp,
|
||||
struct nfsclclient *clp, u_int64_t off, u_int64_t len, struct flock *fl,
|
||||
struct ucred *cred, NFSPROC_T *p)
|
||||
struct ucred *cred, NFSPROC_T *p, void *id, int flags)
|
||||
{
|
||||
u_int32_t *tl;
|
||||
int error, type, size;
|
||||
|
|
@ -3643,7 +3643,7 @@ nfsrpc_lockt(struct nfsrv_descript *nd, vnode_t vp,
|
|||
tl += 2;
|
||||
*tl++ = clp->nfsc_clientid.lval[0];
|
||||
*tl = clp->nfsc_clientid.lval[1];
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
(void) nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN);
|
||||
error = nfscl_request(nd, vp, p, cred, NULL);
|
||||
if (error)
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg,
|
|||
* If none found, add the new one or return error, depending upon
|
||||
* "create".
|
||||
*/
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(p->td_proc, own, F_POSIX);
|
||||
NFSLOCKCLSTATE();
|
||||
dp = NULL;
|
||||
/* First check the delegation list */
|
||||
|
|
@ -521,7 +521,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode,
|
|||
* If p != NULL, we want to search the parentage tree
|
||||
* for a matching OpenOwner and use that.
|
||||
*/
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(p->td_proc, own, F_POSIX);
|
||||
error = nfscl_getopen(&clp->nfsc_owner, nfhp, fhlen, NULL, p,
|
||||
mode, NULL, &op);
|
||||
if (error == 0) {
|
||||
|
|
@ -596,7 +596,7 @@ nfscl_getopen(struct nfsclownerhead *ohp, u_int8_t *nfhp, int fhlen,
|
|||
op = NULL;
|
||||
while (op == NULL && (nproc != NULL || rown != NULL)) {
|
||||
if (nproc != NULL) {
|
||||
nfscl_filllockowner(nproc, own);
|
||||
nfscl_filllockowner(nproc->td_proc, own, F_POSIX);
|
||||
ownp = own;
|
||||
} else {
|
||||
ownp = rown;
|
||||
|
|
@ -881,7 +881,7 @@ nfscl_clientrelease(struct nfsclclient *clp)
|
|||
APPLESTATIC int
|
||||
nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
||||
short type, struct ucred *cred, NFSPROC_T *p, struct nfsclclient *rclp,
|
||||
int recovery, u_int8_t *rownp, u_int8_t *ropenownp,
|
||||
int recovery, void *id, int flags, u_int8_t *rownp, u_int8_t *ropenownp,
|
||||
struct nfscllockowner **lpp, int *newonep, int *donelocallyp)
|
||||
{
|
||||
struct nfscllockowner *lp;
|
||||
|
|
@ -942,7 +942,7 @@ nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
|||
if (recovery) {
|
||||
ownp = rownp;
|
||||
} else {
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
ownp = own;
|
||||
}
|
||||
if (!recovery) {
|
||||
|
|
@ -1079,7 +1079,8 @@ nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
|||
APPLESTATIC int
|
||||
nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
||||
__unused struct ucred *cred, NFSPROC_T *p, int callcnt,
|
||||
struct nfsclclient *clp, struct nfscllockowner **lpp, int *dorpcp)
|
||||
struct nfsclclient *clp, void *id, int flags,
|
||||
struct nfscllockowner **lpp, int *dorpcp)
|
||||
{
|
||||
struct nfscllockowner *lp;
|
||||
struct nfsclowner *owp;
|
||||
|
|
@ -1116,7 +1117,7 @@ nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
|||
sizeof (struct nfscllock), M_NFSCLLOCK, M_WAITOK);
|
||||
*other_lop = *nlop;
|
||||
}
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
dp = NULL;
|
||||
NFSLOCKCLSTATE();
|
||||
if (callcnt == 0)
|
||||
|
|
@ -1188,7 +1189,8 @@ nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
|
|||
* Release all lockowners marked in progess for this process and file.
|
||||
*/
|
||||
APPLESTATIC void
|
||||
nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p)
|
||||
nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p,
|
||||
void *id, int flags)
|
||||
{
|
||||
struct nfsclowner *owp;
|
||||
struct nfsclopen *op;
|
||||
|
|
@ -1197,7 +1199,7 @@ nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p)
|
|||
u_int8_t own[NFSV4CL_LOCKNAMELEN];
|
||||
|
||||
np = VTONFS(vp);
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
NFSLOCKCLSTATE();
|
||||
LIST_FOREACH(owp, &clp->nfsc_owner, nfsow_list) {
|
||||
LIST_FOREACH(op, &owp->nfsow_open, nfso_list) {
|
||||
|
|
@ -1226,7 +1228,7 @@ nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p)
|
|||
*/
|
||||
APPLESTATIC int
|
||||
nfscl_checkwritelocked(vnode_t vp, struct flock *fl,
|
||||
struct ucred *cred, NFSPROC_T *p)
|
||||
struct ucred *cred, NFSPROC_T *p, void *id, int flags)
|
||||
{
|
||||
struct nfsclowner *owp;
|
||||
struct nfscllockowner *lp;
|
||||
|
|
@ -1266,7 +1268,7 @@ nfscl_checkwritelocked(vnode_t vp, struct flock *fl,
|
|||
error = nfscl_getcl(vp, cred, p, &clp);
|
||||
if (error)
|
||||
return (1);
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
NFSLOCKCLSTATE();
|
||||
|
||||
/*
|
||||
|
|
@ -1641,7 +1643,7 @@ nfscl_cleanup(NFSPROC_T *p)
|
|||
|
||||
if (!nfscl_inited)
|
||||
return;
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(p->td_proc, own, F_POSIX);
|
||||
|
||||
NFSLOCKCLSTATE();
|
||||
/*
|
||||
|
|
@ -3322,7 +3324,7 @@ nfscl_checkconflict(struct nfscllockownerhead *lhp, struct nfscllock *nlop,
|
|||
*/
|
||||
APPLESTATIC int
|
||||
nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
|
||||
u_int64_t len, struct flock *fl, NFSPROC_T *p)
|
||||
u_int64_t len, struct flock *fl, NFSPROC_T *p, void *id, int flags)
|
||||
{
|
||||
struct nfscllock *lop, nlck;
|
||||
struct nfscldeleg *dp;
|
||||
|
|
@ -3340,7 +3342,7 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
|
|||
return (NFSERR_INVAL);
|
||||
}
|
||||
np = VTONFS(vp);
|
||||
nfscl_filllockowner(p, own);
|
||||
nfscl_filllockowner(id, own, flags);
|
||||
NFSLOCKCLSTATE();
|
||||
dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
|
||||
error = nfscl_localconflict(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len,
|
||||
|
|
@ -3615,7 +3617,7 @@ nfscl_relock(vnode_t vp, struct nfsclclient *clp, struct nfsmount *nmp,
|
|||
off = lop->nfslo_first;
|
||||
len = lop->nfslo_end - lop->nfslo_first;
|
||||
error = nfscl_getbytelock(vp, off, len, lop->nfslo_type, cred, p,
|
||||
clp, 1, lp->nfsl_owner, lp->nfsl_openowner, &nlp, &newone,
|
||||
clp, 1, NULL, 0, lp->nfsl_owner, lp->nfsl_openowner, &nlp, &newone,
|
||||
&donelocally);
|
||||
if (error || donelocally)
|
||||
return (error);
|
||||
|
|
|
|||
|
|
@ -2898,7 +2898,8 @@ nfs_advlock(struct vop_advlock_args *ap)
|
|||
* RFC3530 Sec. 9.3.2.
|
||||
*/
|
||||
if (ap->a_op == F_UNLCK &&
|
||||
nfscl_checkwritelocked(vp, ap->a_fl, cred, td))
|
||||
nfscl_checkwritelocked(vp, ap->a_fl, cred, td, ap->a_id,
|
||||
ap->a_flags))
|
||||
(void) ncl_flush(vp, MNT_WAIT, cred, td, 1, 0);
|
||||
|
||||
/*
|
||||
|
|
@ -2907,7 +2908,7 @@ nfs_advlock(struct vop_advlock_args *ap)
|
|||
*/
|
||||
do {
|
||||
ret = nfsrpc_advlock(vp, np->n_size, ap->a_op,
|
||||
ap->a_fl, 0, cred, td);
|
||||
ap->a_fl, 0, cred, td, ap->a_id, ap->a_flags);
|
||||
if (ret == NFSERR_DENIED && (ap->a_flags & F_WAIT) &&
|
||||
ap->a_op == F_SETLK) {
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue