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
This commit is contained in:
Axel Dörfler 2002-07-10 21:55:33 +00:00
parent b18756ad83
commit 07fefdf493
3 changed files with 439 additions and 221 deletions

View File

@ -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; i<BOOTDIR_MAX_ENTRIES; i++) {
for (i = 0; i < BOOTDIR_MAX_ENTRIES; i++) {
if(entry[i].be_type != BE_TYPE_NONE && entry[i].be_type != BE_TYPE_DIRECTORY) {
strncpy(path, entry[i].be_name, SYS_MAX_PATH_LEN-1);
path[SYS_MAX_PATH_LEN-1] = '\0';
@ -345,7 +375,12 @@ static int bootfs_create_vnode_tree(struct bootfs *fs, struct bootfs_vnode *root
return 0;
}
static int bootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id *root_vnid)
// #pragma mark -
static int
bootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id *root_vnid)
{
struct bootfs *fs;
struct bootfs_vnode *v;
@ -413,7 +448,9 @@ err:
return err;
}
static int bootfs_unmount(fs_cookie _fs)
static int
bootfs_unmount(fs_cookie _fs)
{
struct bootfs *fs = _fs;
struct bootfs_vnode *v;
@ -435,14 +472,18 @@ static int bootfs_unmount(fs_cookie _fs)
return 0;
}
static int bootfs_sync(fs_cookie fs)
static int
bootfs_sync(fs_cookie fs)
{
TRACE(("bootfs_sync: entry\n"));
return 0;
}
static int bootfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id)
static int
bootfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id)
{
struct bootfs *fs = (struct bootfs *)_fs;
struct bootfs_vnode *dir = (struct bootfs_vnode *)_dir;
@ -452,14 +493,14 @@ static int bootfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_i
TRACE(("bootfs_lookup: entry dir 0x%x, name '%s'\n", dir, name));
if(dir->stream.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; i<vecs->num; 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,

View File

@ -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;
}

View File

@ -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");