Re: [PATCH 11/14] nfsd: add user xattr RPC XDR encoding/decoding logic

Frank van der Linden
2020-03-20T16:47:42Z

Hi Chuck,

On Thu, Mar 12, 2020 at 03:16:37PM -0400, Chuck Lever wrote:
> > +static __be32
> > +nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
> > + struct nfsd4_setxattr *setxattr)
> > +{
> > + DECODE_HEAD;
> > + u32 flags, maxcount, size;
> > + struct kvec head;
> > + struct page **pagelist;
> > +
> > + READ_BUF(4);
> > + flags = be32_to_cpup(p++);
> > +
> > + if (flags > SETXATTR4_REPLACE)
> > + return nfserr_inval;
> > + setxattr->setxa_flags = flags;
> > +
> > + status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name);
> > + if (status)
> > + return status;
> > +
> > + maxcount = svc_max_payload(argp->rqstp);
> > + maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
> > +
> > + READ_BUF(4);
> > + size = be32_to_cpup(p++);
> > + if (size > maxcount)
> > + return nfserr_xattr2big;
> > +
> > + setxattr->setxa_len = size;
> > + if (size > 0) {
> > + status = svcxdr_construct_vector(argp, &head, &pagelist, size);
> > + if (status)
> > + return status;
> > +
> > + status = nfsd4_vbuf_from_stream(argp, &head, pagelist,
> > + &setxattr->setxa_buf, size);
> > + }
>
> Now I'm wondering if read_bytes_from_xdr_buf() might be adequate
> for this purpose, so you can avoid open-coding all of this logic.

This took a little longer, I had to check my notes, but basically the
reasons for doing it this way are:

* The nfsd decode path uses nfsd4_compoundargs, which doesn't have an
xdr_stream (it has a page array). So read_bytes_from_xdr_buf isn't
a natural fit.
* READ_BUF/read_buf don't deal with > PAGE_SIZE chunks, but xattrs may
be larger than that.

The other code that deals with > PAGE_SIZE chunks is the write code. So,
I factored out some code from the write code, used that, and added a function
to process the resulting kvec / pagelist (nfs4_vbuf_from_stream).

There definitely seem to be several copy functions in both the client
and server code that basically do the same, but in slightly different ways,
depending on whether they use an XDR buf or not, whether the pages are
mapped or not, etc. Seems like a good candidate for a cleanup, but I
considered it to be out of scope for these patches.

- Frank