Re: Remove/change fs_truncate() API


Paul Sokolovsky
 

Hello,

On Mon, 4 Sep 2017 09:27:30 +0200
Andrzej Kaczmarek <andrzej.kaczmarek@...> wrote:

Hi,

I was trying to implement fs_truncate() for NFFS but this does not
seem to be possible in a reasonable way, at least not with current
NFFS API. The only option I see now is to copy contents to new file
and unlink old one, but this has obvious disadvantages: it's slow, we
may easily run out of space etc.
ENOTSUP is your friend (except Linux thinks it should be EPERM, see
below).

So do we really need option to truncate any opened file to any size?
POSIX has it:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/ftruncate.html , so we
apparently need it too.

In Mynewt there's only option to truncate file to 0 when opening it by
specifying flag to fs_open() and this seems to be just enough.There
seems to be not many references to fs API right now (actually
Bluetooth subsystem is the only one) so perhaps we could just remove
fs_truncate() and allow truncate to 0 using something else?
In a Linux system, only 0.0001% or so of the source code belongs to the
kernel. With that ratio in mind, how many Zephyr applications have you
considered?

My proposal would be one of:
- add flag to fs_open()
- make fs_truncate() truncate file specified by *path* to 0
Let's have a look at https://linux.die.net/man/2/ftruncate :

truncate(): /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
ftruncate(): /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L

So, ftruncate() was categorized in glibc since the break of the century,
while truncate()-by-path is much more of a novelty, which should set
a priority of the order of their support.

The reason why I'd prefer to have truncation done by *path* instead of
*fp* is because it's simpler to implement in NFFS since what needs to
be done is to unlink old file and create new one. The API to create
new file takes full path as a parameter so having fp only makes it a
bit more complicated.
This seems like a logical fallacy: you have a problem with a single
thing on your hands (NFFS) and you want to change the world around it
(Zephyr API). Just accepting that NFFS is a novel, unproven,
underdeveloped and undertested filesystem should give enough of a
solution: just treat ftruncate operation as unsupported on it. Another
solution of course is to fix NFFS to support a standard POSIX
filesystem operation repertoire.

Let's look at https://linux.die.net/man/2/ftruncate again:

EPERM
The underlying file system does not support extending a file beyond its
current size.

However, my local man has more of it:

EPERM The underlying filesystem does not support extending
a file beyond its current size.

EPERM The operation was prevented by a file seal; see fcntl(2).

So, in Linux, EPERM is ambiguous. There's actually a better error code
- ENOTSUP. Arguably, it's the same "POSIX drama" as with EPERM vs
EACCESS, vividly explained here:
http://blog.unclesniper.org/archives/2-Linux-programmers,-learn-the-difference-between-EACCES-and-EPERM-already!.html
Following the same logic, I'd recommend to use ENOTSUP here (then wait
until Zephyr's POSIX subsystem matures, apps getting ported, and break
because of the "non-Linuxy" error code is used, then we switch it to
EPERM).


Best regards,
Andrzej


--
Best Regards,
Paul

Linaro.org | Open source software for ARM SoCs
Follow Linaro: http://www.facebook.com/pages/Linaro
http://twitter.com/#!/linaroorg - http://www.linaro.org/linaro-blog

Join {devel@lists.zephyrproject.org to automatically receive all group messages.