Skip to content
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

🚸 Add missing filesystem functions #184

Closed

Conversation

TheOregonTrail
Copy link

@TheOregonTrail TheOregonTrail commented Nov 12, 2019

Summary:

Provides Stubs for
chdir
mkdir -- Partial Implementation
chmod
pathconf
getcwd
unlink
link -- Partial Implementation
stat

fixes #176
(maybe) closes #175

@nathan-moore
Copy link
Member

You have some build errors: https://gist.github.com/nathan-moore/7763e0a66be450e184284b8a07982150

Also, what about ser_driver and dev_driver? They also make a fs_driver struct and need to be added to.

Copy link
Member

@nathan-moore nathan-moore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably also should run this through Clang format when you're done with it.

include/api.h Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
include/system/dev/vfs.h Outdated Show resolved Hide resolved
src/system/dev/dev_driver.c Outdated Show resolved Hide resolved
src/system/dev/usd_driver.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/dev_driver.c Outdated Show resolved Hide resolved
src/system/dev/ser_driver.c Outdated Show resolved Hide resolved
version Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/dev_driver.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
include/system/dev/vfs.h Outdated Show resolved Hide resolved
src/system/dev/dev_driver.c Outdated Show resolved Hide resolved
src/system/dev/ser_driver.c Outdated Show resolved Hide resolved
src/system/dev/usd_driver.c Outdated Show resolved Hide resolved
Comment on lines 93 to 102
int file_size(const char* file) {
// Returns true if is under size constraint
size_t i = 0;
for (i = 0; i < MAX_FILELEN; i++) {
if (file[i] == '\0') {
break;
}
}
if (i == MAX_FILELEN) {
return i != MAX_FILELEN;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed, see below

int _open(const char* file, int flags, int mode) {
struct _reent* r = _REENT;
// Check if the filename is too long or not NULL terminated
if (!file_size(file)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just realized we can definitely use strnlen here...

Suggested change
if (!file_size(file)) {
if (strnlen(file, MAX_FILELEN) == MAX_FILELEN) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why we didn't before, unless @edjubuh had some concerns about it? (it's part of the C standard as of C11)

Copy link
Contributor

@HotelCalifornia HotelCalifornia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, a slightly larger review this time. I should have thought about this more earlier, but basically it doesn't make sense given the current implementation to have anything that takes a path argument (as opposed to a file descriptor argument) to the fs_driver struct.

there's two ways I see that we could go about this:

  • do what we did with open, and explicitly delegate to a function like *_open_r
  • change the fs_driver's semantics so that each function taking a path name is called having stripped off the driver-descriptive part of the path

I would have said that the first option is the easiest, however given the number of functions being added here I don't actually think that's the case. Plus, the second option would make #178 easier to work on in the future.

So let me elaborate on the second point. Let's consider mkdir as an example.

int mkdir(const char* pathname, mode_t mode) {
    struct _reent* r = _REENT;
    // check length of pathname
    size_t len = 0;
    if ((len = strnlen(pathname, MAX_FILELEN)) == MAX_FILELEN) {
        r->_errno = ENAMETOOLONG;
        return -1;
    }
    if (len <= 3) {
        // this means that it's too short to be meaningful (needs to at least have "/a/")
        r->_errno = ENOENT;
        return -1;
    } else if (*pathname != '/') {
        // our paths need to start with '/' by convention. this check is delayed so that we
        // can ensure dereferencing the pathname is safe
        r->_errno = ENOENT;
        return -1;
    }
    // now we've established there's some meaningful path
    // by convention, a path should be of the form `/drv/path...` where `drv` is the driver id
    // so we want to find the first substring that starts and ends with '/' to extract this id
    char* path = strchr(pathname + 1, '/'); // skip the first character as we already know it
    size_t drvlen = len - strlen(path);
    char* drv = malloc(drvlen * sizeof(*drv)); // allocate some space for the driver id
    strncpy(drv, pathname, drvlen);
    // at this point we have everything we need, so look up the driver for the driver id
    struct fs_driver* driver;
    if (!(driver = driver_lookup(drv)) {
        free(drv); // make sure to free up memory
        r->_errno = EFAULT; // this errno value is up for debate
        return -1;
    }
    free(drv);
    return driver->mkdir_r(r, pathname + drvlen, mode);
}

A lot of that path extraction stuff could definitely be refactored into its own function. driver_lookup and associated storage would also need to be defined and implemented. Since we currently only support the three drivers (usd, ser, and dev), this would be as simple as checking the driver id and returning a pointer to the right driver (this can be easily extended later).

src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved
src/system/dev/vfs.c Outdated Show resolved Hide resolved

int _chdir(const char* path) {
struct _reent* r = _REENT;
return file_table[file].driver->chdir(r, file_table[file].arg, path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as mkdir


int _chmod(const char* path, mode_t mode) {
struct _reent* r = _REENT;
return file_table[file].driver->chdir(r, file_table[file].arg, path, mode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as mkdir

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls chdir, not chmod.


int _pathconf(const char* path, int name) {
struct _reent* r = _REENT;
return file_table[file].driver->pathconf(r, file_table[file].arg, path, name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as mkdir

Comment on lines 31 to 38
int (*mkdir_r)(struct _reent*, void* const, mode_t mode);
int (*link_r)(struct _reent*, void* const, char*, char*);
int (*unlink_r)(struct _reent*, void* const, char*);
int (*chdir_r)(struct _reent*, void* const, const char*);
int (*chmod_r)(struct _reent*, void* const, const char*);
long (*pathconf_r)(struct _reent*, void* const, const char*, int);
char* (*getcwd_r)(struct _reent*, void* const, const char*, size_t);
int (*stat_r)(struct _reent*, void* const, const char*, struct*);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whatever implementation we end up with, these signatures are wrong. they should match the functions as they're defined

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll line up the signatures and everything during the last clean up commit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might as well do it sooner rather than later. it will make it easier for us to compile it for you

include/system/dev/vfs.h Outdated Show resolved Hide resolved
include/system/dev/vfs.h Outdated Show resolved Hide resolved

int _unlink(char* name) {
struct _reent* r = _REENT;
return file_table[file].driver->mkdir(r, file_table[file].arg, path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plus this calls mkdir, not unlink.


int _chmod(const char* path, mode_t mode) {
struct _reent* r = _REENT;
return file_table[file].driver->chdir(r, file_table[file].arg, path, mode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls chdir, not chmod.

@HotelCalifornia HotelCalifornia changed the title Stubs for Issue on GCC 9.2.0 🚸 Add missing filesystem functions Dec 6, 2019
Copy link
Member

@nathan-moore nathan-moore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newlib supports namespace clean functions for some of these. The ones it does I think you should be doing. There's a list hotel put on the original issue with the function names you should be matching, and it includes which ones have underscores and which ones don't.

return file_table[file].driver->mkdir(r, file_table[file].arg, path);
}

int unlink(char* name) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int unlink(char* name) {
int _unlink(char* name) {

return file_table[file].driver->unlink(r, file_table[file].arg, path);
}

int link(char* old, char* new) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int link(char* old, char* new) {
int _link(char* old, char* new) {

return file_table[file].driver->link(r, file_table[file].arg, new, old);
}

int stat(const char* restrict path, struct stat* st) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int stat(const char* restrict path, struct stat* st) {
int _stat(const char* restrict path, struct stat* st) {

@HotelCalifornia HotelCalifornia added this to In Progress in PROS Non-Versioned Kernel Development via automation Dec 15, 2019
@HotelCalifornia HotelCalifornia added bug Something isn't working enhancement This builds on top of an existing feature in progress This is currently being worked on labels Dec 15, 2019
@HotelCalifornia HotelCalifornia added this to the 3.2.1 milestone Dec 18, 2019
@HotelCalifornia HotelCalifornia removed this from the 3.2.1 milestone Jan 21, 2020
@HotelCalifornia
Copy link
Contributor

as this isn't immediately causing issues, let's close it and we can revisit it later as needed. plus i think the idea is that we'll rework a lot of this along the lines i mentioned (#184 (review)) come PROS 4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement This builds on top of an existing feature in progress This is currently being worked on
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Implement more syscalls Hot/Cold build problems on Linux with GCC 9.2.0
5 participants