From 07fefdf4933b15bad6793c1252435419ba0c9fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 10 Jul 2002 21:55:33 +0000 Subject: [PATCH] Implemented the read_dir(), and rewind_dir() functions for all internal file systems. Removed the read() functionality for directories. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@63 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/fs/bootfs.c | 241 +++++++++++++++++++++++++----------- src/kernel/core/fs/devfs.c | 236 ++++++++++++++++++++++------------- src/kernel/core/fs/rootfs.c | 183 +++++++++++++++++---------- 3 files changed, 439 insertions(+), 221 deletions(-) diff --git a/src/kernel/core/fs/bootfs.c b/src/kernel/core/fs/bootfs.c index 20be101883..19a21d973b 100755 --- a/src/kernel/core/fs/bootfs.c +++ b/src/kernel/core/fs/bootfs.c @@ -80,19 +80,25 @@ struct bootfs_cookie { } u; }; + #define BOOTFS_HASH_SIZE 16 -static unsigned int bootfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) + + +static unsigned int +bootfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) { struct bootfs_vnode *v = _v; const vnode_id *key = _key; - if(v != NULL) + if (v != NULL) return v->id % range; else return (*key) % range; } -static int bootfs_vnode_compare_func(void *_v, const void *_key) + +static int +bootfs_vnode_compare_func(void *_v, const void *_key) { struct bootfs_vnode *v = _v; const vnode_id *key = _key; @@ -103,7 +109,9 @@ static int bootfs_vnode_compare_func(void *_v, const void *_key) return -1; } -static struct bootfs_vnode *bootfs_create_vnode(struct bootfs *fs, const char *name) + +static struct bootfs_vnode * +bootfs_create_vnode(struct bootfs *fs, const char *name) { struct bootfs_vnode *v; @@ -123,7 +131,9 @@ static struct bootfs_vnode *bootfs_create_vnode(struct bootfs *fs, const char *n return v; } -static int bootfs_delete_vnode(struct bootfs *fs, struct bootfs_vnode *v, bool force_delete) + +static int +bootfs_delete_vnode(struct bootfs *fs, struct bootfs_vnode *v, bool force_delete) { // cant delete it if it's in a directory or is a directory // and has children @@ -141,14 +151,18 @@ static int bootfs_delete_vnode(struct bootfs *fs, struct bootfs_vnode *v, bool f return 0; } -static void insert_cookie_in_jar(struct bootfs_vnode *dir, struct bootfs_cookie *cookie) + +static void +insert_cookie_in_jar(struct bootfs_vnode *dir, struct bootfs_cookie *cookie) { cookie->u.dir.next = dir->stream.u.dir.jar_head; dir->stream.u.dir.jar_head = cookie; cookie->u.dir.prev = NULL; } -static void remove_cookie_from_jar(struct bootfs_vnode *dir, struct bootfs_cookie *cookie) + +static void +remove_cookie_from_jar(struct bootfs_vnode *dir, struct bootfs_cookie *cookie) { if(cookie->u.dir.next) cookie->u.dir.next->u.dir.prev = cookie->u.dir.prev; @@ -160,8 +174,11 @@ static void remove_cookie_from_jar(struct bootfs_vnode *dir, struct bootfs_cooki cookie->u.dir.prev = cookie->u.dir.next = NULL; } -/* makes sure none of the dircookies point to the vnode passed in */ -static void update_dircookies(struct bootfs_vnode *dir, struct bootfs_vnode *v) + +/** Makes sure none of the dircookies point to the vnode passed in */ + +static void +update_dircookies(struct bootfs_vnode *dir, struct bootfs_vnode *v) { struct bootfs_cookie *cookie; @@ -173,7 +190,8 @@ static void update_dircookies(struct bootfs_vnode *dir, struct bootfs_vnode *v) } -static struct bootfs_vnode *bootfs_find_in_dir(struct bootfs_vnode *dir, const char *path) +static struct bootfs_vnode * +bootfs_find_in_dir(struct bootfs_vnode *dir, const char *path) { struct bootfs_vnode *v; @@ -195,7 +213,9 @@ static struct bootfs_vnode *bootfs_find_in_dir(struct bootfs_vnode *dir, const c return NULL; } -static int bootfs_insert_in_dir(struct bootfs_vnode *dir, struct bootfs_vnode *v) + +static int +bootfs_insert_in_dir(struct bootfs_vnode *dir, struct bootfs_vnode *v) { if(dir->stream.type != STREAM_TYPE_DIR) return ERR_INVALID_ARGS; @@ -207,7 +227,9 @@ static int bootfs_insert_in_dir(struct bootfs_vnode *dir, struct bootfs_vnode *v return 0; } -static int bootfs_remove_from_dir(struct bootfs_vnode *dir, struct bootfs_vnode *findit) + +static int +bootfs_remove_from_dir(struct bootfs_vnode *dir, struct bootfs_vnode *findit) { struct bootfs_vnode *v; struct bootfs_vnode *last_v; @@ -228,18 +250,24 @@ static int bootfs_remove_from_dir(struct bootfs_vnode *dir, struct bootfs_vnode return -1; } -static int bootfs_is_dir_empty(struct bootfs_vnode *dir) + +static int +bootfs_is_dir_empty(struct bootfs_vnode *dir) { if(dir->stream.type != STREAM_TYPE_DIR) return false; return !dir->stream.u.dir.dir_head; } -// creates a path of vnodes up to the last part of the passed in path. -// returns the vnode the last segment should be a part of and -// a pointer to the leaf of the path. -// clobbers the path string passed in -static struct bootfs_vnode *bootfs_create_path(struct bootfs *fs, char *path, struct bootfs_vnode *base, char **path_leaf) + +/** Creates a path of vnodes up to the last part of the passed in path. + * returns the vnode the last segment should be a part of and + * a pointer to the leaf of the path. + * clobbers the path string passed in + */ + +static struct bootfs_vnode * +bootfs_create_path(struct bootfs *fs, char *path, struct bootfs_vnode *base, char **path_leaf) { struct bootfs_vnode *v; char *temp; @@ -303,7 +331,9 @@ static struct bootfs_vnode *bootfs_create_path(struct bootfs *fs, char *path, st return base; } -static int bootfs_create_vnode_tree(struct bootfs *fs, struct bootfs_vnode *root) + +static int +bootfs_create_vnode_tree(struct bootfs *fs, struct bootfs_vnode *root) { int i; boot_entry *entry; @@ -314,7 +344,7 @@ static int bootfs_create_vnode_tree(struct bootfs *fs, struct bootfs_vnode *root char *leaf; entry = (boot_entry *)bootdir; - for(i=0; istream.type != STREAM_TYPE_DIR) + if (dir->stream.type != STREAM_TYPE_DIR) return ERR_VFS_NOT_DIR; mutex_lock(&fs->lock); // look it up v = bootfs_find_in_dir(dir, name); - if(!v) { + if (!v) { err = ENOENT; goto err; } @@ -479,7 +520,9 @@ err: return err; } -static int bootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) + +static int +bootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) { struct bootfs *fs = (struct bootfs *)_fs; int err; @@ -502,7 +545,9 @@ static int bootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) return ENOENT; } -static int bootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) + +static int +bootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) { struct bootfs_vnode *v = (struct bootfs_vnode *)_v; @@ -511,7 +556,9 @@ static int bootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) return 0; // whatever } -static int bootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) + +static int +bootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) { struct bootfs *fs = (struct bootfs *)_fs; struct bootfs_vnode *v = (struct bootfs_vnode *)_v; @@ -539,14 +586,16 @@ err: return err; } -static int bootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) + +static int +bootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; struct bootfs_cookie *cookie; int err = 0; int start = 0; -dprintf("bootfs_open: \n"); + TRACE(("bootfs_open: vnode 0x%x, stream_type %d, oflags 0x%x\n", v, st, oflags)); if(st != STREAM_TYPE_ANY && st != v->stream.type) { @@ -555,7 +604,7 @@ dprintf("bootfs_open: \n"); } cookie = kmalloc(sizeof(struct bootfs_cookie)); - if(cookie == NULL) { + if (cookie == NULL) { err = ERR_NO_MEMORY; goto err; } @@ -583,7 +632,9 @@ err: return err; } -static int bootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) + +static int +bootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -594,7 +645,9 @@ static int bootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) return 0; } -static int bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) + +static int +bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -608,12 +661,16 @@ static int bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) return 0; } -static int bootfs_fsync(fs_cookie _fs, fs_vnode _v) + +static int +bootfs_fsync(fs_cookie _fs, fs_vnode _v) { return 0; } -static ssize_t bootfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) + +static ssize_t +bootfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -625,27 +682,6 @@ static ssize_t bootfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void mutex_lock(&fs->lock); switch(cookie->s->type) { - case STREAM_TYPE_DIR: { - if(cookie->u.dir.ptr == NULL) { - *len = 0; - err = ENOENT; - break; - } - - if((ssize_t)strlen(cookie->u.dir.ptr->name) + 1 > *len) { - err = ERR_VFS_INSUFFICIENT_BUF; - goto err; - } - - err = user_strcpy(buf, cookie->u.dir.ptr->name); - if(err < 0) - goto err; - - err = strlen(cookie->u.dir.ptr->name) + 1; - - cookie->u.dir.ptr = cookie->u.dir.ptr->dir_next; - break; - } case STREAM_TYPE_FILE: if(*len <= 0) { err = 0; @@ -681,14 +717,18 @@ err: return err; } -static ssize_t bootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_t pos, size_t *len) + +static ssize_t +bootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_t pos, size_t *len) { TRACE(("bootfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, *len)); return EROFS; } -static int bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) + +static int +bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -758,17 +798,55 @@ static int bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t po static int -bootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num) +bootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num) { - // ToDo: implement me! - return B_OK; + struct bootfs_cookie *cookie = _cookie; + struct bootfs *fs = _fs; + status_t status; + + TRACE(("bootfs_read_dir(vnode = 0x%x, cookie = 0x%x, buffer = 0x%x, bufferSize = 0x%x)\n", v, cookie, buffer, bufferSize)); + + mutex_lock(&fs->lock); + + if (cookie->u.dir.ptr == NULL) { + *_num = 0; + status = ENOENT; + goto err; + } + + dirent->d_dev = fs->id; + dirent->d_ino = cookie->u.dir.ptr->id; + dirent->d_reclen = strlen(cookie->u.dir.ptr->name); + + if (sizeof(struct dirent) + dirent->d_reclen + 1 > bufferSize) { + status = ERR_VFS_INSUFFICIENT_BUF; + goto err; + } + + status = user_strcpy(dirent->d_name, cookie->u.dir.ptr->name); + if (status < B_OK) + goto err; + + cookie->u.dir.ptr = cookie->u.dir.ptr->dir_next; + +err: + mutex_unlock(&fs->lock); + return status; } static int bootfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie) { - // ToDo: me too! + struct bootfs *fs = _fs; + struct bootfs_vnode *vnode = _vnode; + struct bootfs_cookie *cookie = _cookie; + + mutex_lock(&fs->lock); + + cookie->u.dir.ptr = vnode->stream.u.dir.dir_head; + + mutex_unlock(&fs->lock); return B_OK; } @@ -788,13 +866,15 @@ bootfs_canpage(fs_cookie _fs, fs_vnode _v) TRACE(("bootfs_canpage: vnode 0x%x\n", v)); - if(v->stream.type == STREAM_TYPE_FILE) + if (v->stream.type == STREAM_TYPE_FILE) return 1; else return 0; } -static ssize_t bootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) + +static ssize_t +bootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -802,8 +882,8 @@ static ssize_t bootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t p TRACE(("bootfs_readpage: vnode 0x%x, vecs 0x%x, pos 0x%x 0x%x\n", v, vecs, pos)); - for(i=0; inum; i++) { - if(pos >= v->stream.u.file.len) { + for (i = 0; i < vecs->num; i++) { + if (pos >= v->stream.u.file.len) { memset(vecs->vec[i].iov_base, 0, vecs->vec[i].iov_len); pos += vecs->vec[i].iov_len; } else { @@ -823,7 +903,9 @@ static ssize_t bootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t p return EPERM; } -static ssize_t bootfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) + +static ssize_t +bootfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -833,22 +915,30 @@ static ssize_t bootfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t return ERR_NOT_ALLOWED; } -static int bootfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid) + +static int +bootfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid) { return ERR_VFS_READONLY_FS; } -static int bootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) + +static int +bootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) { return ERR_VFS_READONLY_FS; } -static int bootfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _newdir, const char *newname) + +static int +bootfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _newdir, const char *newname) { return ERR_VFS_READONLY_FS; } -static int bootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) + +static int +bootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -886,7 +976,8 @@ err: } -static int bootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) +static int +bootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -897,6 +988,10 @@ static int bootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_ return ERR_VFS_READONLY_FS; } + +// #pragma mark - + + static struct fs_calls bootfs_calls = { &bootfs_mount, &bootfs_unmount, diff --git a/src/kernel/core/fs/devfs.c b/src/kernel/core/fs/devfs.c index 3871606407..7c58ebb69c 100755 --- a/src/kernel/core/fs/devfs.c +++ b/src/kernel/core/fs/devfs.c @@ -94,7 +94,10 @@ struct devfs_cookie { static struct devfs *thedevfs = NULL; #define BOOTFS_HASH_SIZE 16 -static unsigned int devfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) + + +static unsigned int +devfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) { struct devfs_vnode *v = _v; const vnode_id *key = _key; @@ -105,7 +108,9 @@ static unsigned int devfs_vnode_hash_func(void *_v, const void *_key, unsigned i return (*key) % range; } -static int devfs_vnode_compare_func(void *_v, const void *_key) + +static int +devfs_vnode_compare_func(void *_v, const void *_key) { struct devfs_vnode *v = _v; const vnode_id *key = _key; @@ -116,7 +121,9 @@ static int devfs_vnode_compare_func(void *_v, const void *_key) return -1; } -static struct devfs_vnode *devfs_create_vnode(struct devfs *fs, const char *name) + +static struct devfs_vnode * +devfs_create_vnode(struct devfs *fs, const char *name) { struct devfs_vnode *v; @@ -136,7 +143,9 @@ static struct devfs_vnode *devfs_create_vnode(struct devfs *fs, const char *name return v; } -static int devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *v, bool force_delete) + +static int +devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *v, bool force_delete) { // cant delete it if it's in a directory or is a directory // and has children @@ -158,14 +167,18 @@ static int devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *v, bool forc return 0; } -static void insert_cookie_in_jar(struct devfs_vnode *dir, struct devfs_cookie *cookie) + +static void +insert_cookie_in_jar(struct devfs_vnode *dir, struct devfs_cookie *cookie) { cookie->u.dir.next = dir->stream.u.dir.jar_head; dir->stream.u.dir.jar_head = cookie; cookie->u.dir.prev = NULL; } -static void remove_cookie_from_jar(struct devfs_vnode *dir, struct devfs_cookie *cookie) + +static void +remove_cookie_from_jar(struct devfs_vnode *dir, struct devfs_cookie *cookie) { if(cookie->u.dir.next) cookie->u.dir.next->u.dir.prev = cookie->u.dir.prev; @@ -177,8 +190,10 @@ static void remove_cookie_from_jar(struct devfs_vnode *dir, struct devfs_cookie cookie->u.dir.prev = cookie->u.dir.next = NULL; } + /* makes sure none of the dircookies point to the vnode passed in */ -static void update_dircookies(struct devfs_vnode *dir, struct devfs_vnode *v) +static void +update_dircookies(struct devfs_vnode *dir, struct devfs_vnode *v) { struct devfs_cookie *cookie; @@ -190,7 +205,8 @@ static void update_dircookies(struct devfs_vnode *dir, struct devfs_vnode *v) } -static struct devfs_vnode *devfs_find_in_dir(struct devfs_vnode *dir, const char *path) +static struct devfs_vnode * +devfs_find_in_dir(struct devfs_vnode *dir, const char *path) { struct devfs_vnode *v; @@ -212,7 +228,9 @@ static struct devfs_vnode *devfs_find_in_dir(struct devfs_vnode *dir, const char return NULL; } -static int devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v) + +static int +devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v) { if(dir->stream.type != STREAM_TYPE_DIR) return EINVAL; @@ -224,7 +242,9 @@ static int devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v) return 0; } -static int devfs_remove_from_dir(struct devfs_vnode *dir, struct devfs_vnode *findit) + +static int +devfs_remove_from_dir(struct devfs_vnode *dir, struct devfs_vnode *findit) { struct devfs_vnode *v; struct devfs_vnode *last_v; @@ -245,7 +265,9 @@ static int devfs_remove_from_dir(struct devfs_vnode *dir, struct devfs_vnode *fi return -1; } -static int devfs_is_dir_empty(struct devfs_vnode *dir) + +static int +devfs_is_dir_empty(struct devfs_vnode *dir) { if(dir->stream.type != STREAM_TYPE_DIR) return false; @@ -253,8 +275,9 @@ static int devfs_is_dir_empty(struct devfs_vnode *dir) } -static int devfs_get_partition_info( struct devfs *fs, struct devfs_vnode *v, - struct devfs_cookie *cookie, void *buf, size_t len) +static int +devfs_get_partition_info( struct devfs *fs, struct devfs_vnode *v, + struct devfs_cookie *cookie, void *buf, size_t len) { devfs_partition_info *info = (devfs_partition_info *)buf; struct devfs_part_map *part_map = v->stream.u.dev.part_map; @@ -362,7 +385,12 @@ err2: return res; } -static int devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *root_vnid) + +// #pragma mark - + + +static int +devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *root_vnid) { struct devfs *fs; struct devfs_vnode *v; @@ -567,13 +595,13 @@ static int devfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_t TRACE(("devfs_open: vnode 0x%x, oflags 0x%x\n", v, oflags)); - if(st != STREAM_TYPE_ANY && st != v->stream.type) { + if (st != STREAM_TYPE_ANY && st != v->stream.type) { err = ERR_VFS_WRONG_STREAM_TYPE; goto err; } cookie = kmalloc(sizeof(struct devfs_cookie)); - if(cookie == NULL) { + if (cookie == NULL) { err = ENOMEM; goto err; } @@ -639,12 +667,16 @@ static int devfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) return 0; } -static int devfs_fsync(fs_cookie _fs, fs_vnode _v) + +static int +devfs_fsync(fs_cookie _fs, fs_vnode _v) { return 0; } -static ssize_t devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) + +static ssize_t +devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) { struct devfs *fs = _fs; struct devfs_vnode *v = _v; @@ -654,45 +686,21 @@ static ssize_t devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void TRACE(("devfs_read: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, len)); - switch(cookie->s->type) { - case STREAM_TYPE_DIR: { - mutex_lock(&fs->lock); - is_locked = true; - - if(cookie->u.dir.ptr == NULL) { - *len = 0; - err = ENOENT; - break; - } - - if((ssize_t)strlen(cookie->u.dir.ptr->name) + 1 > *len) { - err = ENOBUFS; - goto err; - } - - err = user_strcpy(buf, cookie->u.dir.ptr->name); - if(err < 0) - goto err; - - err = strlen(cookie->u.dir.ptr->name) + 1; - - cookie->u.dir.ptr = cookie->u.dir.ptr->dir_next; - break; - } + switch (cookie->s->type) { case STREAM_TYPE_DEVICE: { struct devfs_part_map *part_map = v->stream.u.dev.part_map; - if( part_map ) { + if (part_map) { if( pos < 0 ) pos = 0; - - if( pos > part_map->size ) + + if (pos > part_map->size) return 0; - + *len = min(*len, part_map->size - pos ); pos += part_map->offset; } - + // pass the call through to the device err = v->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buf, len); break; @@ -701,41 +709,44 @@ static ssize_t devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void err = EINVAL; } err: - if(is_locked) + if (is_locked) mutex_unlock(&fs->lock); return err; } -static ssize_t devfs_write(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, const void *buf, - off_t pos, size_t *len) + +static ssize_t +devfs_write(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, const void *buf, + off_t pos, size_t *len) { struct devfs_vnode *v = _v; struct devfs_cookie *cookie = _cookie; TRACE(("devfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, len)); - if(v->stream.type == STREAM_TYPE_DEVICE) { + if (v->stream.type == STREAM_TYPE_DEVICE) { struct devfs_part_map *part_map = v->stream.u.dev.part_map; - - if( part_map ) { - if( pos < 0 ) + + if (part_map) { + if (pos < 0) pos = 0; - - if( pos > part_map->size ) + + if (pos > part_map->size) return 0; *len = min(*len, part_map->size - pos); pos += part_map->offset; } - + return v->stream.u.dev.calls->write(cookie->u.dev.dcookie, pos, buf, len); - } else { - return EROFS; } + return EROFS; } -static int devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) + +static int +devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) { struct devfs *fs = _fs; struct devfs_vnode *v = _v; @@ -777,17 +788,56 @@ static int devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos static int -devfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num) +devfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num) { - // ToDo: implement me! - return B_OK; + struct devfs_cookie *cookie = _cookie; + struct devfs *fs = _fs; + status_t status = 0; + + TRACE(("devfs_read_dir: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, dirent, bufferSize)); + + mutex_lock(&fs->lock); + + if (cookie->u.dir.ptr == NULL) { + *_num = 0; + status = ENOENT; + goto err; + } + + dirent->d_dev = fs->id; + dirent->d_ino = cookie->u.dir.ptr->id; + dirent->d_reclen = strlen(cookie->u.dir.ptr->name); + + if (sizeof(struct dirent) + dirent->d_reclen + 1 > bufferSize) { + status = ENOBUFS; + goto err; + } + + status = user_strcpy(dirent->d_name, cookie->u.dir.ptr->name); + if (status < 0) + goto err; + + cookie->u.dir.ptr = cookie->u.dir.ptr->dir_next; + +err: + mutex_unlock(&fs->lock); + + return status; } static int devfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie) { - // ToDo: me too! + struct devfs *fs = _fs; + struct devfs_vnode *vnode = _vnode; + struct devfs_cookie *cookie = _cookie; + + mutex_lock(&fs->lock); + + cookie->u.dir.ptr = vnode->stream.u.dir.dir_head; + + mutex_unlock(&fs->lock); return B_OK; } @@ -802,20 +852,20 @@ devfs_ioctl(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, ulong op, void *buf TRACE(("devfs_ioctl: vnode 0x%x, cookie 0x%x, op %d, buf 0x%x, len 0x%x\n", _v, _cookie, op, buf, len)); if (v->stream.type == STREAM_TYPE_DEVICE) { - switch( op ) { - case IOCTL_DEVFS_GET_PARTITION_INFO: - return devfs_get_partition_info( fs, v, cookie, buf, len ); - - case IOCTL_DEVFS_SET_PARTITION: - return devfs_set_partition( fs, v, cookie, buf, len ); + switch (op) { + case IOCTL_DEVFS_GET_PARTITION_INFO: + return devfs_get_partition_info( fs, v, cookie, buf, len ); + + case IOCTL_DEVFS_SET_PARTITION: + return devfs_set_partition( fs, v, cookie, buf, len ); } return v->stream.u.dev.calls->control(cookie->u.dev.dcookie, op, buf, len); - } else { - return EINVAL; } + return EINVAL; } + /* static int devfs_canpage(fs_cookie _fs, fs_vnode _v) { @@ -892,12 +942,16 @@ static ssize_t devfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t p } } */ -static int devfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid) + +static int +devfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid) { return EROFS; } -static int devfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) + +static int +devfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) { struct devfs *fs = _fs; struct devfs_vnode *dir = _dir; @@ -930,12 +984,16 @@ err: return res; } -static int devfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _newdir, const char *newname) + +static int +devfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _newdir, const char *newname) { return EROFS; } -static int devfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) + +static int +devfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) { struct devfs_vnode *v = _v; @@ -956,7 +1014,8 @@ static int devfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) } -static int devfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) +static int +devfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) { #if DEVFS_TRACE struct devfs_vnode *v = _v; @@ -967,6 +1026,10 @@ static int devfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_m return EPERM; } + +// #pragma mark - + + static struct fs_calls devfs_calls = { &devfs_mount, &devfs_unmount, @@ -1004,7 +1067,9 @@ static struct fs_calls devfs_calls = { &devfs_wstat, }; -int bootstrap_devfs(void) + +int +bootstrap_devfs(void) { dprintf("bootstrap_devfs: entry\n"); @@ -1012,7 +1077,9 @@ int bootstrap_devfs(void) return vfs_register_filesystem("devfs", &devfs_calls); } -int devfs_publish_device(const char *path, void *ident, device_hooks *calls) + +int +devfs_publish_device(const char *path, void *ident, device_hooks *calls) { int err = 0; int i, last; @@ -1023,7 +1090,7 @@ int devfs_publish_device(const char *path, void *ident, device_hooks *calls) TRACE(("devfs_publish_device: entry path '%s', hooks 0x%x\n", path, calls)); - if(!thedevfs) { + if (!thedevfs) { panic("devfs_publish_device called before devfs mounted\n"); return ERR_GENERAL; } @@ -1056,7 +1123,7 @@ int devfs_publish_device(const char *path, void *ident, device_hooks *calls) // we have a path component v = devfs_find_in_dir(dir, &temp[last]); - if(v) { + if (v) { if(!at_leaf) { // we are not at the leaf of the path, so as long as // this is a dir we're okay @@ -1080,7 +1147,7 @@ int devfs_publish_device(const char *path, void *ident, device_hooks *calls) } // set up the new vnode - if(at_leaf) { + if (at_leaf) { // this is the last component v->stream.type = STREAM_TYPE_DEVICE; v->stream.u.dev.ident = ident; @@ -1096,7 +1163,7 @@ int devfs_publish_device(const char *path, void *ident, device_hooks *calls) devfs_insert_in_dir(dir, v); - if(at_leaf) + if (at_leaf) break; last = i; dir = v; @@ -1106,3 +1173,4 @@ err: mutex_unlock(&thedevfs->lock); return err; } + diff --git a/src/kernel/core/fs/rootfs.c b/src/kernel/core/fs/rootfs.c index 733a2a9c88..6bd6505bbd 100755 --- a/src/kernel/core/fs/rootfs.c +++ b/src/kernel/core/fs/rootfs.c @@ -61,7 +61,10 @@ struct rootfs_cookie { }; #define ROOTFS_HASH_SIZE 16 -static unsigned int rootfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) + + +static unsigned int +rootfs_vnode_hash_func(void *_v, const void *_key, unsigned int range) { struct rootfs_vnode *v = _v; const vnode_id *key = _key; @@ -72,7 +75,9 @@ static unsigned int rootfs_vnode_hash_func(void *_v, const void *_key, unsigned return (*key) % range; } -static int rootfs_vnode_compare_func(void *_v, const void *_key) + +static int +rootfs_vnode_compare_func(void *_v, const void *_key) { struct rootfs_vnode *v = _v; const vnode_id *key = _key; @@ -83,12 +88,14 @@ static int rootfs_vnode_compare_func(void *_v, const void *_key) return -1; } -static struct rootfs_vnode *rootfs_create_vnode(struct rootfs *fs) + +static struct rootfs_vnode * +rootfs_create_vnode(struct rootfs *fs) { struct rootfs_vnode *v; v = kmalloc(sizeof(struct rootfs_vnode)); - if(v == NULL) + if (v == NULL) return NULL; memset(v, 0, sizeof(struct rootfs_vnode)); @@ -97,13 +104,14 @@ static struct rootfs_vnode *rootfs_create_vnode(struct rootfs *fs) return v; } -static int rootfs_delete_vnode(struct rootfs *fs, struct rootfs_vnode *v, bool force_delete) + +static int +rootfs_delete_vnode(struct rootfs *fs, struct rootfs_vnode *v, bool force_delete) { // cant delete it if it's in a directory or is a directory // and has children - if(!force_delete && (v->stream.dir.dir_head != NULL || v->dir_next != NULL)) { + if (!force_delete && (v->stream.dir.dir_head != NULL || v->dir_next != NULL)) return ERR_NOT_ALLOWED; - } // remove it from the global hash table hash_remove(fs->vnode_list_hash, v); @@ -191,12 +199,19 @@ static int rootfs_remove_from_dir(struct rootfs_vnode *dir, struct rootfs_vnode return -1; } -static int rootfs_is_dir_empty(struct rootfs_vnode *dir) + +static int +rootfs_is_dir_empty(struct rootfs_vnode *dir) { return !dir->stream.dir.dir_head; } -static int rootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id *root_vnid) + +// #pragma mark - + + +static int +rootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id *root_vnid) { struct rootfs *fs; struct rootfs_vnode *v; @@ -261,7 +276,9 @@ err: return err; } -static int rootfs_unmount(fs_cookie _fs) + +static int +rootfs_unmount(fs_cookie _fs) { struct rootfs *fs = (struct rootfs *)_fs; struct rootfs_vnode *v; @@ -286,14 +303,18 @@ static int rootfs_unmount(fs_cookie _fs) return 0; } -static int rootfs_sync(fs_cookie fs) + +static int +rootfs_sync(fs_cookie fs) { TRACE(("rootfs_sync: entry\n")); return 0; } -static int rootfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id) + +static int +rootfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id) { struct rootfs *fs = (struct rootfs *)_fs; struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir; @@ -327,7 +348,9 @@ err: return err; } -static int rootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) + +static int +rootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) { struct rootfs *fs = (struct rootfs *)_fs; @@ -349,7 +372,9 @@ static int rootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) return ERR_NOT_FOUND; } -static int rootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) + +static int +rootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) { #if ROOTFS_TRACE struct rootfs_vnode *v = (struct rootfs_vnode *)_v; @@ -359,7 +384,9 @@ static int rootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) return 0; // whatever } -static int rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) + +static int +rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) { struct rootfs *fs = (struct rootfs *)_fs; struct rootfs_vnode *v = (struct rootfs_vnode *)_v; @@ -385,7 +412,9 @@ static int rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) return err; } -static int rootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) + +static int +rootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) { struct rootfs *fs = (struct rootfs *)_fs; struct rootfs_vnode *v = (struct rootfs_vnode *)_v; @@ -394,13 +423,13 @@ static int rootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_ TRACE(("rootfs_open: vnode 0x%x, stream_type %d, oflags 0x%x\n", v, st, oflags)); - if(st != STREAM_TYPE_ANY && st != STREAM_TYPE_DIR) { + if (st != STREAM_TYPE_ANY && st != STREAM_TYPE_DIR) { err = ERR_VFS_WRONG_STREAM_TYPE; goto err; } cookie = kmalloc(sizeof(struct rootfs_cookie)); - if(cookie == NULL) { + if (cookie == NULL) { err = ERR_NO_MEMORY; goto err; } @@ -419,7 +448,9 @@ err: return err; } -static int rootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) + +static int +rootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) { #if ROOTFS_TRACE struct rootfs_vnode *v = _v; @@ -430,7 +461,9 @@ static int rootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) return 0; } -static int rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) + +static int +rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) { struct rootfs_cookie *cookie = _cookie; #if ROOTFS_TRACE @@ -444,57 +477,32 @@ static int rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) return 0; } -static int rootfs_fsync(fs_cookie _fs, fs_vnode _v) + +static int +rootfs_fsync(fs_cookie _fs, fs_vnode _v) { return 0; } -static ssize_t rootfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) + +static ssize_t +rootfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) { - struct rootfs *fs = _fs; -#if ROOTFS_TRACE - struct rootfs_vnode *v = _v; -#endif - struct rootfs_cookie *cookie = _cookie; - int err = 0; - - TRACE(("rootfs_read: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, *len)); - - mutex_lock(&fs->lock); - - if(cookie->ptr == NULL) { - *len = 0; - err = 0; - goto err; - } - - if((ssize_t)strlen(cookie->ptr->name) + 1 > *len) { - err = ERR_VFS_INSUFFICIENT_BUF; - goto err; - } - - err = user_strcpy(buf, cookie->ptr->name); - if(err < 0) - goto err; - - *len = strlen(cookie->ptr->name) + 1; - - cookie->ptr = cookie->ptr->dir_next; - -err: - mutex_unlock(&fs->lock); - - return err; + return EINVAL; } -static ssize_t rootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_t pos, size_t *len) + +static ssize_t +rootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_t pos, size_t *len) { TRACE(("rootfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, *len)); return ERR_NOT_ALLOWED; } -static int rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) + +static int +rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) { struct rootfs *fs = _fs; struct rootfs_vnode *v = _v; @@ -528,17 +536,56 @@ static int rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t po static int -rootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num) +rootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num) { - // ToDo: implement me! - return B_OK; + struct rootfs_cookie *cookie = _cookie; + struct rootfs *fs = _fs; + status_t status = 0; + + TRACE(("rootfs_read_dir: vnode 0x%x, cookie 0x%x, buffer = 0x%x, bufferSize = 0x%x\n", v, cookie, dirent, bufferSize)); + + mutex_lock(&fs->lock); + + if (cookie->ptr == NULL) { + *_num = 0; + status = B_OK; + goto err; + } + + dirent->d_dev = fs->id; + dirent->d_ino = cookie->ptr->id; + dirent->d_reclen = strlen(cookie->ptr->name); + + if (sizeof(struct dirent) + dirent->d_reclen + 1 > bufferSize) { + status = ERR_VFS_INSUFFICIENT_BUF; + goto err; + } + + status = user_strcpy(dirent->d_name, cookie->ptr->name); + if (status < 0) + goto err; + + cookie->ptr = cookie->ptr->dir_next; + +err: + mutex_unlock(&fs->lock); + + return status; } static int rootfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie) { - // ToDo: me too! + struct rootfs *fs = _fs; + struct rootfs_vnode *vnode = _vnode; + struct rootfs_cookie *cookie = _cookie; + + mutex_lock(&fs->lock); + + cookie->ptr = vnode->stream.dir.dir_head; + + mutex_unlock(&fs->lock); return B_OK; } @@ -756,7 +803,9 @@ static int rootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) return 0; } -static int rootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) + +static int +rootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) { #if ROOTFS_TRACE struct rootfs *fs = _fs; @@ -768,6 +817,10 @@ static int rootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_ return EINVAL; } + +// #pragma mark - + + static struct fs_calls rootfs_calls = { &rootfs_mount, &rootfs_unmount, @@ -805,7 +858,9 @@ static struct fs_calls rootfs_calls = { &rootfs_wstat, }; -int bootstrap_rootfs(void) + +int +bootstrap_rootfs(void) { dprintf("bootstrap_rootfs: entry\n");