On Mon, Sep 16, 2019 at 05:13:52PM -0400, Olga Kornievskaia wrote: > @@ -1956,6 +1964,45 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, > - rqstp->rq_auth_slack; > } > > +#ifdef CONFIG_NFSD_V4_2_INTER_SSC > +static __be32 > +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) > +{ > + struct nfsd4_op *op, *current_op, *saved_op; current_op and saved_op need to be initialized to NULL here. > + struct nfsd4_copy *copy; > + struct nfsd4_putfh *putfh; > + int i; > + > + /* traverse all operation and if it's a COPY compound, mark the > + * source filehandle to skip verification > + */ > + for (i = 0; i < args->opcnt; i++) { > + op = &args->ops[i]; > + if (op->opnum == OP_PUTFH) > + current_op = op; > + else if (op->opnum == OP_SAVEFH) > + saved_op = current_op; > + else if (op->opnum == OP_RESTOREFH) > + current_op = saved_op; > + else if (op->opnum == OP_COPY) { > + copy = (struct nfsd4_copy *)&op->u; > + if (!saved_op) > + return nfserr_nofilehandle; Looks like this results in returning an empty compound result with just the bare result. I believe what we need to do is execute all the ops preceding the COPY normally, then return the nofilehandle error on the COPY. One approach might be if (!saved_op) { op->status = nfserr_nofilehandle; return; } and change check_if_stalefh_allowed to have no return value. --b. > + putfh = (struct nfsd4_putfh *)&saved_op->u; > + if (!copy->cp_intra) > + putfh->no_verify = true; > + } > + } > + return nfs_ok; > +} ... > @@ -2004,6 +2051,9 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, > resp->opcnt = 1; > goto encode_op; > } > + status = check_if_stalefh_allowed(args); > + if (status) > + goto out; > > trace_nfsd_compound(rqstp, args->opcnt); > while (!status && resp->opcnt < args->opcnt) {