Updated VFS, more POSIX like open/create, has now extra open_dir/create_dir

functions. sys_create() now returns an fd of the open file (some code in the
kernel shell already depend on this).
Moved the seek functions to fd.c.
Updated all internal file systems to a new and updated API.
vfs.c is not cleaned up well, but also has some bug fixes.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@208 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2002-07-14 05:13:20 +00:00
parent eba8b6cfb9
commit ea536d2ba4
4 changed files with 800 additions and 603 deletions
+82 -60
View File
@@ -589,48 +589,34 @@ err:
static int static int
bootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) bootfs_create(fs_cookie _fs, fs_vnode _dir, file_cookie *_cookie, vnode_id *new_vnid, const char *name, int omode, int perms)
{
return EROFS;
}
static int
bootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, int oflags)
{ {
struct bootfs *fs = _fs; struct bootfs *fs = _fs;
struct bootfs_vnode *v = _v; struct bootfs_vnode *vnode = _v;
struct bootfs_cookie *cookie; struct bootfs_cookie *cookie;
int err = 0;
int start = 0;
TRACE(("bootfs_open: vnode 0x%x, stream_type %d, oflags 0x%x\n", v, st, oflags)); TRACE(("bootfs_open: vnode 0x%x, oflags 0x%x\n", vnode, oflags));
if(st != STREAM_TYPE_ANY && st != v->stream.type) {
err = ERR_VFS_WRONG_STREAM_TYPE;
goto err;
}
cookie = kmalloc(sizeof(struct bootfs_cookie)); cookie = kmalloc(sizeof(struct bootfs_cookie));
if (cookie == NULL) { if (cookie == NULL)
err = ENOMEM; return ENOMEM;
goto err;
}
mutex_lock(&fs->lock); mutex_lock(&fs->lock);
cookie->s = &v->stream; cookie->s = &vnode->stream;
switch(v->stream.type) { cookie->u.file.pos = 0;
case STREAM_TYPE_DIR:
cookie->u.dir.ptr = v->stream.u.dir.dir_head;
break;
case STREAM_TYPE_FILE:
cookie->u.file.pos = 0;
break;
default:
err = ERR_VFS_WRONG_STREAM_TYPE;
kfree(cookie);
}
*_cookie = cookie; *_cookie = cookie;
err1:
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
err:
return err; return B_OK;
} }
@@ -648,7 +634,7 @@ bootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
static int static int
bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) bootfs_free_cookie(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;
@@ -656,7 +642,7 @@ bootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
TRACE(("bootfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v, cookie)); TRACE(("bootfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v, cookie));
if(cookie) if (cookie)
kfree(cookie); kfree(cookie);
return 0; return 0;
@@ -798,6 +784,42 @@ bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
} }
static int
bootfs_create_dir(fs_cookie _fs, fs_vnode _dir, const char *name, int perms, vnode_id *new_vnid)
{
return EROFS;
}
static int
bootfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
{
struct bootfs *fs = _fs;
struct bootfs_vnode *vnode = _v;
struct bootfs_cookie *cookie;
int status = 0;
TRACE(("bootfs_open_dir: vnode 0x%x\n", vnode));
if (vnode->stream.type != STREAM_TYPE_DIR)
return EINVAL;
cookie = kmalloc(sizeof(struct bootfs_cookie));
if (cookie == NULL)
return ENOMEM;
mutex_lock(&fs->lock);
cookie->s = &vnode->stream;
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
*_cookie = cookie;
mutex_unlock(&fs->lock);
return status;
}
static int static int
bootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, 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)
{ {
@@ -917,13 +939,6 @@ bootfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos)
} }
static int
bootfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid)
{
return EROFS;
}
static int static int
bootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) bootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
{ {
@@ -939,12 +954,12 @@ bootfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _ne
static int static int
bootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) bootfs_read_stat(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;
int err = 0; int err = 0;
//dprintf("bootfs_rstat:\n");
TRACE(("bootfs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat)); TRACE(("bootfs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat));
mutex_lock(&fs->lock); mutex_lock(&fs->lock);
@@ -978,7 +993,7 @@ err:
static int static int
bootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) bootfs_write_stat(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;
@@ -1004,30 +1019,36 @@ static struct fs_calls bootfs_calls = {
&bootfs_putvnode, &bootfs_putvnode,
&bootfs_removevnode, &bootfs_removevnode,
&bootfs_open,
&bootfs_close,
&bootfs_freecookie,
&bootfs_fsync,
&bootfs_read,
&bootfs_write,
&bootfs_seek,
&bootfs_read_dir,
&bootfs_rewind_dir,
&bootfs_ioctl,
&bootfs_canpage, &bootfs_canpage,
&bootfs_readpage, &bootfs_readpage,
&bootfs_writepage, &bootfs_writepage,
&bootfs_create, /* common */
&bootfs_ioctl,
&bootfs_fsync,
&bootfs_unlink, &bootfs_unlink,
&bootfs_rename, &bootfs_rename,
&bootfs_rstat, &bootfs_read_stat,
&bootfs_wstat, &bootfs_write_stat,
/* file */
&bootfs_create,
&bootfs_open,
&bootfs_close,
&bootfs_free_cookie,
&bootfs_read,
&bootfs_write,
&bootfs_seek,
/* dir */
&bootfs_create_dir,
&bootfs_open_dir,
&bootfs_close, // we are using the same operations for directories
&bootfs_free_cookie, // and files here - that's intended, not by accident
&bootfs_read_dir,
&bootfs_rewind_dir,
}; };
@@ -1041,8 +1062,9 @@ bootstrap_bootfs(void)
// find the bootdir and set it up // find the bootdir and set it up
rid = vm_find_region_by_name(vm_get_kernel_aspace_id(), "bootdir"); rid = vm_find_region_by_name(vm_get_kernel_aspace_id(), "bootdir");
if(rid < 0) if (rid < 0)
panic("bootstrap_bootfs: no bootdir area found!\n"); panic("bootstrap_bootfs: no bootdir area found!\n");
vm_get_region_info(rid, &rinfo); vm_get_region_info(rid, &rinfo);
bootdir = (char *)rinfo.base; bootdir = (char *)rinfo.base;
bootdir_len = rinfo.size; bootdir_len = rinfo.size;
+135 -119
View File
@@ -399,14 +399,14 @@ devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *r
TRACE(("devfs_mount: entry\n")); TRACE(("devfs_mount: entry\n"));
if(thedevfs) { if (thedevfs) {
dprintf("double mount of devfs attempted\n"); dprintf("double mount of devfs attempted\n");
err = ERR_GENERAL; err = ERR_GENERAL;
goto err; goto err;
} }
fs = kmalloc(sizeof(struct devfs)); fs = kmalloc(sizeof(struct devfs));
if(fs == NULL) { if (fs == NULL) {
err = ENOMEM; err = ENOMEM;
goto err; goto err;
} }
@@ -415,20 +415,20 @@ devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *r
fs->next_vnode_id = 0; fs->next_vnode_id = 0;
err = mutex_init(&fs->lock, "devfs_mutex"); err = mutex_init(&fs->lock, "devfs_mutex");
if(err < 0) { if (err < 0) {
goto err1; goto err1;
} }
fs->vnode_list_hash = hash_init(BOOTFS_HASH_SIZE, (addr)&v->all_next - (addr)v, fs->vnode_list_hash = hash_init(BOOTFS_HASH_SIZE, (addr)&v->all_next - (addr)v,
&devfs_vnode_compare_func, &devfs_vnode_hash_func); &devfs_vnode_compare_func, &devfs_vnode_hash_func);
if(fs->vnode_list_hash == NULL) { if (fs->vnode_list_hash == NULL) {
err = ENOMEM; err = ENOMEM;
goto err2; goto err2;
} }
// create a vnode // create a vnode
v = devfs_create_vnode(fs, ""); v = devfs_create_vnode(fs, "");
if(v == NULL) { if (v == NULL) {
err = ENOMEM; err = ENOMEM;
goto err3; goto err3;
} }
@@ -462,7 +462,9 @@ err:
return err; return err;
} }
static int devfs_unmount(fs_cookie _fs)
static int
devfs_unmount(fs_cookie _fs)
{ {
struct devfs *fs = _fs; struct devfs *fs = _fs;
struct devfs_vnode *v; struct devfs_vnode *v;
@@ -484,14 +486,18 @@ static int devfs_unmount(fs_cookie _fs)
return 0; return 0;
} }
static int devfs_sync(fs_cookie fs)
static int
devfs_sync(fs_cookie fs)
{ {
TRACE(("devfs_sync: entry\n")); TRACE(("devfs_sync: entry\n"));
return 0; return 0;
} }
static int devfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id)
static int
devfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id)
{ {
struct devfs *fs = (struct devfs *)_fs; struct devfs *fs = (struct devfs *)_fs;
struct devfs_vnode *dir = (struct devfs_vnode *)_dir; struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
@@ -528,7 +534,9 @@ err:
return err; return err;
} }
static int devfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
static int
devfs_get_vnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
{ {
struct devfs *fs = (struct devfs *)_fs; struct devfs *fs = (struct devfs *)_fs;
@@ -550,7 +558,9 @@ static int devfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
return ERR_NOT_FOUND; return ERR_NOT_FOUND;
} }
static int devfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r)
static int
devfs_put_vnode(fs_cookie _fs, fs_vnode _v, bool r)
{ {
#if DEVFS_TRACE #if DEVFS_TRACE
struct devfs_vnode *v = (struct devfs_vnode *)_v; struct devfs_vnode *v = (struct devfs_vnode *)_v;
@@ -561,7 +571,9 @@ static int devfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r)
return 0; // whatever return 0; // whatever
} }
static int devfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
static int
devfs_remove_vnode(fs_cookie _fs, fs_vnode _v, bool r)
{ {
struct devfs *fs = (struct devfs *)_fs; struct devfs *fs = (struct devfs *)_fs;
struct devfs_vnode *v = (struct devfs_vnode *)_v; struct devfs_vnode *v = (struct devfs_vnode *)_v;
@@ -587,82 +599,66 @@ static int devfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
return err; return err;
} }
static int devfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags)
static int
devfs_create(fs_cookie _fs, fs_vnode _dir, file_cookie *_cookie, vnode_id *new_vnid, const char *name, int omode, int perms)
{
return EROFS;
}
static int
devfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, int oflags)
{ {
struct devfs *fs = _fs; struct devfs *fs = _fs;
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie; struct devfs_cookie *cookie;
int err = 0; int status = 0;
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) {
err = ERR_VFS_WRONG_STREAM_TYPE;
goto err;
}
cookie = kmalloc(sizeof(struct devfs_cookie)); cookie = kmalloc(sizeof(struct devfs_cookie));
if (cookie == NULL) { if (cookie == NULL)
err = ENOMEM; return ENOMEM;
goto err;
}
mutex_lock(&fs->lock);
cookie->s = &v->stream;
switch(v->stream.type) {
case STREAM_TYPE_DIR:
cookie->u.dir.ptr = v->stream.u.dir.dir_head;
break;
case STREAM_TYPE_DEVICE:
// call the device call, but unlock the devfs first
mutex_unlock(&fs->lock);
err = v->stream.u.dev.calls->open(v->name, oflags, &cookie->u.dev.dcookie);
mutex_lock(&fs->lock);
break;
default:
err = ERR_VFS_WRONG_STREAM_TYPE;
kfree(cookie);
}
status = vnode->stream.u.dev.calls->open(vnode->name, oflags, &cookie->u.dev.dcookie);
*_cookie = cookie; *_cookie = cookie;
mutex_unlock(&fs->lock); return status;
err:
return err;
} }
static int devfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
static int
devfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
{ {
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
int err;
TRACE(("devfs_close: entry vnode 0x%x, cookie 0x%x\n", v, cookie)); TRACE(("devfs_close: entry vnode 0x%x, cookie 0x%x\n", v, cookie));
if(v->stream.type == STREAM_TYPE_DEVICE) { if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying device // pass the call through to the underlying device
err = v->stream.u.dev.calls->close(cookie->u.dev.dcookie); return vnode->stream.u.dev.calls->close(cookie->u.dev.dcookie);
} else {
err = 0;
} }
return err; return B_OK;
} }
static int devfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
static int
devfs_free_cookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
{ {
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v, cookie)); TRACE(("devfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", vnode, cookie));
if(v->stream.type == STREAM_TYPE_DEVICE) { if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying device // pass the call through to the underlying device
v->stream.u.dev.calls->free(cookie->u.dev.dcookie); vnode->stream.u.dev.calls->free(cookie->u.dev.dcookie);
} }
if(cookie) if (cookie)
kfree(cookie); kfree(cookie);
return 0; return 0;
@@ -677,43 +673,32 @@ devfs_fsync(fs_cookie _fs, fs_vnode _v)
static ssize_t static ssize_t
devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, size_t *len) devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buffer, off_t pos, size_t *length)
{ {
struct devfs *fs = _fs; struct devfs *fs = _fs;
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
bool is_locked = false; struct devfs_part_map *part_map;
ssize_t err = 0;
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) { TRACE(("devfs_read: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", vnode, cookie, pos, len));
case STREAM_TYPE_DEVICE: {
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
if (part_map) {
if( pos < 0 )
pos = 0;
if (pos > part_map->size) if (cookie->s->type != STREAM_TYPE_DEVICE)
return 0; return EINVAL;
*len = min(*len, part_map->size - pos ); part_map = vnode->stream.u.dev.part_map;
pos += part_map->offset; if (part_map) {
} if( pos < 0 )
pos = 0;
// pass the call through to the device if (pos > part_map->size)
err = v->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buf, len); return 0;
break;
} *length = min(*length, part_map->size - pos );
default: pos += part_map->offset;
err = EINVAL;
} }
err:
if (is_locked)
mutex_unlock(&fs->lock);
return err; // pass the call through to the device
return vnode->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buffer, length);
} }
@@ -788,6 +773,40 @@ devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
} }
static int
devfs_create_dir(fs_cookie _fs, fs_vnode _dir, const char *name, int perms, vnode_id *new_vnid)
{
return EROFS;
}
static int
devfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
{
struct devfs *fs = _fs;
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie;
TRACE(("devfs_open: vnode 0x%x, oflags 0x%x\n", vnode, oflags));
if (vnode->stream.type != STREAM_TYPE_DIR)
return EINVAL;
cookie = kmalloc(sizeof(struct devfs_cookie));
if (cookie == NULL)
return ENOMEM;
mutex_lock(&fs->lock);
cookie->s = &vnode->stream;
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
*_cookie = cookie;
mutex_unlock(&fs->lock);
return B_OK;
}
static int static int
devfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, 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)
{ {
@@ -944,13 +963,6 @@ 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)
{
return EROFS;
}
static int static int
devfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name) devfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
{ {
@@ -994,14 +1006,12 @@ devfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _new
static int static int
devfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) devfs_read_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
{ {
struct devfs_vnode *v = _v; struct devfs_vnode *v = _v;
TRACE(("devfs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat)); TRACE(("devfs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat));
//dprintf("devfs_rstat\n");
stat->st_ino = v->id; stat->st_ino = v->id;
stat->st_mode = DEFFILEMODE; stat->st_mode = DEFFILEMODE;
stat->st_size = 0; stat->st_size = 0;
@@ -1016,7 +1026,7 @@ devfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
static int static int
devfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) devfs_write_stat(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;
@@ -1038,34 +1048,40 @@ static struct fs_calls devfs_calls = {
&devfs_lookup, &devfs_lookup,
&devfs_getvnode, &devfs_get_vnode,
&devfs_putvnode, &devfs_put_vnode,
&devfs_removevnode, &devfs_remove_vnode,
&devfs_open, NULL, // can page (currently commented out for whatever reason...)
&devfs_close, NULL, // read page
&devfs_freecookie, NULL, // write page
/* common */
&devfs_ioctl,
&devfs_fsync, &devfs_fsync,
&devfs_read,
&devfs_write,
&devfs_seek,
&devfs_read_dir,
&devfs_rewind_dir,
&devfs_ioctl,
NULL,
NULL,
NULL,
&devfs_create,
&devfs_unlink, &devfs_unlink,
&devfs_rename, &devfs_rename,
&devfs_rstat, &devfs_read_stat,
&devfs_wstat, &devfs_write_stat,
/* file */
&devfs_create,
&devfs_open,
&devfs_close,
&devfs_free_cookie,
&devfs_read,
&devfs_write,
&devfs_seek,
/* directory */
&devfs_create_dir,
&devfs_open_dir,
&devfs_close, // we are using the same operations for directories
&devfs_free_cookie, // and files here - that's intended, not by accident
&devfs_read_dir,
&devfs_rewind_dir,
}; };
+131 -123
View File
@@ -351,7 +351,7 @@ err:
static int static int
rootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r) rootfs_get_vnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
{ {
struct rootfs *fs = (struct rootfs *)_fs; struct rootfs *fs = (struct rootfs *)_fs;
@@ -375,7 +375,7 @@ rootfs_getvnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
static int static int
rootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r) rootfs_put_vnode(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;
@@ -387,7 +387,7 @@ rootfs_putvnode(fs_cookie _fs, fs_vnode _v, bool r)
static int static int
rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r) rootfs_remove_vnode(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;
@@ -407,7 +407,7 @@ rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
err = 0; err = 0;
if(!r) if (!r)
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
return err; return err;
@@ -415,38 +415,17 @@ rootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
static int static int
rootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, stream_type st, int oflags) rootfs_create(fs_cookie _fs, fs_vnode _dir, file_cookie *_cookie, vnode_id *new_vnid, const char *name, int omode, int perms)
{ {
struct rootfs *fs = (struct rootfs *)_fs; return EINVAL;
struct rootfs_vnode *v = (struct rootfs_vnode *)_v; }
struct rootfs_cookie *cookie;
int err = 0;
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) { static int
err = ERR_VFS_WRONG_STREAM_TYPE; rootfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, int oflags)
goto err; {
} // allow to open the file, but it can't be done anything with it
return B_OK;
cookie = kmalloc(sizeof(struct rootfs_cookie));
if (cookie == NULL) {
err = ERR_NO_MEMORY;
goto err;
}
mutex_lock(&fs->lock);
cookie->ptr = v->stream.dir.dir_head;
cookie->oflags = oflags;
insert_cookie_in_jar(v, cookie);
*_cookie = cookie;
mutex_unlock(&fs->lock);
err:
return err;
} }
@@ -464,7 +443,7 @@ rootfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
static int static int
rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie) rootfs_free_cookie(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
@@ -472,7 +451,7 @@ rootfs_freecookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
TRACE(("rootfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v, cookie)); TRACE(("rootfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v, cookie));
#endif #endif
if(cookie) if (cookie)
kfree(cookie); kfree(cookie);
return 0; return 0;
@@ -536,6 +515,89 @@ rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
} }
static int
rootfs_create_dir(fs_cookie _fs, fs_vnode _dir, const char *name, int perms, vnode_id *new_vnid)
{
struct rootfs *fs = _fs;
struct rootfs_vnode *dir = _dir;
struct rootfs_vnode *new_vnode;
struct rootfs_stream *s;
int err = 0;
bool created_vnode = false;
TRACE(("rootfs_create: dir 0x%x, name = '%s', stream_type = %d\n", dir, name, st));
mutex_lock(&fs->lock);
new_vnode = rootfs_find_in_dir(dir, name);
if (new_vnode == NULL) {
dprintf("rootfs_create: creating new vnode\n");
new_vnode = rootfs_create_vnode(fs);
if (new_vnode == NULL) {
err = ENOMEM;
goto err;
}
created_vnode = true;
new_vnode->name = kstrdup(name);
if (new_vnode->name == NULL) {
err = ENOMEM;
goto err1;
}
new_vnode->parent = dir;
rootfs_insert_in_dir(dir, new_vnode);
hash_insert(fs->vnode_list_hash, new_vnode);
s = &new_vnode->stream;
} else {
// we found the vnode
err = ERR_VFS_ALREADY_EXISTS;
goto err;
}
new_vnode->stream.dir.dir_head = NULL;
new_vnode->stream.dir.jar_head = NULL;
mutex_unlock(&fs->lock);
return 0;
err1:
if (created_vnode)
rootfs_delete_vnode(fs, new_vnode, false);
err:
mutex_unlock(&fs->lock);
return err;
}
static int
rootfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
{
struct rootfs *fs = (struct rootfs *)_fs;
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_v;
struct rootfs_cookie *cookie;
TRACE(("rootfs_open: vnode 0x%x\n", vnode));
cookie = kmalloc(sizeof(struct rootfs_cookie));
if (cookie == NULL)
return ENOMEM;
mutex_lock(&fs->lock);
cookie->ptr = vnode->stream.dir.dir_head;
//cookie->oflags = oflags;
insert_cookie_in_jar(vnode, cookie);
*_cookie = cookie;
mutex_unlock(&fs->lock);
return B_OK;
}
static int static int
rootfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct dirent *dirent, 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)
{ {
@@ -601,88 +663,28 @@ rootfs_ioctl(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, ulong op, void *bu
static int static int
rootfs_canpage(fs_cookie _fs, fs_vnode _v) rootfs_can_page(fs_cookie _fs, fs_vnode _v)
{ {
return -1; return -1;
} }
static ssize_t static ssize_t
rootfs_readpage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) rootfs_read_page(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos)
{ {
return EPERM; return EPERM;
} }
static ssize_t static ssize_t
rootfs_writepage(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos) rootfs_write_page(fs_cookie _fs, fs_vnode _v, iovecs *vecs, off_t pos)
{ {
return EPERM; return EPERM;
} }
static int static int
rootfs_create(fs_cookie _fs, fs_vnode _dir, const char *name, stream_type st, void *create_args, vnode_id *new_vnid) rootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
{
struct rootfs *fs = _fs;
struct rootfs_vnode *dir = _dir;
struct rootfs_vnode *new_vnode;
struct rootfs_stream *s;
int err = 0;
bool created_vnode = false;
TRACE(("rootfs_create: dir 0x%x, name = '%s', stream_type = %d\n", dir, name, st));
// we only support stream types of STREAM_TYPE_DIR
if (st != STREAM_TYPE_DIR) {
err = EPERM;
goto err;
}
mutex_lock(&fs->lock);
new_vnode = rootfs_find_in_dir(dir, name);
if (new_vnode == NULL) {
dprintf("rootfs_create: creating new vnode\n");
new_vnode = rootfs_create_vnode(fs);
if(new_vnode == NULL) {
err = ENOMEM;
goto err;
}
created_vnode = true;
new_vnode->name = kstrdup(name);
if(new_vnode->name == NULL) {
err = ENOMEM;
goto err1;
}
new_vnode->parent = dir;
rootfs_insert_in_dir(dir, new_vnode);
hash_insert(fs->vnode_list_hash, new_vnode);
s = &new_vnode->stream;
} else {
// we found the vnode
err = ERR_VFS_ALREADY_EXISTS;
goto err;
}
new_vnode->stream.dir.dir_head = NULL;
new_vnode->stream.dir.jar_head = NULL;
mutex_unlock(&fs->lock);
return 0;
err1:
if(created_vnode)
rootfs_delete_vnode(fs, new_vnode, false);
err:
mutex_unlock(&fs->lock);
return err;
}
static int rootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
{ {
struct rootfs *fs = _fs; struct rootfs *fs = _fs;
struct rootfs_vnode *dir = _dir; struct rootfs_vnode *dir = _dir;
@@ -788,7 +790,7 @@ err:
return err; return err;
} }
static int rootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat) static int rootfs_read_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
{ {
struct rootfs_vnode *v = _v; struct rootfs_vnode *v = _v;
@@ -806,7 +808,7 @@ static int rootfs_rstat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
static int static int
rootfs_wstat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask) rootfs_write_stat(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;
@@ -829,34 +831,40 @@ static struct fs_calls rootfs_calls = {
&rootfs_lookup, &rootfs_lookup,
&rootfs_getvnode, &rootfs_get_vnode,
&rootfs_putvnode, &rootfs_put_vnode,
&rootfs_removevnode, &rootfs_remove_vnode,
&rootfs_open, &rootfs_can_page,
&rootfs_close, &rootfs_read_page,
&rootfs_freecookie, &rootfs_write_page,
/* common */
&rootfs_ioctl,
&rootfs_fsync, &rootfs_fsync,
&rootfs_read,
&rootfs_write,
&rootfs_seek,
&rootfs_read_dir,
&rootfs_rewind_dir,
&rootfs_ioctl,
&rootfs_canpage,
&rootfs_readpage,
&rootfs_writepage,
&rootfs_create,
&rootfs_unlink, &rootfs_unlink,
&rootfs_rename, &rootfs_rename,
&rootfs_rstat, &rootfs_read_stat,
&rootfs_wstat, &rootfs_write_stat,
/* file */
&rootfs_create,
&rootfs_open,
&rootfs_close,
&rootfs_free_cookie,
&rootfs_read,
&rootfs_write,
&rootfs_seek,
/* directory */
&rootfs_create_dir,
&rootfs_open_dir,
&rootfs_close, // we are using the same operations for directories
&rootfs_free_cookie, // and files here - that's intended, not by accident
&rootfs_read_dir,
&rootfs_rewind_dir,
}; };
+452 -301
View File
File diff suppressed because it is too large Load Diff