diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 7d3ebc683d1..3daee65ab83 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -3000,12 +3000,18 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); claim = fxdr_unsigned(int, *tl); - if (claim == NFSV4OPEN_CLAIMDELEGATECUR || claim == - NFSV4OPEN_CLAIMDELEGATECURFH) { + if (claim == NFSV4OPEN_CLAIMDELEGATECUR) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER); stp->ls_flags |= NFSLCK_DELEGCUR; + } else if (claim == NFSV4OPEN_CLAIMDELEGATECURFH) { + /* Fill in most of the stateid from the clientid. */ + stateid.seqid = 0; + stateid.other[0] = clientid.lval[0]; + stateid.other[1] = clientid.lval[1]; + stateid.other[2] = 0; + stp->ls_flags |= NFSLCK_DELEGCUR; } else if (claim == NFSV4OPEN_CLAIMDELEGATEPREV || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { stp->ls_flags |= NFSLCK_DELEGPREV; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index c7384027702..da57ebde7a5 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -2568,6 +2568,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. + * For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides + * the clientid, which is the first two "other" elements + * for the stateid. This should be sufficient, since there + * is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2578,8 +2582,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) || @@ -2830,6 +2834,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. + * For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides + * the clientid, which is the first two "other" elements + * for the stateid. This should be sufficient, since there + * is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2840,8 +2848,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) ||