Jann Horn <jannh@xxxxxxxxxx> wrote: > Hm - I guess just returning a list of attributes ought to be fine? > Then AFS can just return one of its two statically-allocated attribute > lists there, and a filesystem with more complicated circumstances > (like FUSE or overlayfs or whatever) can compute a heap-allocated list > on mount that is freed when the superblock goes away, or something > like that? I've changed it so that the core calls into the filesystem with no buffer allocated first. If the fs finds an appropriate attribute, it calls a helper to handle it. As there's no buffer, this will just return the size. If the fs doesn't have a handler, it returns -EOPNOTSUPP and the core looks for a common attribute instead and calls the helper on that if found. At this point, if a valid length was returned and if userspace didn't specify a buffer, we just return the proposed size to userspace. If userspace did specify a buffer, then core will allocate a buffer of the requested size and call into the filesystem again. The helper will call the ->get() function to retrieve the value. The ->get() function returns the size. If the returned size exceeds the buffer size, a bigger buffer will be allocated and it will repeat the last step. A simple example looks like: int ext4_fsinfo(struct path *path, struct fsinfo_context *ctx) { return fsinfo_get_attribute(path, ctx, ext4_fsinfo_attributes); } where the ext4_fsinfo_attributes is an array of attribute defs. The helper, fsinfo_get_attribute() scans the list. The helper can be called multiple times if there's more than one list to process. The caller should stop if one doesn't return -EOPNOTSUPP. When the attribute IDs are being listed, the helper will detect that and just add all the IDs to the list, returning -EOPNOTSUPP when it's done so that all the attributes get listed. When the metadata for an attribute is being retrieved, the helper detects that and searches the given table for that attribute. If it finds it, it will return information about that attribute rather than calling the attribute helper. David