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:
+168
-73
@@ -80,19 +80,25 @@ struct bootfs_cookie {
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define BOOTFS_HASH_SIZE 16
|
#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;
|
struct bootfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
const vnode_id *key = _key;
|
||||||
|
|
||||||
if(v != NULL)
|
if (v != NULL)
|
||||||
return v->id % range;
|
return v->id % range;
|
||||||
else
|
else
|
||||||
return (*key) % range;
|
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;
|
struct bootfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
const vnode_id *key = _key;
|
||||||
@@ -103,7 +109,9 @@ static int bootfs_vnode_compare_func(void *_v, const void *_key)
|
|||||||
return -1;
|
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;
|
struct bootfs_vnode *v;
|
||||||
|
|
||||||
@@ -123,7 +131,9 @@ static struct bootfs_vnode *bootfs_create_vnode(struct bootfs *fs, const char *n
|
|||||||
return v;
|
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
|
// cant delete it if it's in a directory or is a directory
|
||||||
// and has children
|
// and has children
|
||||||
@@ -141,14 +151,18 @@ static int bootfs_delete_vnode(struct bootfs *fs, struct bootfs_vnode *v, bool f
|
|||||||
return 0;
|
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;
|
cookie->u.dir.next = dir->stream.u.dir.jar_head;
|
||||||
dir->stream.u.dir.jar_head = cookie;
|
dir->stream.u.dir.jar_head = cookie;
|
||||||
cookie->u.dir.prev = NULL;
|
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)
|
if(cookie->u.dir.next)
|
||||||
cookie->u.dir.next->u.dir.prev = cookie->u.dir.prev;
|
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;
|
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;
|
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;
|
struct bootfs_vnode *v;
|
||||||
|
|
||||||
@@ -195,7 +213,9 @@ static struct bootfs_vnode *bootfs_find_in_dir(struct bootfs_vnode *dir, const c
|
|||||||
return NULL;
|
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)
|
if(dir->stream.type != STREAM_TYPE_DIR)
|
||||||
return ERR_INVALID_ARGS;
|
return ERR_INVALID_ARGS;
|
||||||
@@ -207,7 +227,9 @@ static int bootfs_insert_in_dir(struct bootfs_vnode *dir, struct bootfs_vnode *v
|
|||||||
return 0;
|
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 *v;
|
||||||
struct bootfs_vnode *last_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;
|
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)
|
if(dir->stream.type != STREAM_TYPE_DIR)
|
||||||
return false;
|
return false;
|
||||||
return !dir->stream.u.dir.dir_head;
|
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
|
/** Creates a path of vnodes up to the last part of the passed in path.
|
||||||
// a pointer to the leaf of the path.
|
* returns the vnode the last segment should be a part of and
|
||||||
// clobbers the path string passed in
|
* a pointer to the leaf of the path.
|
||||||
static struct bootfs_vnode *bootfs_create_path(struct bootfs *fs, char *path, struct bootfs_vnode *base, char **path_leaf)
|
* 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;
|
struct bootfs_vnode *v;
|
||||||
char *temp;
|
char *temp;
|
||||||
@@ -303,7 +331,9 @@ static struct bootfs_vnode *bootfs_create_path(struct bootfs *fs, char *path, st
|
|||||||
return base;
|
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;
|
int i;
|
||||||
boot_entry *entry;
|
boot_entry *entry;
|
||||||
@@ -314,7 +344,7 @@ static int bootfs_create_vnode_tree(struct bootfs *fs, struct bootfs_vnode *root
|
|||||||
char *leaf;
|
char *leaf;
|
||||||
|
|
||||||
entry = (boot_entry *)bootdir;
|
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) {
|
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);
|
strncpy(path, entry[i].be_name, SYS_MAX_PATH_LEN-1);
|
||||||
path[SYS_MAX_PATH_LEN-1] = '\0';
|
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;
|
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 *fs;
|
||||||
struct bootfs_vnode *v;
|
struct bootfs_vnode *v;
|
||||||
@@ -413,7 +448,9 @@ err:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bootfs_unmount(fs_cookie _fs)
|
|
||||||
|
static int
|
||||||
|
bootfs_unmount(fs_cookie _fs)
|
||||||
{
|
{
|
||||||
struct bootfs *fs = _fs;
|
struct bootfs *fs = _fs;
|
||||||
struct bootfs_vnode *v;
|
struct bootfs_vnode *v;
|
||||||
@@ -435,14 +472,18 @@ static int bootfs_unmount(fs_cookie _fs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bootfs_sync(fs_cookie fs)
|
|
||||||
|
static int
|
||||||
|
bootfs_sync(fs_cookie fs)
|
||||||
{
|
{
|
||||||
TRACE(("bootfs_sync: entry\n"));
|
TRACE(("bootfs_sync: entry\n"));
|
||||||
|
|
||||||
return 0;
|
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 *fs = (struct bootfs *)_fs;
|
||||||
struct bootfs_vnode *dir = (struct bootfs_vnode *)_dir;
|
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));
|
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;
|
return ERR_VFS_NOT_DIR;
|
||||||
|
|
||||||
mutex_lock(&fs->lock);
|
mutex_lock(&fs->lock);
|
||||||
|
|
||||||
// look it up
|
// look it up
|
||||||
v = bootfs_find_in_dir(dir, name);
|
v = bootfs_find_in_dir(dir, name);
|
||||||
if(!v) {
|
if (!v) {
|
||||||
err = ENOENT;
|
err = ENOENT;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -479,7 +520,9 @@ err:
|
|||||||
return 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;
|
struct bootfs *fs = (struct bootfs *)_fs;
|
||||||
int err;
|
int err;
|
||||||
@@ -502,7 +545,9 @@ static int bootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
|
|||||||
return ENOENT;
|
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;
|
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
|
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 *fs = (struct bootfs *)_fs;
|
||||||
struct bootfs_vnode *v = (struct bootfs_vnode *)_v;
|
struct bootfs_vnode *v = (struct bootfs_vnode *)_v;
|
||||||
@@ -539,14 +586,16 @@ err:
|
|||||||
return 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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
struct bootfs_vnode *v = _v;
|
||||||
struct bootfs_cookie *cookie;
|
struct bootfs_cookie *cookie;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
dprintf("bootfs_open: \n");
|
|
||||||
TRACE(("bootfs_open: vnode 0x%x, stream_type %d, oflags 0x%x\n", v, st, oflags));
|
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) {
|
if(st != STREAM_TYPE_ANY && st != v->stream.type) {
|
||||||
@@ -555,7 +604,7 @@ dprintf("bootfs_open: \n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
cookie = kmalloc(sizeof(struct bootfs_cookie));
|
cookie = kmalloc(sizeof(struct bootfs_cookie));
|
||||||
if(cookie == NULL) {
|
if (cookie == NULL) {
|
||||||
err = ERR_NO_MEMORY;
|
err = ERR_NO_MEMORY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -583,7 +632,9 @@ err:
|
|||||||
return 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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
struct bootfs_vnode *v = _v;
|
||||||
@@ -594,7 +645,9 @@ static int bootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
|
|||||||
return 0;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
struct bootfs_vnode *v = _v;
|
||||||
@@ -608,12 +661,16 @@ static int bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bootfs_fsync(fs_cookie _fs, fs_vnode _v)
|
|
||||||
|
static int
|
||||||
|
bootfs_fsync(fs_cookie _fs, fs_vnode _v)
|
||||||
{
|
{
|
||||||
return 0;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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);
|
mutex_lock(&fs->lock);
|
||||||
|
|
||||||
switch(cookie->s->type) {
|
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:
|
case STREAM_TYPE_FILE:
|
||||||
if(*len <= 0) {
|
if(*len <= 0) {
|
||||||
err = 0;
|
err = 0;
|
||||||
@@ -681,14 +717,18 @@ err:
|
|||||||
return 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));
|
TRACE(("bootfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, *len));
|
||||||
|
|
||||||
return EROFS;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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
|
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!
|
struct bootfs_cookie *cookie = _cookie;
|
||||||
return B_OK;
|
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
|
static int
|
||||||
bootfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,13 +866,15 @@ bootfs_canpage(fs_cookie _fs, fs_vnode _v)
|
|||||||
|
|
||||||
TRACE(("bootfs_canpage: vnode 0x%x\n", 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;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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));
|
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++) {
|
for (i = 0; i < vecs->num; i++) {
|
||||||
if(pos >= v->stream.u.file.len) {
|
if (pos >= v->stream.u.file.len) {
|
||||||
memset(vecs->vec[i].iov_base, 0, vecs->vec[i].iov_len);
|
memset(vecs->vec[i].iov_base, 0, vecs->vec[i].iov_len);
|
||||||
pos += vecs->vec[i].iov_len;
|
pos += vecs->vec[i].iov_len;
|
||||||
} else {
|
} else {
|
||||||
@@ -823,7 +903,9 @@ static ssize_t bootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t p
|
|||||||
return EPERM;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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;
|
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;
|
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;
|
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;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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 *fs = _fs;
|
||||||
struct bootfs_vnode *v = _v;
|
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;
|
return ERR_VFS_READONLY_FS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static struct fs_calls bootfs_calls = {
|
static struct fs_calls bootfs_calls = {
|
||||||
&bootfs_mount,
|
&bootfs_mount,
|
||||||
&bootfs_unmount,
|
&bootfs_unmount,
|
||||||
|
|||||||
+152
-84
@@ -94,7 +94,10 @@ struct devfs_cookie {
|
|||||||
static struct devfs *thedevfs = NULL;
|
static struct devfs *thedevfs = NULL;
|
||||||
|
|
||||||
#define BOOTFS_HASH_SIZE 16
|
#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;
|
struct devfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
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;
|
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;
|
struct devfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
const vnode_id *key = _key;
|
||||||
@@ -116,7 +121,9 @@ static int devfs_vnode_compare_func(void *_v, const void *_key)
|
|||||||
return -1;
|
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;
|
struct devfs_vnode *v;
|
||||||
|
|
||||||
@@ -136,7 +143,9 @@ static struct devfs_vnode *devfs_create_vnode(struct devfs *fs, const char *name
|
|||||||
return v;
|
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
|
// cant delete it if it's in a directory or is a directory
|
||||||
// and has children
|
// and has children
|
||||||
@@ -158,14 +167,18 @@ static int devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *v, bool forc
|
|||||||
return 0;
|
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;
|
cookie->u.dir.next = dir->stream.u.dir.jar_head;
|
||||||
dir->stream.u.dir.jar_head = cookie;
|
dir->stream.u.dir.jar_head = cookie;
|
||||||
cookie->u.dir.prev = NULL;
|
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)
|
if(cookie->u.dir.next)
|
||||||
cookie->u.dir.next->u.dir.prev = cookie->u.dir.prev;
|
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;
|
cookie->u.dir.prev = cookie->u.dir.next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* makes sure none of the dircookies point to the vnode passed in */
|
/* 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;
|
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;
|
struct devfs_vnode *v;
|
||||||
|
|
||||||
@@ -212,7 +228,9 @@ static struct devfs_vnode *devfs_find_in_dir(struct devfs_vnode *dir, const char
|
|||||||
return NULL;
|
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)
|
if(dir->stream.type != STREAM_TYPE_DIR)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@@ -224,7 +242,9 @@ static int devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v)
|
|||||||
return 0;
|
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 *v;
|
||||||
struct devfs_vnode *last_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;
|
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)
|
if(dir->stream.type != STREAM_TYPE_DIR)
|
||||||
return false;
|
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,
|
static int
|
||||||
struct devfs_cookie *cookie, void *buf, size_t len)
|
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;
|
devfs_partition_info *info = (devfs_partition_info *)buf;
|
||||||
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
|
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
|
||||||
@@ -362,7 +385,12 @@ err2:
|
|||||||
return res;
|
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 *fs;
|
||||||
struct devfs_vnode *v;
|
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));
|
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;
|
err = ERR_VFS_WRONG_STREAM_TYPE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = kmalloc(sizeof(struct devfs_cookie));
|
cookie = kmalloc(sizeof(struct devfs_cookie));
|
||||||
if(cookie == NULL) {
|
if (cookie == NULL) {
|
||||||
err = ENOMEM;
|
err = ENOMEM;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -639,12 +667,16 @@ static int devfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devfs_fsync(fs_cookie _fs, fs_vnode _v)
|
|
||||||
|
static int
|
||||||
|
devfs_fsync(fs_cookie _fs, fs_vnode _v)
|
||||||
{
|
{
|
||||||
return 0;
|
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 *fs = _fs;
|
||||||
struct devfs_vnode *v = _v;
|
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));
|
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) {
|
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;
|
|
||||||
}
|
|
||||||
case STREAM_TYPE_DEVICE: {
|
case STREAM_TYPE_DEVICE: {
|
||||||
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
|
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
|
||||||
|
|
||||||
if( part_map ) {
|
if (part_map) {
|
||||||
if( pos < 0 )
|
if( pos < 0 )
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
|
||||||
if( pos > part_map->size )
|
if (pos > part_map->size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*len = min(*len, part_map->size - pos );
|
*len = min(*len, part_map->size - pos );
|
||||||
pos += part_map->offset;
|
pos += part_map->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass the call through to the device
|
// pass the call through to the device
|
||||||
err = v->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buf, len);
|
err = v->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buf, len);
|
||||||
break;
|
break;
|
||||||
@@ -701,41 +709,44 @@ static ssize_t devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void
|
|||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
if(is_locked)
|
if (is_locked)
|
||||||
mutex_unlock(&fs->lock);
|
mutex_unlock(&fs->lock);
|
||||||
|
|
||||||
return err;
|
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_vnode *v = _v;
|
||||||
struct devfs_cookie *cookie = _cookie;
|
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));
|
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;
|
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
|
||||||
|
|
||||||
if( part_map ) {
|
if (part_map) {
|
||||||
if( pos < 0 )
|
if (pos < 0)
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
|
||||||
if( pos > part_map->size )
|
if (pos > part_map->size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*len = min(*len, part_map->size - pos);
|
*len = min(*len, part_map->size - pos);
|
||||||
pos += part_map->offset;
|
pos += part_map->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v->stream.u.dev.calls->write(cookie->u.dev.dcookie, pos, buf, len);
|
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 *fs = _fs;
|
||||||
struct devfs_vnode *v = _v;
|
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
|
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!
|
struct devfs_cookie *cookie = _cookie;
|
||||||
return B_OK;
|
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
|
static int
|
||||||
devfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie)
|
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;
|
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));
|
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) {
|
if (v->stream.type == STREAM_TYPE_DEVICE) {
|
||||||
switch( op ) {
|
switch (op) {
|
||||||
case IOCTL_DEVFS_GET_PARTITION_INFO:
|
case IOCTL_DEVFS_GET_PARTITION_INFO:
|
||||||
return devfs_get_partition_info( fs, v, cookie, buf, len );
|
return devfs_get_partition_info( fs, v, cookie, buf, len );
|
||||||
|
|
||||||
case IOCTL_DEVFS_SET_PARTITION:
|
case IOCTL_DEVFS_SET_PARTITION:
|
||||||
return devfs_set_partition( fs, v, cookie, buf, len );
|
return devfs_set_partition( fs, v, cookie, buf, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
return v->stream.u.dev.calls->control(cookie->u.dev.dcookie, op, 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)
|
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;
|
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 *fs = _fs;
|
||||||
struct devfs_vnode *dir = _dir;
|
struct devfs_vnode *dir = _dir;
|
||||||
@@ -930,12 +984,16 @@ err:
|
|||||||
return res;
|
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;
|
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;
|
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
|
#if DEVFS_TRACE
|
||||||
struct devfs_vnode *v = _v;
|
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;
|
return EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static struct fs_calls devfs_calls = {
|
static struct fs_calls devfs_calls = {
|
||||||
&devfs_mount,
|
&devfs_mount,
|
||||||
&devfs_unmount,
|
&devfs_unmount,
|
||||||
@@ -1004,7 +1067,9 @@ static struct fs_calls devfs_calls = {
|
|||||||
&devfs_wstat,
|
&devfs_wstat,
|
||||||
};
|
};
|
||||||
|
|
||||||
int bootstrap_devfs(void)
|
|
||||||
|
int
|
||||||
|
bootstrap_devfs(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
dprintf("bootstrap_devfs: entry\n");
|
dprintf("bootstrap_devfs: entry\n");
|
||||||
@@ -1012,7 +1077,9 @@ int bootstrap_devfs(void)
|
|||||||
return vfs_register_filesystem("devfs", &devfs_calls);
|
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 err = 0;
|
||||||
int i, last;
|
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));
|
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");
|
panic("devfs_publish_device called before devfs mounted\n");
|
||||||
return ERR_GENERAL;
|
return ERR_GENERAL;
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1123,7 @@ int devfs_publish_device(const char *path, void *ident, device_hooks *calls)
|
|||||||
|
|
||||||
// we have a path component
|
// we have a path component
|
||||||
v = devfs_find_in_dir(dir, &temp[last]);
|
v = devfs_find_in_dir(dir, &temp[last]);
|
||||||
if(v) {
|
if (v) {
|
||||||
if(!at_leaf) {
|
if(!at_leaf) {
|
||||||
// we are not at the leaf of the path, so as long as
|
// we are not at the leaf of the path, so as long as
|
||||||
// this is a dir we're okay
|
// 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
|
// set up the new vnode
|
||||||
if(at_leaf) {
|
if (at_leaf) {
|
||||||
// this is the last component
|
// this is the last component
|
||||||
v->stream.type = STREAM_TYPE_DEVICE;
|
v->stream.type = STREAM_TYPE_DEVICE;
|
||||||
v->stream.u.dev.ident = ident;
|
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);
|
devfs_insert_in_dir(dir, v);
|
||||||
|
|
||||||
if(at_leaf)
|
if (at_leaf)
|
||||||
break;
|
break;
|
||||||
last = i;
|
last = i;
|
||||||
dir = v;
|
dir = v;
|
||||||
@@ -1106,3 +1173,4 @@ err:
|
|||||||
mutex_unlock(&thedevfs->lock);
|
mutex_unlock(&thedevfs->lock);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+119
-64
@@ -61,7 +61,10 @@ struct rootfs_cookie {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define ROOTFS_HASH_SIZE 16
|
#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;
|
struct rootfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
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;
|
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;
|
struct rootfs_vnode *v = _v;
|
||||||
const vnode_id *key = _key;
|
const vnode_id *key = _key;
|
||||||
@@ -83,12 +88,14 @@ static int rootfs_vnode_compare_func(void *_v, const void *_key)
|
|||||||
return -1;
|
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;
|
struct rootfs_vnode *v;
|
||||||
|
|
||||||
v = kmalloc(sizeof(struct rootfs_vnode));
|
v = kmalloc(sizeof(struct rootfs_vnode));
|
||||||
if(v == NULL)
|
if (v == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(v, 0, sizeof(struct rootfs_vnode));
|
memset(v, 0, sizeof(struct rootfs_vnode));
|
||||||
@@ -97,13 +104,14 @@ static struct rootfs_vnode *rootfs_create_vnode(struct rootfs *fs)
|
|||||||
return v;
|
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
|
// cant delete it if it's in a directory or is a directory
|
||||||
// and has children
|
// 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;
|
return ERR_NOT_ALLOWED;
|
||||||
}
|
|
||||||
|
|
||||||
// remove it from the global hash table
|
// remove it from the global hash table
|
||||||
hash_remove(fs->vnode_list_hash, v);
|
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;
|
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;
|
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 *fs;
|
||||||
struct rootfs_vnode *v;
|
struct rootfs_vnode *v;
|
||||||
@@ -261,7 +276,9 @@ err:
|
|||||||
return 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 *fs = (struct rootfs *)_fs;
|
||||||
struct rootfs_vnode *v;
|
struct rootfs_vnode *v;
|
||||||
@@ -286,14 +303,18 @@ static int rootfs_unmount(fs_cookie _fs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rootfs_sync(fs_cookie fs)
|
|
||||||
|
static int
|
||||||
|
rootfs_sync(fs_cookie fs)
|
||||||
{
|
{
|
||||||
TRACE(("rootfs_sync: entry\n"));
|
TRACE(("rootfs_sync: entry\n"));
|
||||||
|
|
||||||
return 0;
|
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 *fs = (struct rootfs *)_fs;
|
||||||
struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir;
|
struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir;
|
||||||
@@ -327,7 +348,9 @@ err:
|
|||||||
return 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;
|
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;
|
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
|
#if ROOTFS_TRACE
|
||||||
struct rootfs_vnode *v = (struct rootfs_vnode *)_v;
|
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
|
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 *fs = (struct rootfs *)_fs;
|
||||||
struct rootfs_vnode *v = (struct rootfs_vnode *)_v;
|
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;
|
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 *fs = (struct rootfs *)_fs;
|
||||||
struct rootfs_vnode *v = (struct rootfs_vnode *)_v;
|
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));
|
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;
|
err = ERR_VFS_WRONG_STREAM_TYPE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = kmalloc(sizeof(struct rootfs_cookie));
|
cookie = kmalloc(sizeof(struct rootfs_cookie));
|
||||||
if(cookie == NULL) {
|
if (cookie == NULL) {
|
||||||
err = ERR_NO_MEMORY;
|
err = ERR_NO_MEMORY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -419,7 +448,9 @@ err:
|
|||||||
return 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
|
#if ROOTFS_TRACE
|
||||||
struct rootfs_vnode *v = _v;
|
struct rootfs_vnode *v = _v;
|
||||||
@@ -430,7 +461,9 @@ static int rootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
|
|||||||
return 0;
|
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;
|
struct rootfs_cookie *cookie = _cookie;
|
||||||
#if ROOTFS_TRACE
|
#if ROOTFS_TRACE
|
||||||
@@ -444,57 +477,32 @@ static int rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rootfs_fsync(fs_cookie _fs, fs_vnode _v)
|
|
||||||
|
static int
|
||||||
|
rootfs_fsync(fs_cookie _fs, fs_vnode _v)
|
||||||
{
|
{
|
||||||
return 0;
|
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;
|
return EINVAL;
|
||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
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;
|
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 *fs = _fs;
|
||||||
struct rootfs_vnode *v = _v;
|
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
|
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!
|
struct rootfs_cookie *cookie = _cookie;
|
||||||
return B_OK;
|
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
|
static int
|
||||||
rootfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +803,9 @@ static int rootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
|
|||||||
return 0;
|
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
|
#if ROOTFS_TRACE
|
||||||
struct rootfs *fs = _fs;
|
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;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static struct fs_calls rootfs_calls = {
|
static struct fs_calls rootfs_calls = {
|
||||||
&rootfs_mount,
|
&rootfs_mount,
|
||||||
&rootfs_unmount,
|
&rootfs_unmount,
|
||||||
@@ -805,7 +858,9 @@ static struct fs_calls rootfs_calls = {
|
|||||||
&rootfs_wstat,
|
&rootfs_wstat,
|
||||||
};
|
};
|
||||||
|
|
||||||
int bootstrap_rootfs(void)
|
|
||||||
|
int
|
||||||
|
bootstrap_rootfs(void)
|
||||||
{
|
{
|
||||||
dprintf("bootstrap_rootfs: entry\n");
|
dprintf("bootstrap_rootfs: entry\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user