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 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.


--
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