diff --git a/src/fs/devfs.c b/src/fs/devfs.c index e476f684..c0e5afe7 100644 --- a/src/fs/devfs.c +++ b/src/fs/devfs.c @@ -50,9 +50,35 @@ static int devfs_create() UNIMPLEMENTED static int devfs_write() UNIMPLEMENTED static int devfs_read() UNIMPLEMENTED +static int devfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount){ + + *readcount = 0; + + // all getdirents on devfs will return the same + + for(uintmax_t i = 0; i < count; ++i){ + dent_t* d = &buff[i]; + vnode_t* child = hashtable_fromoffset(&devnodes, offset, d->d_name); + + if(!child){ + *readcount = i; + return 0; + } + + d->d_ino = child->st.st_ino; + d->d_off = offset; + d->d_reclen = sizeof(dent_t); + d->d_type = GETTYPE(child->st.st_mode); + ++offset; + } + + *readcount = count; + + return 0; +} static fscalls_t devfscalls = { - devfs_mount, devfs_unmount, devfs_open, devfs_close, devfs_mkdir, devfs_create, devfs_write, devfs_read + devfs_mount, devfs_unmount, devfs_open, devfs_close, devfs_mkdir, devfs_create, devfs_write, devfs_read, devfs_getdirent }; void devfs_init(){ @@ -64,8 +90,6 @@ void devfs_init(){ } - - int devfs_newdevice(char* name, int type, dev_t dev, mode_t mode){ vnode_t* node = vfs_newnode(name, fs, 0); diff --git a/src/fs/tmpfs.c b/src/fs/tmpfs.c index b1e5f3c3..4d598d50 100644 --- a/src/fs/tmpfs.c +++ b/src/fs/tmpfs.c @@ -4,6 +4,8 @@ #include #include #include +#include + static int tmpfs_mount(dirnode_t* mountpoint, vnode_t* device, int mountflags, void* fsinfo){ @@ -126,8 +128,32 @@ static int tmpfs_create(dirnode_t* parent, char* name, mode_t mode){ return 0; } +static int tmpfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount){ + + *readcount = 0; + + for(uintmax_t i = 0; i < count; ++i){ + dent_t* d = &buff[i]; + vnode_t* child = hashtable_fromoffset(&node->children, offset, d->d_name); + if(!child){ + *readcount = i; + return 0; + } + + d->d_ino = child->st.st_ino; + d->d_off = offset; + d->d_reclen = sizeof(dent_t); + d->d_type = GETTYPE(child->st.st_mode); + ++offset; + } + + *readcount = count; + + return 0; +} + static fscalls_t funcs = { - tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create, tmpfs_write, tmpfs_read + tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create, tmpfs_write, tmpfs_read, tmpfs_getdirent }; diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 282359a5..2a4b97d1 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -5,6 +5,7 @@ #include #include #include +#include dirnode_t* vfsroot; hashtable fsfuncs; @@ -134,6 +135,27 @@ int vfs_close(vnode_t* node){ return status; } +int vfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount){ + + int err = 0; + + spinlock_acquire(&lock); + + + if(GETTYPE(node->vnode.st.st_mode) != TYPE_DIR){ + err = ENOTDIR; + goto _ret; + } + + err = node->vnode.fs->calls->getdirent(node, buff, count, offset, readcount); + + _ret: + + spinlock_release(&lock); + + return err; +} + int vfs_open(vnode_t** buff, dirnode_t* ref, char* path){ vnode_t* node; @@ -375,6 +397,10 @@ int vfs_resolvepath(vnode_t** result, dirnode_t** resultparent, dirnode_t* ref, if(resultparent) *resultparent = iterator->vnode.parent; + + if(GETTYPE(iterator->vnode.st.st_mode) == TYPE_DIR) + iterator = mountpoint(iterator); + *result = (vnode_t*)iterator; return 0; diff --git a/src/include/dirent.h b/src/include/dirent.h new file mode 100644 index 00000000..26f9807b --- /dev/null +++ b/src/include/dirent.h @@ -0,0 +1,24 @@ +#ifndef _DIRENT_H_INCLUDE +#define _DIRENT_H_INCLUDE + +#include + +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 + +typedef struct { + ino_t d_ino; + off_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[1024]; +} dent_t; + +#endif diff --git a/src/include/kernel/vfs.h b/src/include/kernel/vfs.h index 7fc5762d..55eaa654 100644 --- a/src/include/kernel/vfs.h +++ b/src/include/kernel/vfs.h @@ -4,6 +4,7 @@ #include #include #include +#include struct _vnode_t; struct _fscalls_t; @@ -56,6 +57,8 @@ typedef struct _fscalls_t { int (*write)(int* error, vnode_t* node, void* buff, size_t count, size_t offset); // read from a file int (*read)(int* error, vnode_t* node, void* buff, size_t count, size_t offset); + // get dir ents + int (*getdirent)(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount); } fscalls_t; @@ -68,6 +71,7 @@ int vfs_create(dirnode_t* ref, char* path, mode_t mode); int vfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset); int vfs_read(int* error, vnode_t* node, void* buff, size_t count, size_t offset); int vfs_isatty(vnode_t* node); +int vfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount); void vfs_init(); dirnode_t* vfs_root();