Re: Any idea how best to handle potentially large POSIX ACLs for getfacl?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Sep 4, 2024 at 8:28 AM Chuck Lever III <chuck.lever@xxxxxxxxxx> wrote:
>
>
>
> > On Sep 2, 2024, at 8:16 PM, Rick Macklem <rick.macklem@xxxxxxxxx> wrote:
> >
> > On Thu, Aug 29, 2024 at 6:41 PM Trond Myklebust <trondmy@xxxxxxxxxxxxxxx> wrote:
> >>
> >> On Thu, 2024-08-29 at 18:32 -0700, Rick Macklem wrote:
> >>> On Thu, Aug 29, 2024 at 5:33 PM Trond Myklebust
> >>> <trondmy@xxxxxxxxxxxxxxx> wrote:
> >>>>
> >>>> On Thu, 2024-08-29 at 17:19 -0700, Rick Macklem wrote:
> >>>>> Hi,
> >>>>>
> >>>>> I have a rather crude patch that does the POSIX draft ACL
> >>>>> attributes
> >>>>> that my draft is suggesting for NFSv4.2 for the Linux client.
> >>>>> - It is working ok for small ACLs, but...
> >>>>>
> >>>>> The hassle is that the on-the-wire ACEs have a "who" field that
> >>>>> can
> >>>>> be up to 128bytes (IDMAP_NAMESZ).
> >>>>>
> >>>>> I think I have figured out the SETATTR side, which isn't too bad
> >>>>> because
> >>>>> it knows how many ACEs. (It does roughly what the NFSv3 NFSACL
> >>>>> code
> >>>>> did, which is allocate some pages for the large ones.)
> >>>>>
> >>>>> However, the getfacl side doesn't know how bug the ACL will be in
> >>>>> the reply. The NFSACL code allocates pages (7 of them) to handle
> >>>>> the
> >>>>> largest possible ACL. Unfortunately, for these NFSv4 attributes,
> >>>>> they
> >>>>> could be roughly 140Kbytes (140bytes assuming the largest "who"
> >>>>> times
> >>>>> 1024 ACEs).
> >>>>> --> Anyone have a better suggestion than just allocating 35pages
> >>>>> each
> >>>>> time
> >>>>>    (when 99.99% of them will fit in a fraction of a page)?
> >>>>>
> >>>>> Thanks for any suggestions, rick
> >>>>>
> >>>>
> >>>> See the NFSv3 posix acl client code.
> >>>>
> >>>> It allocates the 'pages[]' array of pointers to the page buffers to
> >>>> be
> >>>> of length NFSACL_MAXPAGES, but only allocates the first entry, and
> >>>> leaves the rest NULL.
> >>>> Then in the XDR encoder "nfs3_xdr_enc_getacl3args()" where it
> >>>> declares
> >>>> the length of that array, it sets the flag XDRBUF_SPARSE_PAGES on
> >>>> the
> >>>> reply buffer.
> >>>>
> >>>> That tells the RPC layer that if the incoming RPC reply needs to
> >>>> fill
> >>>> in more data than will fit into that single page, then it should
> >>>> allocate extra pages and add them to the 'pages' array.
> >>> Oh, ok thanks for the explanation.
> >>> It doesn't sound like a problem then.
> >>>
> >>> I'll just code things the same way.
> >>>
> >>> Maybe I can ask one more question??
> >>> There are a large # of XXX_decode_XXX functions. Are there any that
> >>> should/should not be used for the above case?
> >>> For example, there are:
> >>> - Ones that take a "struct xdr_stream *xdr" (usually with _stream_ in
> >>> the name)
> >>> vs
> >>> - Ones that take a "struct xdr_buf *buf" argument.
> >>>  (I ended up using these for the encode side and this looks like
> >>> what
> >>>   nfsacl_decode() uses, as well.)
> >>>
> >>> (I'll admit I have been wading around in the code, but haven't really
> >>> gotten to the point of understanding which ones should be used.)
> >>>
> >>
> >> The "struct xdr_stream' based code is the 'newer' way of doing things,
> >> and allows you to write code that abstracts away some of the ugliness
> >> in the RPC layer, particularly when you need to mix regular buffers and
> >> page data.
> >> That said, there is definitely legacy code out there that works quite
> >> well and is not worth a lot of effort to convert.
> >>
> >> I'd recommend trying to use the xdr_stream if possible, just because of
> >> the better abstraction, but if you have to fall back to manipulating
> >> the xdr_buf directly, then that API is there, and is still supported.
> > I haven't been able to figure out how to use the xdr_stream... stuff
> > when the attributes get large enough that they need pages.
> >
> > What I currently have (that seems to work) is...
> > For GETATTR, XDRBUF_SPARSE_PAGES is set, and then, once it
> > gets to the actual ACL (which can be pretty big), I use
> >   xdr_decode_word() and read_bytes_from_xdr_buf() to decode it
> >   (The stream calls worked until the ACL got too big for the non-page
> >    part, which I think is 2Kbytes?)
> >   - Maybe there is some trick I don't know to get the big ones to work
> >     with the xdr_stream_XXX() decode calls?
>
> See xdr_set_scratch_buffer() -- xdr_stream wants a scratch
> buffer for managing the transitions between the xdr_buf's
> head/page/tail components.
Thanks Chuck. That seems to work fine, rick

>
>
> --
> Chuck Lever
>
>





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux