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:
parent
b46f99148e
commit
243d156e21
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user