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:
+82
-60
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user