* Miklos Szeredi:
quoted
Try-and-resize interfaces can be quite bad for data obtained from the
network.
In this particular case it's all local information.
That's good.
quoted
If the first call provides the minimum buffer size (like
getgroups, but unlike readlink or the glibc *_r interfaces for NSS),
this could at least allow us to avoid allocating too much. In
userspace, we cannot reduce the size of the heap allocation without
knowing where the pointers are and what they mean.
Does it matter if the heap allocation is say 32k instead of 589bytes?
The returned strings are not limited in size, but are quite unlikely
to be over PATH_MAX.
It matters if the application needs to keep a copy.
E.g. getdents apparently uses 32k buffers, which is really a tiny
amount of heap these days, but more than enough for the purpose. Not
sure if this is hard coded into libc or if it's the result of some
heuristic based on available memory, but I don't see why similar
treatment couldn't be applied to the statmount(2) syscall.
getdents gets away with this buffer size because applications can copy
out all the data from struct dirent if they need long-term storage.
They have to do that because the usual readdir interface overwrites the
buffer, potentially at the next readdir call. This means the buffer
size does not introduce an amount of memory fragmention that is
dependent on the directory size.
With an opaque, pointer-carrying struct, copying out the data is not
possible in a generic fashion. Only the parts that the application
knows about can be copied out. So I think it's desirable to have a
fairly exact allocation.
quoted
I also don't quite understand the dislike of variable-sized records.
Don't getdents, inotify, Netlink all use them? And I think at least for
Netlink, more stuff is added all the time?
What do you mean by variable sized records?
Iterating through d_reclen-sized subojects (for getdents).
Thanks,
Florian