Rework getting and listing attributes
authorIustin Pop <iustin@k1024.org>
Tue, 25 Oct 2016 22:34:07 +0000 (00:34 +0200)
committerIustin Pop <iustin@k1024.org>
Tue, 25 Oct 2016 23:27:40 +0000 (01:27 +0200)
commit4cb3598f6e5f3279f93f9888b7a1d59827c708f4
tree6c0f48c654f3be445a6ecb4627f20e92b12d5ff1
parent951bc94f126e499b41d9957385e102616a795b2b
Rework getting and listing attributes

Currently, getting and listing attributes is inconsistent in how it
deals with allocating memory for the data returned by the syscall:

- in most cases, we ask the kernel for the value, allocate memory,
  then retrieve the value; if the value changed (increased) in the
  meantime, this will lead to what should be preventable failures
- in the single case of getall, there is a loop for getting the
  individual values, but not for initially get the list of values

Hence the bug report #12. This rather large change refactors a lot of
the code:

- doing a get/list is abstracted away into a helper function that
  always does retries until we can read the value or fail with a
  different error than ERANGE; this helper deal with all allocations
  and resize operations.
- this means most of the single get/list operations are heavily
  simplified
- and also means that we can always start optimistically with an
  initial buffer size (currently set to 1K), instead of asking the
  kernel first: this saves one out of two syscalls in the case the
  value will indeed be smaller, but adds one extra syscall (the failed
  initial read) in the case it's not.

The optimisation is a double-edged sword: for small attributes, it
will be a win (e.g. the test suite is ~5% faster now), but for large
attribute/lists, it will be potentially slower (50% more
syscalls). Not sure how to nicely deal with this; it would be good to
have a keyword argument maybe? Or build flag? Left for future
enhancements.

Closes #12.
xattr.c