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:
parent
b18756ad83
commit
07fefdf493
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue