sys_seek() now returns the stream position as an off_t.

Minor bug fixes.
fd_close() now doesn't have to call remove_fd() anymore - it's now called
in user|sys_close(), fd_close() is now only called in the last put_fd().
Cleanup, improved debug output (without any warnings).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@266 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2002-07-17 07:55:51 +00:00
parent b46f99148e
commit 243d156e21
5 changed files with 404 additions and 433 deletions

View File

@ -23,12 +23,31 @@
return EINVAL;
#define PRINT(x) dprintf x
#define TRACE_FD 0
#if TRACE_FD
# define TRACE(x) dprintf x
# define PRINT(x) dprintf x
#else
# define TRACE(x)
# define PRINT(x)
#endif
/*** General fd routines ***/
#ifdef DEBUG
void dump_fd(int fd, struct file_descriptor *descriptor);
void
dump_fd(int fd,struct file_descriptor *descriptor)
{
dprintf("fd[%d] = %p: type = %d, ref_count = %d, ops = %p, vnode = %p, cookie = %p, dummy = %x\n",
fd,descriptor,descriptor->type,descriptor->ref_count,descriptor->ops,
descriptor->vnode,descriptor->cookie,descriptor->dummy);
}
#endif
/** Allocates and initializes a new file_descriptor */
struct file_descriptor *
@ -41,6 +60,7 @@ alloc_fd(void)
f->vnode = NULL;
f->cookie = NULL;
f->ref_count = 1;
f->dummy = 0xdeadbeef;
}
return f;
}
@ -76,15 +96,18 @@ err:
void
put_fd(struct file_descriptor *f)
put_fd(struct file_descriptor *descriptor)
{
/* Run a cleanup (fd_free) routine if there is one and free structure, but only
* if we've just removed the final reference to it :)
*/
if (atomic_add(&f->ref_count, -1) == 1) {
if (f->ops->fd_free)
f->ops->fd_free(f);
kfree(f);
if (atomic_add(&descriptor->ref_count, -1) == 1) {
if (descriptor->ops->fd_close)
descriptor->ops->fd_close(descriptor);
if (descriptor->ops->fd_free)
descriptor->ops->fd_free(descriptor);
kfree(descriptor);
}
}
@ -105,6 +128,7 @@ get_fd(struct io_context *ioctx, int fd)
}
mutex_unlock(&ioctx->io_mutex);
return f;
}
@ -185,23 +209,24 @@ user_write(int fd, const void *buffer, off_t pos, size_t length)
}
int
user_seek(int fd, off_t pos, int seek_type)
off_t
user_seek(int fd, off_t pos, int seekType)
{
struct file_descriptor *descriptor;
int status;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return EBADF;
TRACE(("user_seek(descriptor = %p)\n",descriptor));
if (descriptor->ops->fd_seek)
status = descriptor->ops->fd_seek(descriptor, pos, seek_type);
pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
else
status = EOPNOTSUPP;
pos = ESPIPE;
put_fd(descriptor);
return status;
return pos;
}
@ -291,6 +316,8 @@ user_fstat(int fd, struct stat *stat)
if (descriptor == NULL)
return EBADF;
TRACE(("user_fstat(descriptor = %p)\n",descriptor));
if (descriptor->ops->fd_stat) {
// we're using the stat buffer on the stack to not have to
// lock the given stat buffer in memory
@ -310,20 +337,18 @@ user_fstat(int fd, struct stat *stat)
int
user_close(int fd)
{
struct io_context *ioContext = get_current_io_context(false);
struct file_descriptor *descriptor = get_fd(ioContext, fd);
int retval;
struct io_context *io = get_current_io_context(false);
struct file_descriptor *descriptor = get_fd(io, fd);
if (descriptor == NULL)
return EBADF;
if (descriptor->ops->fd_close)
retval = descriptor->ops->fd_close(descriptor, fd, ioContext);
else
retval = EOPNOTSUPP;
TRACE(("user_close(descriptor = %p)\n",descriptor));
remove_fd(io, fd);
put_fd(descriptor);
return retval;
return B_OK;
}
@ -364,7 +389,6 @@ sys_write(int fd, const void *buffer, off_t pos, size_t length)
struct file_descriptor *descriptor;
ssize_t retval;
// dprintf("sys_write: fd %d\n", fd);
// CHECK_SYS_ADDR(buffer)
descriptor = get_fd(get_current_io_context(true), fd);
@ -385,23 +409,22 @@ sys_write(int fd, const void *buffer, off_t pos, size_t length)
}
int
sys_seek(int fd, off_t pos, int seek_type)
off_t
sys_seek(int fd, off_t pos, int seekType)
{
struct file_descriptor *descriptor;
int status;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return EBADF;
if (descriptor->ops->fd_seek)
status = descriptor->ops->fd_seek(descriptor, pos, seek_type);
pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
else
status = EOPNOTSUPP;
pos = ESPIPE;
put_fd(descriptor);
return status;
return pos;
}
@ -460,7 +483,7 @@ sys_rewind_dir(int fd)
struct file_descriptor *descriptor;
status_t status;
PRINT(("user_rewind_dir(fd = %d)\n",fd));
PRINT(("sys_rewind_dir(fd = %d)\n",fd));
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
@ -479,19 +502,15 @@ sys_rewind_dir(int fd)
int
sys_close(int fd)
{
struct io_context *ioContext = get_current_io_context(true);
struct file_descriptor *descriptor = get_fd(ioContext, fd);
int status;
struct io_context *io = get_current_io_context(true);
struct file_descriptor *descriptor = get_fd(io, fd);
if (descriptor == NULL)
return EBADF;
if (descriptor->ops->fd_close)
status = descriptor->ops->fd_close(descriptor, fd, ioContext);
else
status = EOPNOTSUPP;
remove_fd(io, fd);
put_fd(descriptor);
return status;
return B_OK;
}

View File

@ -581,7 +581,7 @@ bootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
err = 0;
err:
if(!r)
if (!r)
mutex_unlock(&fs->lock);
return err;
@ -714,73 +714,57 @@ bootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_
}
static int
bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
static off_t
bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int seekType)
{
struct bootfs *fs = _fs;
struct bootfs_vnode *v = _v;
struct bootfs_cookie *cookie = _cookie;
int err = 0;
int err = B_OK;
TRACE(("bootfs_seek: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, seek_type %d\n", v, cookie, pos, st));
if (cookie->s->type != STREAM_TYPE_FILE)
return EINVAL;
mutex_lock(&fs->lock);
switch(cookie->s->type) {
case STREAM_TYPE_DIR:
switch(st) {
// only valid args are seek_type SEEK_SET, pos 0.
// this rewinds to beginning of directory
case SEEK_SET:
if(pos == 0) {
cookie->u.dir.ptr = cookie->s->u.dir.dir_head;
} else {
err = ESPIPE;
}
break;
case SEEK_CUR:
case SEEK_END:
default:
err = ESPIPE;
}
switch (seekType) {
case SEEK_SET:
if (pos < 0)
pos = 0;
if (pos > cookie->s->u.file.len)
pos = cookie->s->u.file.len;
cookie->u.file.pos = pos;
break;
case STREAM_TYPE_FILE:
switch(st) {
case SEEK_SET:
if(pos < 0)
pos = 0;
if(pos > cookie->s->u.file.len)
pos = cookie->s->u.file.len;
cookie->u.file.pos = pos;
break;
case SEEK_CUR:
if(pos + cookie->u.file.pos > cookie->s->u.file.len)
cookie->u.file.pos = cookie->s->u.file.len;
else if(pos + cookie->u.file.pos < 0)
cookie->u.file.pos = 0;
else
cookie->u.file.pos += pos;
break;
case SEEK_END:
if(pos > 0)
cookie->u.file.pos = cookie->s->u.file.len;
else if(pos + cookie->s->u.file.len < 0)
cookie->u.file.pos = 0;
else
cookie->u.file.pos = pos + cookie->s->u.file.len;
break;
default:
err = EINVAL;
}
case SEEK_CUR:
if (pos + cookie->u.file.pos > cookie->s->u.file.len)
pos = cookie->s->u.file.len;
else if (pos + cookie->u.file.pos < 0)
pos = 0;
else
pos += cookie->u.file.pos;
break;
case SEEK_END:
if (pos > 0)
pos = cookie->s->u.file.len;
else if (pos + cookie->s->u.file.len < 0)
pos = 0;
else
pos += cookie->s->u.file.len;
break;
default:
err = EINVAL;
}
if (err == B_OK)
cookie->u.file.pos = pos;
mutex_unlock(&fs->lock);
return err;
if (err < B_OK)
return err;
return pos;
}

View File

@ -27,9 +27,11 @@
#define DEVFS_TRACE 0
#if DEVFS_TRACE
#define TRACE(x) dprintf x
# define TRACE(x) dprintf x
# define INSANE(x) dprintf x
#else
#define TRACE(x)
# define TRACE(x)
# define INSANE(x)
#endif
struct devfs_part_map {
@ -51,7 +53,7 @@ struct devfs_stream {
struct devfs_cookie *jar_head;
} dir;
struct stream_dev {
void * ident;
void *ident;
device_hooks *calls;
struct devfs_part_map *part_map;
} dev;
@ -77,7 +79,7 @@ struct devfs {
};
struct devfs_cookie {
struct devfs_stream *s;
struct devfs_stream *stream;
int oflags;
union {
struct cookie_dir {
@ -92,7 +94,7 @@ struct devfs_cookie {
};
/* the one and only allowed devfs instance */
static struct devfs *thedevfs = NULL;
static struct devfs *gDeviceFileSystem = NULL;
#define BOOTFS_HASH_SIZE 16
@ -103,10 +105,10 @@ devfs_vnode_hash_func(void *_v, const void *_key, unsigned int range)
struct devfs_vnode *v = _v;
const vnode_id *key = _key;
if(v != NULL)
if (v != NULL)
return v->id % range;
else
return (*key) % range;
return (*key) % range;
}
@ -116,10 +118,10 @@ devfs_vnode_compare_func(void *_v, const void *_key)
struct devfs_vnode *v = _v;
const vnode_id *key = _key;
if(v->id == *key)
if (v->id == *key)
return 0;
else
return -1;
return -1;
}
@ -129,14 +131,14 @@ devfs_create_vnode(struct devfs *fs, const char *name)
struct devfs_vnode *v;
v = kmalloc(sizeof(struct devfs_vnode));
if(v == NULL)
if (v == NULL)
return NULL;
memset(v, 0, sizeof(struct devfs_vnode));
v->id = fs->next_vnode_id++;
v->name = kstrdup(name);
if(v->name == NULL) {
if (v->name == NULL) {
kfree(v);
return NULL;
}
@ -150,18 +152,19 @@ devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *v, bool force_delete)
{
// cant delete it if it's in a directory or is a directory
// and has children
if(!force_delete && ((v->stream.type == STREAM_TYPE_DIR && v->stream.u.dir.dir_head != NULL) || v->dir_next != NULL)) {
if (!force_delete
&& ((v->stream.type == STREAM_TYPE_DIR && v->stream.u.dir.dir_head != NULL)
|| v->dir_next != NULL))
return EPERM;
}
// remove it from the global hash table
hash_remove(fs->vnode_list_hash, v);
// TK: for partitions, we have to release the raw device
if( v->stream.type == STREAM_TYPE_DEVICE && v->stream.u.dev.part_map )
vfs_put_vnode( fs->id, v->stream.u.dev.part_map->raw_vnode->id );
if(v->name != NULL)
if (v->stream.type == STREAM_TYPE_DEVICE && v->stream.u.dev.part_map)
vfs_put_vnode(fs->id, v->stream.u.dev.part_map->raw_vnode->id);
if (v->name != NULL)
kfree(v->name);
kfree(v);
@ -198,10 +201,9 @@ update_dircookies(struct devfs_vnode *dir, struct devfs_vnode *v)
{
struct devfs_cookie *cookie;
for(cookie = dir->stream.u.dir.jar_head; cookie; cookie = cookie->u.dir.next) {
if(cookie->u.dir.ptr == v) {
for (cookie = dir->stream.u.dir.jar_head; cookie; cookie = cookie->u.dir.next) {
if (cookie->u.dir.ptr == v)
cookie->u.dir.ptr = v->dir_next;
}
}
}
@ -211,18 +213,18 @@ devfs_find_in_dir(struct devfs_vnode *dir, const char *path)
{
struct devfs_vnode *v;
if(dir->stream.type != STREAM_TYPE_DIR)
if (dir->stream.type != STREAM_TYPE_DIR)
return NULL;
if(!strcmp(path, "."))
if (!strcmp(path, "."))
return dir;
if(!strcmp(path, ".."))
if (!strcmp(path, ".."))
return dir->parent;
for(v = dir->stream.u.dir.dir_head; v; v = v->dir_next) {
// dprintf("devfs_find_in_dir: looking at entry '%s'\n", v->name);
if(strcmp(v->name, path) == 0) {
// dprintf("devfs_find_in_dir: found it at 0x%x\n", v);
for (v = dir->stream.u.dir.dir_head; v; v = v->dir_next) {
INSANE(("devfs_find_in_dir: looking at entry '%s'\n", v->name));
if (strcmp(v->name, path) == 0) {
INSANE(("devfs_find_in_dir: found it at %p\n", v));
return v;
}
}
@ -233,7 +235,7 @@ devfs_find_in_dir(struct devfs_vnode *dir, const char *path)
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;
v->dir_next = dir->stream.u.dir.dir_head;
@ -250,12 +252,12 @@ devfs_remove_from_dir(struct devfs_vnode *dir, struct devfs_vnode *findit)
struct devfs_vnode *v;
struct devfs_vnode *last_v;
for(v = dir->stream.u.dir.dir_head, last_v = NULL; v; last_v = v, v = v->dir_next) {
if(v == findit) {
for (v = dir->stream.u.dir.dir_head, last_v = NULL; v; last_v = v, v = v->dir_next) {
if (v == findit) {
/* make sure all dircookies dont point to this vnode */
update_dircookies(dir, v);
if(last_v)
if (last_v)
last_v->dir_next = v->dir_next;
else
dir->stream.u.dir.dir_head = v->dir_next;
@ -270,8 +272,9 @@ devfs_remove_from_dir(struct devfs_vnode *dir, struct devfs_vnode *findit)
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 !dir->stream.u.dir.dir_head;
}
@ -282,8 +285,8 @@ devfs_get_partition_info( struct devfs *fs, struct devfs_vnode *v,
{
devfs_partition_info *info = (devfs_partition_info *)buf;
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
if( v->stream.type != STREAM_TYPE_DEVICE || part_map == NULL )
if (v->stream.type != STREAM_TYPE_DEVICE || part_map == NULL)
return EINVAL;
info->offset = part_map->offset;
@ -310,20 +313,20 @@ static int devfs_set_partition( struct devfs *fs, struct devfs_vnode *v,
info = *(devfs_partition_info *)buf;
if( v->stream.type != STREAM_TYPE_DEVICE )
if (v->stream.type != STREAM_TYPE_DEVICE)
return EINVAL;
// we don't support nested partitions
if( v->stream.u.dev.part_map )
if (v->stream.u.dev.part_map)
return EINVAL;
// reduce checks to a minimum - things like negative offsets could be useful
if( info.size < 0)
if (info.size < 0)
return EINVAL;
// create partition map
part_map = kmalloc( sizeof( *part_map ));
if( !part_map )
part_map = kmalloc(sizeof(*part_map));
if (!part_map)
return ENOMEM;
part_map->offset = info.offset;
@ -332,12 +335,12 @@ static int devfs_set_partition( struct devfs *fs, struct devfs_vnode *v,
part_map->session = info.session;
part_map->partition = info.partition;
sprintf( part_name, "%i_%i", info.session, info.partition );
sprintf(part_name, "%i_%i", info.session, info.partition);
mutex_lock(&thedevfs->lock);
mutex_lock(&gDeviceFileSystem->lock);
// you cannot change a partition once set
if( devfs_find_in_dir( v->parent, part_name )) {
if (devfs_find_in_dir( v->parent, part_name)) {
res = EINVAL;
goto err1;
}
@ -345,14 +348,14 @@ static int devfs_set_partition( struct devfs *fs, struct devfs_vnode *v,
// increase reference count of raw device -
// the partition device really needs it
// (at least to resolve its name on GET_PARTITION_INFO)
res = vfs_get_vnode( fs->id, v->id, (fs_vnode *)&part_map->raw_vnode );
if( res < 0 )
res = vfs_get_vnode(fs->id, v->id, (fs_vnode *)&part_map->raw_vnode);
if (res < 0)
goto err1;
// now create the partition node
part_node = devfs_create_vnode( fs, part_name );
part_node = devfs_create_vnode(fs, part_name);
if( part_node == NULL ) {
if (part_node == NULL) {
res = ENOMEM;
goto err2;
}
@ -362,27 +365,27 @@ static int devfs_set_partition( struct devfs *fs, struct devfs_vnode *v,
part_node->stream.u.dev.calls = v->stream.u.dev.calls;
part_node->stream.u.dev.part_map = part_map;
hash_insert( fs->vnode_list_hash, part_node );
hash_insert(fs->vnode_list_hash, part_node);
devfs_insert_in_dir( v->parent, part_node );
devfs_insert_in_dir(v->parent, part_node);
mutex_unlock(&thedevfs->lock);
mutex_unlock(&gDeviceFileSystem->lock);
dprintf( "SET_PARTITION: Added partition\n" );
TRACE(("SET_PARTITION: Added partition\n"));
return B_NO_ERROR;
err1:
mutex_unlock(&thedevfs->lock);
mutex_unlock(&gDeviceFileSystem->lock);
kfree( part_map );
kfree(part_map);
return res;
err2:
mutex_unlock(&thedevfs->lock);
mutex_unlock(&gDeviceFileSystem->lock);
vfs_put_vnode( fs->id, v->id );
kfree( part_map );
vfs_put_vnode(fs->id, v->id);
kfree(part_map);
return res;
}
@ -399,7 +402,7 @@ devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *r
TRACE(("devfs_mount: entry\n"));
if (thedevfs) {
if (gDeviceFileSystem) {
dprintf("double mount of devfs attempted\n");
err = ERR_GENERAL;
goto err;
@ -447,7 +450,7 @@ devfs_mount(fs_cookie *_fs, fs_id id, const char *devfs, void *args, vnode_id *r
*root_vnid = v->id;
*_fs = fs;
thedevfs = fs;
gDeviceFileSystem = fs;
return 0;
@ -470,7 +473,7 @@ devfs_unmount(fs_cookie _fs)
struct devfs_vnode *v;
struct hash_iterator i;
TRACE(("devfs_unmount: entry fs = 0x%x\n", fs));
TRACE(("devfs_unmount: entry fs = %p\n", fs));
// delete all of the vnodes
hash_open(fs->vnode_list_hash, &i);
@ -501,71 +504,69 @@ devfs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id)
{
struct devfs *fs = (struct devfs *)_fs;
struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
struct devfs_vnode *v;
struct devfs_vnode *v1;
struct devfs_vnode *vnode;
struct devfs_vnode *vdummy;
int err;
TRACE(("devfs_lookup: entry dir 0x%x, name '%s'\n", dir, name));
TRACE(("devfs_lookup: entry dir %p, name '%s'\n", dir, name));
if(dir->stream.type != STREAM_TYPE_DIR)
if (dir->stream.type != STREAM_TYPE_DIR)
return ENOTDIR;
mutex_lock(&fs->lock);
// look it up
v = devfs_find_in_dir(dir, name);
if(!v) {
vnode = devfs_find_in_dir(dir, name);
if (!vnode) {
err = ERR_NOT_FOUND;
goto err;
}
err = vfs_get_vnode(fs->id, v->id, (fs_vnode *)&v1);
if(err < 0) {
err = vfs_get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
if (err < 0)
goto err;
}
*id = v->id;
err = B_NO_ERROR;
*id = vnode->id;
err:
mutex_unlock(&fs->lock);
INSANE(("--devfs_lookup: returns %d\n",err));
return err;
}
static int
devfs_get_vnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
devfs_get_vnode(fs_cookie _fs, vnode_id id, fs_vnode *_vnode, bool reenter)
{
struct devfs *fs = (struct devfs *)_fs;
TRACE(("devfs_getvnode: asking for vnode 0x%x 0x%x, r %d\n", id, r));
TRACE(("devfs_get_vnode: asking for vnode id = %Ld, vnode = %p, r %d\n", id, _vnode, reenter));
if(!r)
if (!reenter)
mutex_lock(&fs->lock);
*v = hash_lookup(fs->vnode_list_hash, &id);
*_vnode = hash_lookup(fs->vnode_list_hash, &id);
if(!r)
if (!reenter)
mutex_unlock(&fs->lock);
TRACE(("devfs_getnvnode: looked it up at 0x%x\n", *v));
TRACE(("devfs_get_vnode: looked it up at %p\n", *_vnode));
if(*v)
if (*_vnode)
return 0;
else
return ERR_NOT_FOUND;
return ERR_NOT_FOUND;
}
static int
devfs_put_vnode(fs_cookie _fs, fs_vnode _v, bool r)
devfs_put_vnode(fs_cookie _fs, fs_vnode _v, bool reenter)
{
#if DEVFS_TRACE
struct devfs_vnode *v = (struct devfs_vnode *)_v;
struct devfs_vnode *vnode = (struct devfs_vnode *)_v;
TRACE(("devfs_putvnode: entry on vnode 0x%x 0x%x, r %d\n", v->id, r));
TRACE(("devfs_put_vnode: entry on vnode %p, id = %Ld, reenter %d\n", vnode, vnode->id, reenter));
#endif
return 0; // whatever
@ -573,30 +574,27 @@ devfs_put_vnode(fs_cookie _fs, fs_vnode _v, bool r)
static int
devfs_remove_vnode(fs_cookie _fs, fs_vnode _v, bool r)
devfs_remove_vnode(fs_cookie _fs, fs_vnode _v, bool reenter)
{
struct devfs *fs = (struct devfs *)_fs;
struct devfs_vnode *v = (struct devfs_vnode *)_v;
int err;
struct devfs_vnode *vnode = (struct devfs_vnode *)_v;
TRACE(("devfs_removevnode: remove 0x%x (0x%x 0x%x), r %d\n", v, v->id, r));
TRACE(("devfs_removevnode: remove %p (%Ld), reenter %d\n", vnode, vnode->id, reenter));
if(!r)
if (!reenter)
mutex_lock(&fs->lock);
if(v->dir_next) {
if (vnode->dir_next) {
// can't remove node if it's linked to the dir
panic("devfs_removevnode: vnode %p asked to be removed is present in dir\n", v);
panic("devfs_removevnode: vnode %p asked to be removed is present in dir\n", vnode);
}
devfs_delete_vnode(fs, v, false);
devfs_delete_vnode(fs, vnode, false);
err = 0;
if(!r)
if (!reenter)
mutex_unlock(&fs->lock);
return err;
return B_OK;
}
@ -615,14 +613,25 @@ devfs_open(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie, int oflags)
struct devfs_cookie *cookie;
int status = 0;
TRACE(("devfs_open: vnode 0x%x, oflags 0x%x\n", v, oflags));
TRACE(("devfs_open: vnode %p, oflags 0x%x\n", vnode, oflags));
cookie = kmalloc(sizeof(struct devfs_cookie));
if (cookie == NULL)
return ENOMEM;
INSANE(("zulu: calls = %p\n",vnode->stream.u.dev.calls));
if (vnode->stream.u.dev.calls)
INSANE(("hellacious: open = %p!\n",vnode->stream.u.dev.calls->open));
if (vnode->stream.type != STREAM_TYPE_DEVICE) {
INSANE(("bye bye!\n"));
return EINVAL;
}
INSANE(("got here.\n"));
status = vnode->stream.u.dev.calls->open(vnode->name, oflags, &cookie->u.dev.dcookie);
*_cookie = cookie;
INSANE(("cool!\n"));
return status;
}
@ -634,7 +643,7 @@ devfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_close: entry vnode 0x%x, cookie 0x%x\n", v, cookie));
TRACE(("devfs_close: entry vnode %p, cookie %p\n", vnode, cookie));
if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying device
@ -651,7 +660,7 @@ devfs_free_cookie(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_freecookie: entry vnode 0x%x, cookie 0x%x\n", vnode, cookie));
TRACE(("devfs_freecookie: entry vnode %p, cookie %p\n", vnode, cookie));
if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying device
@ -679,15 +688,19 @@ devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buffer, off_t
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie;
struct devfs_part_map *part_map;
int status;
TRACE(("devfs_read: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", vnode, cookie, pos, len));
TRACE(("devfs_read: vnode %p, cookie %p, pos %Ld, len %p\n", vnode, cookie, pos, length));
if (cookie->s->type != STREAM_TYPE_DEVICE)
return EINVAL;
INSANE(("juchu, buffer = %p!\n",buffer));
// if (cookie->stream->type != STREAM_TYPE_DEVICE)
// return EINVAL;
INSANE((":%p:%p:%p:%p\n",vnode->all_next,vnode->name,vnode->redir_vnode,vnode->parent));
INSANE(("name = %s\n",vnode->name));
part_map = vnode->stream.u.dev.part_map;
if (part_map) {
if( pos < 0 )
if (pos < 0)
pos = 0;
if (pos > part_map->size)
@ -698,7 +711,11 @@ devfs_read(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, void *buffer, off_t
}
// pass the call through to the device
return vnode->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buffer, length);
INSANE(("calls = %p\n",vnode->stream.u.dev.calls));
status = vnode->stream.u.dev.calls->read(cookie->u.dev.dcookie, pos, buffer, length);
INSANE(("hulu: calls = %p\n",vnode->stream.u.dev.calls));
INSANE((":%p:%p:%p:%p\n",vnode->all_next,vnode->name,vnode->redir_vnode,vnode->parent));
return status;
}
@ -706,13 +723,15 @@ 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 *vnode = _v;
struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, len));
TRACE(("devfs_write: vnode %p, cookie %p, pos %Ld, len %p\n", vnode, cookie, pos, len));
INSANE((":%p:%p:%p:%p\n",vnode->all_next,vnode->name,vnode->redir_vnode,vnode->parent));
if (v->stream.type == STREAM_TYPE_DEVICE) {
struct devfs_part_map *part_map = v->stream.u.dev.part_map;
if (vnode->stream.type == STREAM_TYPE_DEVICE) {
struct devfs_part_map *part_map = vnode->stream.u.dev.part_map;
int written;
if (part_map) {
if (pos < 0)
@ -725,51 +744,28 @@ devfs_write(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, const void *buf,
pos += part_map->offset;
}
return v->stream.u.dev.calls->write(cookie->u.dev.dcookie, pos, buf, len);
INSANE(("hela: name = \"%s\", calls = %p\n",vnode->name,vnode->stream.u.dev.calls));
written = vnode->stream.u.dev.calls->write(cookie->u.dev.dcookie, pos, buf, len);
INSANE(("helu: calls = %p\n",vnode->stream.u.dev.calls));
INSANE((":%p:%p:%p:%p\n",vnode->all_next,vnode->name,vnode->redir_vnode,vnode->parent));
return written;
}
return EROFS;
return EINVAL;
}
static int
devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
static off_t
devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int seekType)
{
#ifdef DEBUG
struct devfs *fs = _fs;
struct devfs_vnode *v = _v;
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie;
int err = 0;
TRACE(("devfs_seek: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, seek_type %d\n", v, cookie, pos, st));
TRACE(("devfs_seek: vnode %p, cookie %p, pos %Ld, seekType %d\n", vnode, cookie, pos, seekType));
#endif
switch(cookie->s->type) {
case STREAM_TYPE_DIR:
mutex_lock(&fs->lock);
switch(st) {
// only valid args are seek_type SEEK_SET, pos 0.
// this rewinds to beginning of directory
case SEEK_SET:
if(pos == 0) {
cookie->u.dir.ptr = cookie->s->u.dir.dir_head;
} else {
err = ESPIPE;
}
break;
case SEEK_CUR:
case SEEK_END:
default:
err = EINVAL;
}
mutex_unlock(&fs->lock);
break;
case STREAM_TYPE_DEVICE:
dprintf("seek not supported!\n");
//err = v->stream.u.dev.calls->dev_seek(cookie->u.dev.dcookie, pos, st);
break;
default:
err = EINVAL;
}
return err;
return ESPIPE;
}
@ -787,7 +783,7 @@ devfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie;
TRACE(("devfs_open: vnode 0x%x, oflags 0x%x\n", vnode, oflags));
TRACE(("devfs_open_dir: vnode %p\n", vnode));
if (vnode->stream.type != STREAM_TYPE_DIR)
return EINVAL;
@ -798,7 +794,7 @@ devfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
mutex_lock(&fs->lock);
cookie->s = &vnode->stream;
cookie->stream = &vnode->stream;
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
*_cookie = cookie;
@ -814,7 +810,10 @@ devfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct diren
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));
TRACE(("devfs_read_dir: vnode %p, cookie %p, buffer %p, size %ld\n", _vnode, cookie, dirent, bufferSize));
if (cookie->stream->type != STREAM_TYPE_DIR)
return EINVAL;
mutex_lock(&fs->lock);
@ -850,12 +849,16 @@ static int
devfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie)
{
struct devfs *fs = _fs;
struct devfs_vnode *vnode = _vnode;
struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_rewind_dir: vnode %p, cookie %p\n", _vnode, _cookie));
if (cookie->stream->type != STREAM_TYPE_DIR)
return EINVAL;
mutex_lock(&fs->lock);
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
cookie->u.dir.ptr = cookie->stream->u.dir.dir_head;
mutex_unlock(&fs->lock);
return B_OK;
@ -869,15 +872,15 @@ devfs_ioctl(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, ulong op, void *buf
struct devfs_vnode *v = _v;
struct devfs_cookie *cookie = _cookie;
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 %p, cookie %p, op %ld, buf %p, len %ld\n", _v, _cookie, op, buf, len));
if (v->stream.type == STREAM_TYPE_DEVICE) {
switch (op) {
case IOCTL_DEVFS_GET_PARTITION_INFO:
return devfs_get_partition_info( fs, v, cookie, buf, len );
return devfs_get_partition_info(fs, v, cookie, buf, len);
case IOCTL_DEVFS_SET_PARTITION:
return devfs_set_partition( fs, v, cookie, buf, len );
return devfs_set_partition(fs, v, cookie, buf, len);
}
return v->stream.u.dev.calls->control(cookie->u.dev.dcookie, op, buf, len);
@ -1008,15 +1011,16 @@ devfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _new
static int
devfs_read_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
{
struct devfs_vnode *v = _v;
struct devfs_vnode *vnode = _v;
TRACE(("devfs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat));
TRACE(("devfs_rstat: vnode %p (%Ld), stat %p\n", vnode, vnode->id, stat));
INSANE(("-> calls = %p\n",vnode->stream.u.dev.calls));
stat->st_ino = v->id;
stat->st_ino = vnode->id;
stat->st_mode = DEFFILEMODE;
stat->st_size = 0;
if (v->stream.type == STREAM_TYPE_DIR)
if (vnode->stream.type == STREAM_TYPE_DIR)
stat->st_mode |= S_IFDIR;
else
stat->st_mode |= S_IFCHR;
@ -1031,7 +1035,7 @@ devfs_write_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat, int stat_mask)
#if DEVFS_TRACE
struct devfs_vnode *v = _v;
TRACE(("devfs_wstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v, v->id, stat));
TRACE(("devfs_wstat: vnode %p (%Ld), stat %p\n", v, v->id, stat));
#endif
// cannot change anything
return EPERM;
@ -1089,7 +1093,7 @@ int
bootstrap_devfs(void)
{
dprintf("bootstrap_devfs: entry\n");
TRACE(("bootstrap_devfs: entry\n"));
return vfs_register_filesystem("devfs", &devfs_calls);
}
@ -1105,9 +1109,14 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
struct devfs_vnode *v;
bool at_leaf;
TRACE(("devfs_publish_device: entry path '%s', hooks 0x%x\n", path, calls));
TRACE(("devfs_publish_device: entry path '%s', ident %p, hooks %p\n", path, ident, calls));
if (!thedevfs) {
if (calls == NULL || path == NULL) {
panic("devfs_publish_device called with NULL pointer!\n");
return EINVAL;
}
if (!gDeviceFileSystem) {
panic("devfs_publish_device called before devfs mounted\n");
return ERR_GENERAL;
}
@ -1116,16 +1125,16 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
strncpy(temp, path, SYS_MAX_PATH_LEN);
temp[SYS_MAX_PATH_LEN] = 0;
mutex_lock(&thedevfs->lock);
mutex_lock(&gDeviceFileSystem->lock);
// create the path leading to the device
// parse the path passed in, stripping out '/'
dir = thedevfs->root_vnode;
dir = gDeviceFileSystem->root_vnode;
v = NULL;
i = 0;
last = 0;
at_leaf = false;
for(;;) {
for (;;) {
if(temp[i] == 0) {
at_leaf = true; // we'll be done after this one
} else if(temp[i] == '/') {
@ -1141,10 +1150,10 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
// we have a path component
v = devfs_find_in_dir(dir, &temp[last]);
if (v) {
if(!at_leaf) {
if (!at_leaf) {
// we are not at the leaf of the path, so as long as
// this is a dir we're okay
if(v->stream.type == STREAM_TYPE_DIR) {
if (v->stream.type == STREAM_TYPE_DIR) {
last = i;
dir = v;
continue;
@ -1156,8 +1165,8 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
err = ERR_VFS_ALREADY_EXISTS;
goto err;
} else {
v = devfs_create_vnode(thedevfs, &temp[last]);
if(!v) {
v = devfs_create_vnode(gDeviceFileSystem, &temp[last]);
if (!v) {
err = ENOMEM;
goto err;
}
@ -1176,7 +1185,7 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
v->stream.u.dir.jar_head = NULL;
}
hash_insert(thedevfs->vnode_list_hash, v);
hash_insert(gDeviceFileSystem->vnode_list_hash, v);
devfs_insert_in_dir(dir, v);
@ -1187,7 +1196,7 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
}
err:
mutex_unlock(&thedevfs->lock);
mutex_unlock(&gDeviceFileSystem->lock);
return err;
}

View File

@ -112,12 +112,12 @@ rootfs_delete_vnode(struct rootfs *fs, struct rootfs_vnode *v, bool force_delete
// cant delete it if it's in a directory or is a directory
// and has children
if (!force_delete && (v->stream.dir.dir_head != NULL || v->dir_next != NULL))
return ERR_NOT_ALLOWED;
return EPERM;
// remove it from the global hash table
hash_remove(fs->vnode_list_hash, v);
if(v->name != NULL)
if (v->name != NULL)
kfree(v->name);
kfree(v);
@ -221,10 +221,8 @@ rootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id
TRACE(("rootfs_mount: entry\n"));
fs = kmalloc(sizeof(struct rootfs));
if(fs == NULL) {
err = ERR_NO_MEMORY;
goto err;
}
if (fs == NULL)
return ENOMEM;
fs->id = id;
fs->next_vnode_id = 0;
@ -236,23 +234,23 @@ rootfs_mount(fs_cookie *_fs, fs_id id, const char *device, void *args, vnode_id
fs->vnode_list_hash = hash_init(ROOTFS_HASH_SIZE, (addr)&v->all_next - (addr)v,
&rootfs_vnode_compare_func, &rootfs_vnode_hash_func);
if(fs->vnode_list_hash == NULL) {
err = ERR_NO_MEMORY;
if (fs->vnode_list_hash == NULL) {
err = ENOMEM;
goto err2;
}
// create a vnode
v = rootfs_create_vnode(fs);
if(v == NULL) {
err = ERR_NO_MEMORY;
if (v == NULL) {
err = ENOMEM;
goto err3;
}
// set it up
v->parent = v;
v->name = kstrdup("");
if(v->name == NULL) {
err = ERR_NO_MEMORY;
if (v->name == NULL) {
err = ENOMEM;
goto err4;
}
@ -273,7 +271,7 @@ err2:
mutex_destroy(&fs->lock);
err1:
kfree(fs);
err:
return err;
}
@ -357,20 +355,20 @@ rootfs_get_vnode(fs_cookie _fs, vnode_id id, fs_vnode *v, bool r)
TRACE(("rootfs_getvnode: asking for vnode 0x%x 0x%x, r %d\n", id, r));
if(!r)
if (!r)
mutex_lock(&fs->lock);
*v = hash_lookup(fs->vnode_list_hash, &id);
if(!r)
if (!r)
mutex_unlock(&fs->lock);
TRACE(("rootfs_getnvnode: looked it up at 0x%x\n", *v));
if(*v)
return 0;
else
return ERR_NOT_FOUND;
if (*v)
return B_NO_ERROR;
return ENOENT;
}
@ -477,41 +475,14 @@ rootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_
{
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 EPERM;
}
static int
static off_t
rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
{
struct rootfs *fs = _fs;
struct rootfs_vnode *v = _v;
struct rootfs_cookie *cookie = _cookie;
int err = 0;
TRACE(("rootfs_seek: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, seek_type %d\n", v, cookie, pos, st));
mutex_lock(&fs->lock);
switch(st) {
// only valid args are seek_type SEEK_SET, pos 0.
// this rewinds to beginning of directory
case SEEK_SET:
if(pos == 0) {
cookie->ptr = v->stream.dir.dir_head;
} else {
err = ESPIPE;
}
break;
case SEEK_CUR:
case SEEK_END:
default:
err = EINVAL;
}
mutex_unlock(&fs->lock);
return err;
return ESPIPE;
}

View File

@ -108,15 +108,16 @@ static int vfs_close(struct file_descriptor *, int, struct io_context *);
static int common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
static int common_read_stat(struct file_descriptor *, struct stat *);
static int common_close(struct file_descriptor *, int, struct io_context *);
static ssize_t file_read(struct file_descriptor *, void *, off_t, size_t *);
static ssize_t file_write(struct file_descriptor *, const void *, off_t, size_t *);
static int file_seek(struct file_descriptor *, off_t pos, int seek_type);
static off_t file_seek(struct file_descriptor *, off_t pos, int seek_type);
static status_t dir_read(struct file_descriptor *,struct dirent *buffer,size_t bufferSize,uint32 *_count);
static status_t dir_rewind(struct file_descriptor *);
static void file_free_fd(struct file_descriptor *);
static int file_close(struct file_descriptor *);
static void dir_free_fd(struct file_descriptor *);
static int dir_close(struct file_descriptor *);
static int vfs_open(char *path, int omode, bool kernel);
static int vfs_open_dir(char *path, bool kernel);
@ -132,7 +133,7 @@ struct fd_ops file_ops = {
NULL,
NULL,
common_read_stat,
common_close,
file_close,
file_free_fd
};
@ -145,7 +146,7 @@ struct fd_ops dir_ops = {
dir_read,
dir_rewind,
common_read_stat,
common_close,
dir_close,
dir_free_fd
};
@ -165,10 +166,10 @@ mount_compare(void *_m, const void *_key)
struct fs_mount *mount = _m;
const fs_id *id = _key;
if(mount->id == *id)
if (mount->id == *id)
return 0;
else
return -1;
return -1;
}
@ -178,10 +179,10 @@ mount_hash(void *_m, const void *_key, unsigned int range)
struct fs_mount *mount = _m;
const fs_id *id = _key;
if(mount)
if (mount)
return mount->id % range;
else
return *id % range;
return *id % range;
}
@ -312,7 +313,7 @@ dec_vnode_ref_count(struct vnode *v, bool free_mem, bool r)
old_ref = atomic_add(&v->ref_count, -1);
PRINT(("dec_vnode_ref_count: vnode 0x%x, ref now %d\n", v, v->ref_count));
PRINT(("dec_vnode_ref_count: vnode 0x%p, ref now %d\n", v, v->ref_count));
if (old_ref == 1) {
v->busy = true;
@ -350,7 +351,7 @@ static int
inc_vnode_ref_count(struct vnode *v)
{
atomic_add(&v->ref_count, 1);
PRINT(("inc_vnode_ref_count: vnode 0x%x, ref now %d\n", v, v->ref_count));
PRINT(("inc_vnode_ref_count: vnode 0x%p, ref now %d\n", v, v->ref_count));
return 0;
}
@ -373,7 +374,7 @@ get_vnode(fs_id fsid, vnode_id vnid, struct vnode **outv, int r)
struct vnode *v;
int err;
FUNCTION(("get_vnode: fsid %d vnid 0x%x 0x%x\n", fsid, vnid));
FUNCTION(("get_vnode: fsid %d vnid 0x%Lx 0x%p\n", fsid, vnid,outv));
mutex_lock(&vfs_vnode_mutex);
@ -389,7 +390,7 @@ get_vnode(fs_id fsid, vnode_id vnid, struct vnode **outv, int r)
}
} while(0);
PRINT(("get_vnode: tried to lookup vnode, got 0x%x\n", v));
PRINT(("get_vnode: tried to lookup vnode, got 0x%p\n", v));
if (v) {
inc_vnode_ref_count(v);
@ -428,7 +429,7 @@ get_vnode(fs_id fsid, vnode_id vnid, struct vnode **outv, int r)
mutex_unlock(&vfs_vnode_mutex);
PRINT(("get_vnode: returning 0x%x\n", v));
PRINT(("get_vnode: returning 0x%p\n", v));
*outv = v;
return B_NO_ERROR;
@ -486,7 +487,7 @@ vfs_put_vnode(fs_id fsid, vnode_id vnid)
void
vfs_vnode_acquire_ref(void *v)
{
FUNCTION(("vfs_vnode_acquire_ref: vnode 0x%x\n", v));
FUNCTION(("vfs_vnode_acquire_ref: vnode 0x%p\n", v));
inc_vnode_ref_count((struct vnode *)v);
}
@ -494,7 +495,7 @@ vfs_vnode_acquire_ref(void *v)
void
vfs_vnode_release_ref(void *v)
{
FUNCTION(("vfs_vnode_release_ref: vnode 0x%x\n", v));
FUNCTION(("vfs_vnode_release_ref: vnode 0x%p\n", v));
dec_vnode_ref_count((struct vnode *)v, true, false);
}
@ -538,7 +539,7 @@ file_free_fd(struct file_descriptor *descriptor)
struct vnode *vnode = descriptor->vnode;
if (vnode != NULL) {
FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
//FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
FS_CALL(vnode,fs_free_cookie)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
dec_vnode_ref_count(vnode, true, false);
}
@ -551,7 +552,7 @@ dir_free_fd(struct file_descriptor *descriptor)
struct vnode *vnode = descriptor->vnode;
if (vnode != NULL) {
FS_CALL(vnode,fs_close_dir)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
//FS_CALL(vnode,fs_close_dir)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
FS_CALL(vnode,fs_free_dir_cookie)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
dec_vnode_ref_count(vnode, true, false);
}
@ -942,26 +943,24 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
struct vnode *covered_vnode = NULL;
vnode_id root_id;
#if MAKE_NOIZE
dprintf("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name);
#endif
FUNCTION(("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name));
mutex_lock(&vfs_mount_op_mutex);
mount = (struct fs_mount *)kmalloc(sizeof(struct fs_mount));
if(mount == NULL) {
if (mount == NULL) {
err = ENOMEM;
goto err;
}
mount->mount_point = kstrdup(path);
if(mount->mount_point == NULL) {
if (mount->mount_point == NULL) {
err = ENOMEM;
goto err1;
}
mount->fs = find_fs(fs_name);
if(mount->fs == NULL) {
if (mount->fs == NULL) {
err = ERR_VFS_INVALID_FS;
goto err2;
}
@ -972,13 +971,13 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
if(!root_vnode) {
// we haven't mounted anything yet
if(strcmp(path, "/") != 0) {
if (strcmp(path, "/") != 0) {
err = ERR_VFS_GENERAL;
goto err3;
}
err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id);
if(err < 0) {
if (err < 0) {
err = ERR_VFS_GENERAL;
goto err3;
}
@ -986,18 +985,17 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
mount->covers_vnode = NULL; // this is the root mount
} else {
err = path_to_vnode(path,&covered_vnode,kernel);
if(err < 0) {
if (err < 0)
goto err2;
}
if(!covered_vnode) {
if (!covered_vnode) {
err = ERR_VFS_GENERAL;
goto err2;
}
// XXX insert check to make sure covered_vnode is a DIR, or maybe it's okay for it not to be
if((covered_vnode != root_vnode) && (covered_vnode->mount->root_vnode == covered_vnode)){
if ((covered_vnode != root_vnode) && (covered_vnode->mount->root_vnode == covered_vnode)){
err = ERR_VFS_ALREADY_MOUNTPOINT;
goto err2;
}
@ -1006,7 +1004,7 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
// mount it
err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id);
if(err < 0)
if (err < 0)
goto err4;
}
@ -1018,14 +1016,14 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
mutex_unlock(&vfs_mount_mutex);
err = get_vnode(mount->id, root_id, &mount->root_vnode, 0);
if(err < 0)
if (err < 0)
goto err5;
// XXX may be a race here
if(mount->covers_vnode)
if (mount->covers_vnode)
mount->covers_vnode->covered_by = mount->root_vnode;
if(!root_vnode)
if (!root_vnode)
root_vnode = mount->root_vnode;
mutex_unlock(&vfs_mount_op_mutex);
@ -1035,7 +1033,7 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
err5:
mount->fs->calls->fs_unmount(mount->cookie);
err4:
if(mount->covers_vnode)
if (mount->covers_vnode)
dec_vnode_ref_count(mount->covers_vnode, true, false);
err3:
recursive_lock_destroy(&mount->rlock);
@ -1057,12 +1055,10 @@ vfs_unmount(char *path, bool kernel)
struct fs_mount *mount;
int err;
#if MAKE_NOIZE
dprintf("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel);
#endif
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
err = path_to_vnode(path, &v, kernel);
if(err < 0) {
if (err < 0) {
err = ERR_VFS_PATH_NOT_FOUND;
goto err;
}
@ -1070,11 +1066,10 @@ vfs_unmount(char *path, bool kernel)
mutex_lock(&vfs_mount_op_mutex);
mount = fsid_to_mount(v->fsid);
if(!mount) {
if (!mount)
panic("vfs_unmount: fsid_to_mount failed on root vnode @%p of mount\n", v);
}
if(mount->root_vnode != v) {
if (mount->root_vnode != v) {
// not mountpoint
dec_vnode_ref_count(v, true, false);
err = ERR_VFS_NOT_MOUNTPOINT;
@ -1147,16 +1142,14 @@ vfs_sync(void)
struct hash_iterator iter;
struct fs_mount *mount;
#if MAKE_NOIZE
dprintf("vfs_sync: entry.\n");
#endif
FUNCTION(("vfs_sync: entry.\n"));
/* cycle through and call sync on each mounted fs */
mutex_lock(&vfs_mount_op_mutex);
mutex_lock(&vfs_mount_mutex);
hash_open(mounts_table, &iter);
while((mount = hash_next(mounts_table, &iter))) {
while ((mount = hash_next(mounts_table, &iter))) {
mount->fs->calls->fs_sync(mount->cookie);
}
hash_close(mounts_table, &iter, false);
@ -1200,7 +1193,7 @@ vfs_create(char *path, int omode, int perms, bool kernel)
vnode_id newID;
int status;
FUNCTION(("vfs_create: path '%s', kernel %d\n", path, stream_type, args, kernel));
FUNCTION(("vfs_create: path '%s', omode %x, perms %d, kernel %d\n", path, omode, perms, kernel));
status = path_to_dir_vnode(path, &vnode, filename, kernel);
if (status < 0)
@ -1270,13 +1263,30 @@ err:
static int
common_close(struct file_descriptor *descriptor, int fd, struct io_context *io)
file_close(struct file_descriptor *descriptor)
{
// We don't call fs_close() here, because a forked team might
// have access to the same fd - just remove it from our fd array
remove_fd(io, fd);
struct vnode *vnode = descriptor->vnode;
return 0;
FUNCTION(("file_close(descriptor = %p)\n",descriptor));
if (FS_CALL(vnode,fs_close))
return FS_CALL(vnode,fs_close)(vnode->mount->cookie,vnode->priv_vnode,descriptor->cookie);
return B_OK;
}
static int
dir_close(struct file_descriptor *descriptor)
{
struct vnode *vnode = descriptor->vnode;
FUNCTION(("dir_close(descriptor = %p)\n",descriptor));
if (FS_CALL(vnode,fs_close_dir))
return FS_CALL(vnode,fs_close_dir)(vnode->mount->cookie,vnode->priv_vnode,descriptor->cookie);
return B_OK;
}
@ -1287,9 +1297,7 @@ vfs_fsync(int fd, bool kernel)
struct vnode *v;
int err;
#if MAKE_NOIZE
dprintf("vfs_fsync: entry. fd %d kernel %d\n", fd, kernel);
#endif
FUNCTION(("vfs_fsync: entry. fd %d kernel %d\n", fd, kernel));
f = get_fd(get_current_io_context(kernel), fd);
if (!f)
@ -1309,8 +1317,7 @@ file_read(struct file_descriptor *f, void *buffer, off_t pos, size_t *length)
{
struct vnode *v = f->vnode;
FUNCTION(("vfs_read: fd = %d, buf 0x%x, pos 0x%x 0x%x, len 0x%x, kernel %d\n", fd, buffer, pos, length, kernel));
FUNCTION(("file_read: buf %p, pos %Ld, len 0x%p\n", buffer, pos, length));
return v->mount->fs->calls->fs_read(v->mount->cookie, v->priv_vnode, f->cookie, buffer, pos, length);
}
@ -1320,20 +1327,19 @@ file_write(struct file_descriptor *f, const void *buffer, off_t pos, size_t *len
{
struct vnode *v = f->vnode;
FUNCTION(("vfs_write: fd = %d, buf 0x%x, pos 0x%x 0x%x, len 0x%x\n", fd, buffer, pos, length));
FUNCTION(("file_write: buf %p, pos %Ld, len 0x%p\n", buffer, pos, length));
return v->mount->fs->calls->fs_write(v->mount->cookie, v->priv_vnode, f->cookie, buffer, pos, length);
}
static int
file_seek(struct file_descriptor *descriptor, off_t pos, int seek_type)
static off_t
file_seek(struct file_descriptor *descriptor, off_t pos, int seekType)
{
struct vnode *vnode = descriptor->vnode;
FUNCTION(("file_seek: fd = %d, pos 0x%x 0x%x, seek_type %d, kernel %d\n", fd, pos, seek_type, kernel));
FUNCTION(("file_seek: pos 0x%Ld, seek_type %d\n", pos, seekType));
return FS_CALL(vnode,fs_seek)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie, pos, seek_type);
return FS_CALL(vnode,fs_seek)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie, pos, seekType);
}
@ -1370,7 +1376,7 @@ vfs_open_dir(char *path, bool kernel)
int status;
int fd;
FUNCTION(("vfs_open_dir: entry. path = '%s', omode %d, kernel %d\n", path, omode, kernel));
FUNCTION(("vfs_open_dir: path = '%s', kernel %d\n", path, kernel));
status = path_to_vnode(path, &vnode, kernel);
if (status < 0)
@ -1396,7 +1402,6 @@ vfs_open_dir(char *path, bool kernel)
status = ERR_VFS_FD_TABLE_FULL;
goto err1;
}
return fd;
err1:
@ -1505,8 +1510,7 @@ common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
{
struct vnode *vnode = descriptor->vnode;
FUNCTION(("vfs_rstat: path '%s', stat 0x%x\n", path, stat));
FUNCTION(("common_read_stat: stat 0x%p\n", stat));
return FS_CALL(vnode,fs_read_stat)(vnode->mount->cookie, vnode->priv_vnode, stat);
}
@ -1517,7 +1521,7 @@ vfs_write_stat(char *path, struct stat *stat, int stat_mask, bool kernel)
struct vnode *vnode;
int status;
FUNCTION(("vfs_wstat: path '%s', stat 0x%x, stat_mask %d, kernel %d\n", path, stat, stat_mask, kernel));
FUNCTION(("vfs_write_stat: path '%s', stat 0x%p, stat_mask %d, kernel %d\n", path, stat, stat_mask, kernel));
status = path_to_vnode(path, &vnode, kernel);
if (status < 0)
@ -1556,15 +1560,13 @@ vfs_get_vnode_from_path(const char *path, bool kernel, void **vnode)
int err;
char buf[SYS_MAX_PATH_LEN+1];
#if MAKE_NOIZE
dprintf("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel);
#endif
PRINT(("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel));
strncpy(buf, path, SYS_MAX_PATH_LEN);
buf[SYS_MAX_PATH_LEN] = 0;
err = path_to_vnode(buf, &v, kernel);
if(err < 0)
if (err < 0)
goto err;
*vnode = v;
@ -1590,7 +1592,7 @@ vfs_can_page(void *_v)
{
struct vnode *vnode = _v;
FUNCTION(("vfs_canpage: vnode 0x%x\n", vnode));
FUNCTION(("vfs_canpage: vnode 0x%p\n", vnode));
if (FS_CALL(vnode,fs_can_page))
return FS_CALL(vnode,fs_can_page)(vnode->mount->cookie, vnode->priv_vnode);
@ -1604,7 +1606,7 @@ vfs_read_page(void *_v, iovecs *vecs, off_t pos)
{
struct vnode *vnode = _v;
FUNCTION(("vfs_readpage: vnode 0x%x, vecs 0x%x, pos 0x%x 0x%x\n", vnode, vecs, pos));
FUNCTION(("vfs_readpage: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos));
return FS_CALL(vnode,fs_read_page)(vnode->mount->cookie, vnode->priv_vnode, vecs, pos);
}
@ -1615,7 +1617,7 @@ vfs_write_page(void *_v, iovecs *vecs, off_t pos)
{
struct vnode *vnode = _v;
FUNCTION(("vfs_writepage: vnode 0x%x, vecs 0x%x, pos 0x%x 0x%x\n", vnode, vecs, pos));
FUNCTION(("vfs_writepage: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos));
return FS_CALL(vnode,fs_write_page)(vnode->mount->cookie, vnode->priv_vnode, vecs, pos);
}
@ -1631,7 +1633,7 @@ vfs_get_cwd(char *buffer, size_t size, bool kernel)
// Get current working directory from io context
struct vnode *cwd = get_current_io_context(kernel)->cwd;
FUNCTION(("vfs_get_cwd: buf 0x%x, 0x%x\n", buffer, size));
FUNCTION(("vfs_get_cwd: buf %p, size %ld\n", buffer, size));
if (cwd)
//
@ -1707,9 +1709,7 @@ vfs_dup(int fd, bool kernel)
struct file_descriptor *f;
int rc;
#if MAKE_NOIZE
dprintf("vfs_dup: fd=%d\n", fd);
#endif
FUNCTION(("vfs_dup: fd = %d\n", fd));
// Try to get the fd structure
f = get_fd(io, fd);
@ -1736,9 +1736,7 @@ vfs_dup2(int ofd, int nfd, bool kernel)
struct file_descriptor *evicted;
int rc;
#if MAKE_NOIZE
dprintf("vfs_dup2: ofd=%d nfd=%d\n", ofd, nfd);
#endif
FUNCTION(("vfs_dup2: ofd = %d, nfd = %d\n", ofd, nfd));
// quick check
if ((ofd < 0) || (nfd < 0)) {
@ -1919,7 +1917,7 @@ sys_read_stat(const char *path, struct stat *stat)
strncpy(buf, path, SYS_MAX_PATH_LEN);
buf[SYS_MAX_PATH_LEN] = 0;
FUNCTION(("sys_rstat: path '%s', stat 0x%x,\n", path, stat));
FUNCTION(("sys_read_stat: path '%s', stat %p,\n", path, stat));
status = path_to_vnode(buf, &vnode, true);
if (status < 0)
@ -1950,9 +1948,7 @@ sys_getcwd(char *buf, size_t size)
char path[SYS_MAX_PATH_LEN];
int rc;
#if MAKE_NOIZE
dprintf("sys_getcwd: buf 0x%x, 0x%x\n", buf, size);
#endif
PRINT(("sys_getcwd: buf %p, %ld\n", buf, size));
// Call vfs to get current working directory
rc = vfs_get_cwd(path,SYS_MAX_PATH_LEN-1,true);
@ -1967,13 +1963,11 @@ sys_getcwd(char *buf, size_t size)
int
sys_setcwd(const char* _path)
sys_setcwd(const char *_path)
{
char path[SYS_MAX_PATH_LEN];
#if MAKE_NOIZE
dprintf("sys_setcwd: path=0x%x\n", _path);
#endif
PRINT(("sys_setcwd: path = %s\n", _path));
// Copy new path to kernel space
strncpy(path, _path, SYS_MAX_PATH_LEN-1);
@ -2259,9 +2253,7 @@ user_getcwd(char *buf, size_t size)
char path[SYS_MAX_PATH_LEN];
int rc, rc2;
#if MAKE_NOIZE
dprintf("user_getcwd: buf 0x%x, 0x%x\n", buf, size);
#endif
PRINT(("user_getcwd: buf %p, %ld\n", buf, size));
// Check if userspace address is inside "shared" kernel space
if((addr)buf >= KERNEL_BASE && (addr)buf <= KERNEL_TOP)
@ -2282,14 +2274,12 @@ user_getcwd(char *buf, size_t size)
int
user_setcwd(const char* upath)
user_setcwd(const char *upath)
{
char path[SYS_MAX_PATH_LEN];
int rc;
#if MAKE_NOIZE
dprintf("user_setcwd: path=0x%x\n", upath);
#endif
PRINT(("user_setcwd: path = %p\n", upath));
// Check if userspace address is inside "shared" kernel space
if((addr)upath >= KERNEL_BASE && (addr)upath <= KERNEL_TOP)
@ -2297,9 +2287,9 @@ user_setcwd(const char* upath)
// Copy new path to kernel space
rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN-1);
if (rc < 0) {
if (rc < 0)
return rc;
}
path[SYS_MAX_PATH_LEN-1] = 0;
// Call vfs to set new working directory
@ -2458,9 +2448,7 @@ vfs_test(void)
sys_seek(fd, 0, SEEK_SET);
for (;;) {
len = sys_read(fd, buf, -1, sizeof(buf));
// if(len <= 0)
// panic("readdir returned %Ld\n", (long long)len);
if(len > 0)
if (len > 0)
dprintf("readdir returned name = '%s'\n", buf);
else {
dprintf("readdir returned %s\n", strerror(len));
@ -2488,23 +2476,24 @@ vfs_test(void)
#endif
#if 1
fd = sys_open("/boot", STREAM_TYPE_DIR, 0);
fd = sys_open_dir("/boot");
sys_close(fd);
fd = sys_open("/boot", STREAM_TYPE_DIR, 0);
if(fd < 0)
fd = sys_open_dir("/boot");
if (fd < 0)
panic("unable to open dir /boot\n");
{
char buf[64];
char buf[256];
struct dirent *dirent = (struct dirent *)buf;
ssize_t len;
sys_seek(fd, 0, SEEK_SET);
for(;;) {
len = sys_read(fd, buf, -1, sizeof(buf));
sys_rewind_dir(fd);
for (;;) {
len = sys_read_dir(fd, dirent, sizeof(buf), 1);
// if(len < 0)
// panic("readdir returned %Ld\n", (long long)len);
if(len > 0)
dprintf("sys_read returned name = '%s'\n", buf);
if (len > 0)
dprintf("sys_read returned name = '%s'\n", dirent->d_name);
else {
dprintf("sys_read returned %s\n", strerror(len));
break;
@ -2513,15 +2502,15 @@ vfs_test(void)
}
sys_close(fd);
fd = sys_open("/boot/kernel", STREAM_TYPE_FILE, 0);
if(fd < 0)
fd = sys_open("/boot/kernel", O_RDONLY);
if (fd < 0)
panic("unable to open kernel file '/boot/kernel'\n");
{
char buf[64];
ssize_t len;
len = sys_read(fd, buf, 0, sizeof(buf));
if(len < 0)
if (len < 0)
panic("failed on read\n");
dprintf("read returned %Ld\n", (long long)len);
}
@ -2529,8 +2518,8 @@ vfs_test(void)
{
struct stat stat;
err = sys_rstat("/boot/kernel", &stat);
if(err < 0)
err = sys_read_stat("/boot/kernel", &stat);
if (err < 0)
panic("err stating '/boot/kernel'\n");
dprintf("stat results:\n");
dprintf("\tvnid 0x%Lx\n\ttype %d\n\tsize 0x%Lx\n", stat.st_ino, stat.st_mode, stat.st_size);
@ -2538,7 +2527,6 @@ vfs_test(void)
#endif
dprintf("vfs_test() done\n");
// panic("foo\n");
return 0;
}
@ -2555,11 +2543,11 @@ vfs_load_fs_module(const char *name)
// sprintf(path, "/boot/addons/fs/%s", name);
id = elf_load_kspace(path, "");
if(id < 0)
if (id < 0)
return id;
bootstrap = (void *)elf_lookup_symbol(id, "fs_bootstrap");
if(!bootstrap)
if (!bootstrap)
return ERR_VFS_INVALID_FS;
bootstrap();
@ -2621,7 +2609,7 @@ vfs_register_filesystem(const char *name, struct fs_calls *calls)
struct fs_container *container;
container = (struct fs_container *)kmalloc(sizeof(struct fs_container));
if(container == NULL)
if (container == NULL)
return ENOMEM;
container->name = name;
@ -2644,29 +2632,29 @@ vfs_init(kernel_args *ka)
struct vnode *v;
vnode_table = hash_init(VNODE_HASH_TABLE_SIZE, (addr)&v->next - (addr)v,
&vnode_compare, &vnode_hash);
if(vnode_table == NULL)
if (vnode_table == NULL)
panic("vfs_init: error creating vnode hash table\n");
}
{
struct fs_mount *mount;
mounts_table = hash_init(MOUNTS_HASH_TABLE_SIZE, (addr)&mount->next - (addr)mount,
&mount_compare, &mount_hash);
if(mounts_table == NULL)
if (mounts_table == NULL)
panic("vfs_init: error creating mounts hash table\n");
}
fs_list = NULL;
root_vnode = NULL;
if(mutex_init(&vfs_mutex, "vfs_lock") < 0)
if (mutex_init(&vfs_mutex, "vfs_lock") < 0)
panic("vfs_init: error allocating vfs lock\n");
if(mutex_init(&vfs_mount_op_mutex, "vfs_mount_op_lock") < 0)
if (mutex_init(&vfs_mount_op_mutex, "vfs_mount_op_lock") < 0)
panic("vfs_init: error allocating vfs_mount_op lock\n");
if(mutex_init(&vfs_mount_mutex, "vfs_mount_lock") < 0)
if (mutex_init(&vfs_mount_mutex, "vfs_mount_lock") < 0)
panic("vfs_init: error allocating vfs_mount lock\n");
if(mutex_init(&vfs_vnode_mutex, "vfs_vnode_lock") < 0)
if (mutex_init(&vfs_vnode_mutex, "vfs_vnode_lock") < 0)
panic("vfs_init: error allocating vfs_vnode lock\n");
return 0;