New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File system truncate API #7010
Comments
As mentioned in PelionIoT/sd-driver#99, we do have implementations of truncate in both the ChaN FAT filesystem and LittleFS, so it should just be an API addition here: |
@geky could you please help me add the API? i have no idea how to define it |
@geky I can look at doing If we do have that, does it make sense to have [Mirrored to Jira] |
I think we shouldn't add apis without design review |
Is there someway I could add it now?
I need it for my work
El vie., 25 de may. de 2018 9:22 AM, Daniel Benor <notifications@github.com>
escribió:
I think we shouldn't add apis without design review
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#7010 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AkhVKoBb8ji6Toh3wtN7I3Gog3Xtwq4Qks5t2BOkgaJpZM4UM_Wd>
.
*[Mirrored to Jira]*
|
Sorry I missed so many messages @OscarGarciaF, the ChaN documentation may help: It looks like truncate uses the current file position. So you will need to seek to where you want to truncate to first. I haven't tested it, but adding this implementation to the FATFileSystem may work: int FATFileSystem::file_truncate(fs_file_t file, off_t length)
{
FIL *fh = static_cast<FIL*>(file);
lock();
// save current position
FSIZE_T oldoff = f_tell(fh);
// seek to new file size and truncate
FRESULT res = f_lseek(fh, length);
if (res) {
unlock();
return fat_error_remap(res);
}
FRESULT res = f_truncate(fh);
if (res) {
unlock();
return fat_error_remap(res);
}
// restore old position
FRESULT res = f_lseek(fh, oldoff);
if (res) {
unlock();
return fat_error_remap(res);
}
return 0;
} Unfortunately, there are several layers that the API needs to be poked through:
That should be enough to get you to the point where you can use the truncate API: FATFileSystem fs("fs", &bd);
int main() {
// with C++ api
File f;
f.open(&fs, "hi.txt", O_WRONLY);
f.truncate(1000);
f.close();
} To add
@kjbracey-arm, I think retarget support to call FileHandle::truncate is sufficient, this would be poked through to the filesystems like this:
It's a bit of a long chain but gets you where you want and allows support at both the FileSystem and FileHandle levels.
@kjbracey-arm, Sounds fine to me, LittleFS and POSIX support allocation via truncate (counterintuitively), and ChaN has its own f_expand function. Also should be noted none of our filesystem support file holes.
@dannybenor, that shouldn't stop someone from creating a PR. It's the only way for @OscarGarciaF to initiate a design review. Fortunately ftruncate is already a standardized API as a part of POSIX: [Mirrored to Jira] |
Thanks you so much @geky, you are a real life saver.
I will test it out today at work
El vie., 25 de may. de 2018 11:14 AM, Christopher Haster <
notifications@github.com> escribió:
Sorry I missed so many messages
@OscarGarciaF <https://github.com/OscarGarciaF>, the ChaN documentation
may help:
http://elm-chan.org/fsw/ff/doc/truncate.html
It looks like truncate uses the current file position. So you will need to
seek to where you want to truncate to first.
I haven't tested it, but adding this implementation to the FATFileSystem
may work:
int FATFileSystem::file_truncate(fs_file_t file, off_t length)
{
FIL *fh = static_cast<FIL*>(file);
lock();
// save current position
FSIZE_T oldoff = f_tell(fh);
// seek to new file size and truncate
FRESULT res = f_lseek(fh, length);
if (res) {
unlock();
return fat_error_remap(res);
}
FRESULT res = f_truncate(fh);
if (res) {
unlock();
return fat_error_remap(res);
}
// restore old position
FRESULT res = f_lseek(fh, oldoff);
if (res) {
unlock();
return fat_error_remap(res);
}
return 0;
}
Unfortunately, there are several layers that the API needs to be poked
through:
- Add function to FATFileSystem
class FATFileSystem {
virtual int file_truncate(fs_file_t file, off_t length);
}
https://github.com/ARMmbed/mbed-os/blob/master/features/filesystem/fat/FATFileSystem.h#L37
- Add virtual function to the abstract FileSystem class
class FileSystem {
virtual int file_truncate(fs_file_t file, off_t length) = 0;
}
https://github.com/ARMmbed/mbed-os/blob/master/features/filesystem/FileSystem.h#L49
- Add wrapper for File class
class File {
virtual int truncate(off_t length) {
return _fs->file_truncate(_file, length);
}
}
https://github.com/ARMmbed/mbed-os/blob/master/features/filesystem/File.h#L30
That should be enough to get you to the point where you can use the
truncate API:
FATFileSystem fs("fs", &bd);
int main() {
// with C++ api
File f;
f.open(&fs, "hi.txt", O_WRONLY);
f.truncate(1000);
f.close();
}
To add ftruncate and truncate would require toolchain specific
retargetting support. This can get quite a bit more difficult.
------------------------------
If we do have that, does it make sense to have FileSystem::truncate also
passed down to filesystem implementations, or could the be defined in terms
of FileHandle::truncate?
@kjbracey-arm <https://github.com/kjbracey-arm>, I think retarget support
to call FileHandle::truncate is sufficient, this would be poked through to
the filesystems like this:
ftruncate --calls-> FileHandle::truncate --virtual-> File::truncate --calls-> FileSystem::file_truncate --virtual-> FATFileSystem::file_truncate
It's a bit of a long chain but gets you where you want and allows support
at both the FileSystem and FileHandle levels.
I was also fancying its opposite posix_fallocate and FileHandle::allocate
@kjbracey-arm <https://github.com/kjbracey-arm>, Sounds fine to me,
LittleFS and POSIX support allocation via truncate (counterintuitively),
and ChaN has its own f_expand function. Though none of our filesystem
support file holes.
I think we shouldn't add apis without design review
@dannybenor <https://github.com/dannybenor>, that shouldn't stop someone
from creating a PR. It's the only way for @OscarGarciaF
<https://github.com/OscarGarciaF> to initiate a design review.
Fortunately ftruncate is already a standardized API as a part of POSIX:
http://pubs.opengroup.org/onlinepubs/007908799/xsh/ftruncate.html
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#7010 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AkhVKsettw6jZDIyk1Q-66pxKN11JyZQks5t2C3PgaJpZM4UM_Wd>
.
*[Mirrored to Jira]*
|
@geky im getting an error since im using FILE(aka __sFILE) instead of File [Mirrored to Jira] |
Ah yes, they are different things. Unfortunately, @kjbracey-arm correct me if I'm wrong, I don't think you can get the FileHandle from a FILE. What you can do, is add the extern "C" int ftruncate(int fildes, off_t length) {
FileHandle* fhc = get_fhc(fildes);
int err = fhc->truncate(length);
if (err) {
errno = -err;
return -1;
}
return 0;
} Note this has to be in mbed_retarget.cpp, since get_fhc is internal. Then you can use it in combination with the int main() {
FILE *f = fopen("/fs/hi.txt", O_WRONLY);
int fd = fileno(f);
ftruncate(fd, 1000);
} [Mirrored to Jira] |
thanks @geky [Mirrored to Jira] |
@geky, no sorry, can't do @OscarGarciaF - |
@kjbracey-arm if they cannot be merged then why not eliminate one to have an unified API? |
The internals of mbed-os are built on C++ classes, so at some layer (maybe internally) there will be a C++ api. The POSIX layer is it's own feature that (in theory) lets you easily add libraries written for the desktop to your application. It's been around since mbed got off the ground and extends to other less obvious features, such as support for printf and time functions. Maybe it would help the user experience to document the |
Internal Jira reference: https://jira.arm.com/browse/IOTSTOR-446 |
I'm sorry to ask this here but would anyone know how to implement geky's workaround for MBED 2? It seems like much the same deal, adding the virtual functions to the SDFileSystem's FATFileHandle, and then MBED's FileHandle and LocalFileSystem. However, adding the function screws with every library that uses the Stream class, which inherits FileHandle. Anybody know how to make it not make all my stream classes virtual? I've tried adding the function to Stream as well but that results in obscure linker errors. |
Description
From @OscarGarciaF:
How can i truncate a file to a certain size with this library?
related PelionIoT/sd-driver#99, IOTSTOR-352
cc @dannybenor, @kjbracey-arm, @ARMmbed/mbed-os-storage fyi
Issue request type
[x] Question
[ ] Enhancement
[ ] Bug
The text was updated successfully, but these errors were encountered: