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
+55 -36
View File
@@ -23,12 +23,31 @@
return EINVAL; 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 ***/ /*** 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 */ /** Allocates and initializes a new file_descriptor */
struct file_descriptor * struct file_descriptor *
@@ -41,6 +60,7 @@ alloc_fd(void)
f->vnode = NULL; f->vnode = NULL;
f->cookie = NULL; f->cookie = NULL;
f->ref_count = 1; f->ref_count = 1;
f->dummy = 0xdeadbeef;
} }
return f; return f;
} }
@@ -76,15 +96,18 @@ err:
void 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 /* 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 we've just removed the final reference to it :)
*/ */
if (atomic_add(&f->ref_count, -1) == 1) { if (atomic_add(&descriptor->ref_count, -1) == 1) {
if (f->ops->fd_free) if (descriptor->ops->fd_close)
f->ops->fd_free(f); descriptor->ops->fd_close(descriptor);
kfree(f); 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); mutex_unlock(&ioctx->io_mutex);
return f; return f;
} }
@@ -185,23 +209,24 @@ user_write(int fd, const void *buffer, off_t pos, size_t length)
} }
int off_t
user_seek(int fd, off_t pos, int seek_type) user_seek(int fd, off_t pos, int seekType)
{ {
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
int status;
descriptor = get_fd(get_current_io_context(false), fd); descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor) if (!descriptor)
return EBADF; return EBADF;
TRACE(("user_seek(descriptor = %p)\n",descriptor));
if (descriptor->ops->fd_seek) if (descriptor->ops->fd_seek)
status = descriptor->ops->fd_seek(descriptor, pos, seek_type); pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
else else
status = EOPNOTSUPP; pos = ESPIPE;
put_fd(descriptor); put_fd(descriptor);
return status; return pos;
} }
@@ -291,6 +316,8 @@ user_fstat(int fd, struct stat *stat)
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
TRACE(("user_fstat(descriptor = %p)\n",descriptor));
if (descriptor->ops->fd_stat) { if (descriptor->ops->fd_stat) {
// we're using the stat buffer on the stack to not have to // we're using the stat buffer on the stack to not have to
// lock the given stat buffer in memory // lock the given stat buffer in memory
@@ -310,20 +337,18 @@ user_fstat(int fd, struct stat *stat)
int int
user_close(int fd) user_close(int fd)
{ {
struct io_context *ioContext = get_current_io_context(false); struct io_context *io = get_current_io_context(false);
struct file_descriptor *descriptor = get_fd(ioContext, fd); struct file_descriptor *descriptor = get_fd(io, fd);
int retval;
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
if (descriptor->ops->fd_close) TRACE(("user_close(descriptor = %p)\n",descriptor));
retval = descriptor->ops->fd_close(descriptor, fd, ioContext);
else remove_fd(io, fd);
retval = EOPNOTSUPP;
put_fd(descriptor); 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; struct file_descriptor *descriptor;
ssize_t retval; ssize_t retval;
// dprintf("sys_write: fd %d\n", fd);
// CHECK_SYS_ADDR(buffer) // CHECK_SYS_ADDR(buffer)
descriptor = get_fd(get_current_io_context(true), fd); 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 off_t
sys_seek(int fd, off_t pos, int seek_type) sys_seek(int fd, off_t pos, int seekType)
{ {
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
int status;
descriptor = get_fd(get_current_io_context(true), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor) if (!descriptor)
return EBADF; return EBADF;
if (descriptor->ops->fd_seek) if (descriptor->ops->fd_seek)
status = descriptor->ops->fd_seek(descriptor, pos, seek_type); pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
else else
status = EOPNOTSUPP; pos = ESPIPE;
put_fd(descriptor); put_fd(descriptor);
return status; return pos;
} }
@@ -460,7 +483,7 @@ sys_rewind_dir(int fd)
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
status_t status; 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); descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL) if (descriptor == NULL)
@@ -479,19 +502,15 @@ sys_rewind_dir(int fd)
int int
sys_close(int fd) sys_close(int fd)
{ {
struct io_context *ioContext = get_current_io_context(true); struct io_context *io = get_current_io_context(true);
struct file_descriptor *descriptor = get_fd(ioContext, fd); struct file_descriptor *descriptor = get_fd(io, fd);
int status;
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
if (descriptor->ops->fd_close) remove_fd(io, fd);
status = descriptor->ops->fd_close(descriptor, fd, ioContext);
else
status = EOPNOTSUPP;
put_fd(descriptor); put_fd(descriptor);
return status; return B_OK;
} }
+35 -51
View File
@@ -581,7 +581,7 @@ bootfs_removevnode(fs_cookie _fs, fs_vnode _v, bool r)
err = 0; err = 0;
err: err:
if(!r) if (!r)
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
return err; return err;
@@ -714,73 +714,57 @@ bootfs_write(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_
} }
static int static off_t
bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) bootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int seekType)
{ {
struct bootfs *fs = _fs; struct bootfs *fs = _fs;
struct bootfs_vnode *v = _v; struct bootfs_vnode *v = _v;
struct bootfs_cookie *cookie = _cookie; 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)); 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); mutex_lock(&fs->lock);
switch(cookie->s->type) { switch (seekType) {
case STREAM_TYPE_DIR: case SEEK_SET:
switch(st) { if (pos < 0)
// only valid args are seek_type SEEK_SET, pos 0. pos = 0;
// this rewinds to beginning of directory if (pos > cookie->s->u.file.len)
case SEEK_SET: pos = cookie->s->u.file.len;
if(pos == 0) { cookie->u.file.pos = pos;
cookie->u.dir.ptr = cookie->s->u.dir.dir_head;
} else {
err = ESPIPE;
}
break;
case SEEK_CUR:
case SEEK_END:
default:
err = ESPIPE;
}
break; break;
case STREAM_TYPE_FILE: case SEEK_CUR:
switch(st) { if (pos + cookie->u.file.pos > cookie->s->u.file.len)
case SEEK_SET: pos = cookie->s->u.file.len;
if(pos < 0) else if (pos + cookie->u.file.pos < 0)
pos = 0; pos = 0;
if(pos > cookie->s->u.file.len) else
pos = cookie->s->u.file.len; pos += cookie->u.file.pos;
cookie->u.file.pos = pos; break;
break; case SEEK_END:
case SEEK_CUR: if (pos > 0)
if(pos + cookie->u.file.pos > cookie->s->u.file.len) pos = cookie->s->u.file.len;
cookie->u.file.pos = cookie->s->u.file.len; else if (pos + cookie->s->u.file.len < 0)
else if(pos + cookie->u.file.pos < 0) pos = 0;
cookie->u.file.pos = 0; else
else pos += cookie->s->u.file.len;
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;
}
break; break;
default: default:
err = EINVAL; err = EINVAL;
} }
if (err == B_OK)
cookie->u.file.pos = pos;
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
return err; if (err < B_OK)
return err;
return pos;
} }
+179 -170
View File
@@ -27,9 +27,11 @@
#define DEVFS_TRACE 0 #define DEVFS_TRACE 0
#if DEVFS_TRACE #if DEVFS_TRACE
#define TRACE(x) dprintf x # define TRACE(x) dprintf x
# define INSANE(x) dprintf x
#else #else
#define TRACE(x) # define TRACE(x)
# define INSANE(x)
#endif #endif
struct devfs_part_map { struct devfs_part_map {
@@ -51,7 +53,7 @@ struct devfs_stream {
struct devfs_cookie *jar_head; struct devfs_cookie *jar_head;
} dir; } dir;
struct stream_dev { struct stream_dev {
void * ident; void *ident;
device_hooks *calls; device_hooks *calls;
struct devfs_part_map *part_map; struct devfs_part_map *part_map;
} dev; } dev;
@@ -77,7 +79,7 @@ struct devfs {
}; };
struct devfs_cookie { struct devfs_cookie {
struct devfs_stream *s; struct devfs_stream *stream;
int oflags; int oflags;
union { union {
struct cookie_dir { struct cookie_dir {
@@ -92,7 +94,7 @@ struct devfs_cookie {
}; };
/* the one and only allowed devfs instance */ /* the one and only allowed devfs instance */
static struct devfs *thedevfs = NULL; static struct devfs *gDeviceFileSystem = NULL;
#define BOOTFS_HASH_SIZE 16 #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; struct devfs_vnode *v = _v;
const vnode_id *key = _key; const vnode_id *key = _key;
if(v != NULL) if (v != NULL)
return v->id % range; return v->id % range;
else
return (*key) % range; return (*key) % range;
} }
@@ -116,10 +118,10 @@ devfs_vnode_compare_func(void *_v, const void *_key)
struct devfs_vnode *v = _v; struct devfs_vnode *v = _v;
const vnode_id *key = _key; const vnode_id *key = _key;
if(v->id == *key) if (v->id == *key)
return 0; return 0;
else
return -1; return -1;
} }
@@ -129,14 +131,14 @@ devfs_create_vnode(struct devfs *fs, const char *name)
struct devfs_vnode *v; struct devfs_vnode *v;
v = kmalloc(sizeof(struct devfs_vnode)); v = kmalloc(sizeof(struct devfs_vnode));
if(v == NULL) if (v == NULL)
return NULL; return NULL;
memset(v, 0, sizeof(struct devfs_vnode)); memset(v, 0, sizeof(struct devfs_vnode));
v->id = fs->next_vnode_id++; v->id = fs->next_vnode_id++;
v->name = kstrdup(name); v->name = kstrdup(name);
if(v->name == NULL) { if (v->name == NULL) {
kfree(v); kfree(v);
return NULL; 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 // cant delete it if it's in a directory or is a directory
// and has children // 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; return EPERM;
}
// remove it from the global hash table // remove it from the global hash table
hash_remove(fs->vnode_list_hash, v); hash_remove(fs->vnode_list_hash, v);
// TK: for partitions, we have to release the raw device // TK: for partitions, we have to release the raw device
if( v->stream.type == STREAM_TYPE_DEVICE && v->stream.u.dev.part_map ) 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 ); vfs_put_vnode(fs->id, v->stream.u.dev.part_map->raw_vnode->id);
if(v->name != NULL) if (v->name != NULL)
kfree(v->name); kfree(v->name);
kfree(v); kfree(v);
@@ -198,10 +201,9 @@ update_dircookies(struct devfs_vnode *dir, struct devfs_vnode *v)
{ {
struct devfs_cookie *cookie; struct devfs_cookie *cookie;
for(cookie = dir->stream.u.dir.jar_head; cookie; cookie = cookie->u.dir.next) { for (cookie = dir->stream.u.dir.jar_head; cookie; cookie = cookie->u.dir.next) {
if(cookie->u.dir.ptr == v) { if (cookie->u.dir.ptr == v)
cookie->u.dir.ptr = v->dir_next; 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; struct devfs_vnode *v;
if(dir->stream.type != STREAM_TYPE_DIR) if (dir->stream.type != STREAM_TYPE_DIR)
return NULL; return NULL;
if(!strcmp(path, ".")) if (!strcmp(path, "."))
return dir; return dir;
if(!strcmp(path, "..")) if (!strcmp(path, ".."))
return dir->parent; return dir->parent;
for(v = dir->stream.u.dir.dir_head; v; v = v->dir_next) { 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); INSANE(("devfs_find_in_dir: looking at entry '%s'\n", v->name));
if(strcmp(v->name, path) == 0) { if (strcmp(v->name, path) == 0) {
// dprintf("devfs_find_in_dir: found it at 0x%x\n", v); INSANE(("devfs_find_in_dir: found it at %p\n", v));
return v; return v;
} }
} }
@@ -233,7 +235,7 @@ devfs_find_in_dir(struct devfs_vnode *dir, const char *path)
static int static int
devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v) devfs_insert_in_dir(struct devfs_vnode *dir, struct devfs_vnode *v)
{ {
if(dir->stream.type != STREAM_TYPE_DIR) if (dir->stream.type != STREAM_TYPE_DIR)
return EINVAL; return EINVAL;
v->dir_next = dir->stream.u.dir.dir_head; 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 *v;
struct devfs_vnode *last_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) { for (v = dir->stream.u.dir.dir_head, last_v = NULL; v; last_v = v, v = v->dir_next) {
if(v == findit) { if (v == findit) {
/* make sure all dircookies dont point to this vnode */ /* make sure all dircookies dont point to this vnode */
update_dircookies(dir, v); update_dircookies(dir, v);
if(last_v) if (last_v)
last_v->dir_next = v->dir_next; last_v->dir_next = v->dir_next;
else else
dir->stream.u.dir.dir_head = v->dir_next; 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 static int
devfs_is_dir_empty(struct devfs_vnode *dir) devfs_is_dir_empty(struct devfs_vnode *dir)
{ {
if(dir->stream.type != STREAM_TYPE_DIR) if (dir->stream.type != STREAM_TYPE_DIR)
return false; return false;
return !dir->stream.u.dir.dir_head; 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; devfs_partition_info *info = (devfs_partition_info *)buf;
struct devfs_part_map *part_map = v->stream.u.dev.part_map; struct devfs_part_map *part_map = v->stream.u.dev.part_map;
if( v->stream.type != STREAM_TYPE_DEVICE || part_map == NULL ) if (v->stream.type != STREAM_TYPE_DEVICE || part_map == NULL)
return EINVAL; return EINVAL;
info->offset = part_map->offset; 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; info = *(devfs_partition_info *)buf;
if( v->stream.type != STREAM_TYPE_DEVICE ) if (v->stream.type != STREAM_TYPE_DEVICE)
return EINVAL; return EINVAL;
// we don't support nested partitions // we don't support nested partitions
if( v->stream.u.dev.part_map ) if (v->stream.u.dev.part_map)
return EINVAL; return EINVAL;
// reduce checks to a minimum - things like negative offsets could be useful // reduce checks to a minimum - things like negative offsets could be useful
if( info.size < 0) if (info.size < 0)
return EINVAL; return EINVAL;
// create partition map // create partition map
part_map = kmalloc( sizeof( *part_map )); part_map = kmalloc(sizeof(*part_map));
if( !part_map ) if (!part_map)
return ENOMEM; return ENOMEM;
part_map->offset = info.offset; 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->session = info.session;
part_map->partition = info.partition; 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 // 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; res = EINVAL;
goto err1; goto err1;
} }
@@ -345,14 +348,14 @@ static int devfs_set_partition( struct devfs *fs, struct devfs_vnode *v,
// increase reference count of raw device - // increase reference count of raw device -
// the partition device really needs it // the partition device really needs it
// (at least to resolve its name on GET_PARTITION_INFO) // (at least to resolve its name on GET_PARTITION_INFO)
res = vfs_get_vnode( fs->id, v->id, (fs_vnode *)&part_map->raw_vnode ); res = vfs_get_vnode(fs->id, v->id, (fs_vnode *)&part_map->raw_vnode);
if( res < 0 ) if (res < 0)
goto err1; goto err1;
// now create the partition node // 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; res = ENOMEM;
goto err2; 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.calls = v->stream.u.dev.calls;
part_node->stream.u.dev.part_map = part_map; 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; return B_NO_ERROR;
err1: err1:
mutex_unlock(&thedevfs->lock); mutex_unlock(&gDeviceFileSystem->lock);
kfree( part_map ); kfree(part_map);
return res; return res;
err2: err2:
mutex_unlock(&thedevfs->lock); mutex_unlock(&gDeviceFileSystem->lock);
vfs_put_vnode( fs->id, v->id ); vfs_put_vnode(fs->id, v->id);
kfree( part_map ); kfree(part_map);
return res; 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")); TRACE(("devfs_mount: entry\n"));
if (thedevfs) { if (gDeviceFileSystem) {
dprintf("double mount of devfs attempted\n"); dprintf("double mount of devfs attempted\n");
err = ERR_GENERAL; err = ERR_GENERAL;
goto err; 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; *root_vnid = v->id;
*_fs = fs; *_fs = fs;
thedevfs = fs; gDeviceFileSystem = fs;
return 0; return 0;
@@ -470,7 +473,7 @@ devfs_unmount(fs_cookie _fs)
struct devfs_vnode *v; struct devfs_vnode *v;
struct hash_iterator i; 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 // delete all of the vnodes
hash_open(fs->vnode_list_hash, &i); 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 *fs = (struct devfs *)_fs;
struct devfs_vnode *dir = (struct devfs_vnode *)_dir; struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
struct devfs_vnode *v; struct devfs_vnode *vnode;
struct devfs_vnode *v1; struct devfs_vnode *vdummy;
int err; 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; return ENOTDIR;
mutex_lock(&fs->lock); mutex_lock(&fs->lock);
// look it up // look it up
v = devfs_find_in_dir(dir, name); vnode = devfs_find_in_dir(dir, name);
if(!v) { if (!vnode) {
err = ERR_NOT_FOUND; err = ERR_NOT_FOUND;
goto err; goto err;
} }
err = vfs_get_vnode(fs->id, v->id, (fs_vnode *)&v1); err = vfs_get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
if(err < 0) { if (err < 0)
goto err; goto err;
}
*id = v->id; *id = vnode->id;
err = B_NO_ERROR;
err: err:
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
INSANE(("--devfs_lookup: returns %d\n",err));
return err; return err;
} }
static int 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; 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); 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); 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; return 0;
else
return ERR_NOT_FOUND; return ERR_NOT_FOUND;
} }
static int 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 #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 #endif
return 0; // whatever return 0; // whatever
@@ -573,30 +574,27 @@ devfs_put_vnode(fs_cookie _fs, fs_vnode _v, bool r)
static int 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 *fs = (struct devfs *)_fs;
struct devfs_vnode *v = (struct devfs_vnode *)_v; struct devfs_vnode *vnode = (struct devfs_vnode *)_v;
int err;
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); mutex_lock(&fs->lock);
if(v->dir_next) { if (vnode->dir_next) {
// can't remove node if it's linked to the dir // 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 (!reenter)
if(!r)
mutex_unlock(&fs->lock); 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; struct devfs_cookie *cookie;
int status = 0; 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)); cookie = kmalloc(sizeof(struct devfs_cookie));
if (cookie == NULL) if (cookie == NULL)
return ENOMEM; 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); status = vnode->stream.u.dev.calls->open(vnode->name, oflags, &cookie->u.dev.dcookie);
*_cookie = cookie; *_cookie = cookie;
INSANE(("cool!\n"));
return status; return status;
} }
@@ -634,7 +643,7 @@ devfs_close(fs_cookie _fs, fs_vnode _v, file_cookie _cookie)
struct devfs_vnode *vnode = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; 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) { if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying 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_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; 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) { if (vnode->stream.type == STREAM_TYPE_DEVICE) {
// pass the call through to the underlying 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_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
struct devfs_part_map *part_map; 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) INSANE(("juchu, buffer = %p!\n",buffer));
return EINVAL; // 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; part_map = vnode->stream.u.dev.part_map;
if (part_map) { if (part_map) {
if( pos < 0 ) if (pos < 0)
pos = 0; pos = 0;
if (pos > part_map->size) if (pos > part_map->size)
@@ -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 // 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, devfs_write(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, const void *buf,
off_t pos, size_t *len) off_t pos, size_t *len)
{ {
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
TRACE(("devfs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v, cookie, pos, len)); TRACE(("devfs_write: vnode %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) { if (vnode->stream.type == STREAM_TYPE_DEVICE) {
struct devfs_part_map *part_map = v->stream.u.dev.part_map; struct devfs_part_map *part_map = vnode->stream.u.dev.part_map;
int written;
if (part_map) { if (part_map) {
if (pos < 0) 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; 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 static off_t
devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st) devfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int seekType)
{ {
#ifdef DEBUG
struct devfs *fs = _fs; struct devfs *fs = _fs;
struct devfs_vnode *v = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie = _cookie; struct devfs_cookie *cookie = _cookie;
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) { return ESPIPE;
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;
} }
@@ -787,7 +783,7 @@ devfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
struct devfs_vnode *vnode = _v; struct devfs_vnode *vnode = _v;
struct devfs_cookie *cookie; 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) if (vnode->stream.type != STREAM_TYPE_DIR)
return EINVAL; return EINVAL;
@@ -798,7 +794,7 @@ devfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
mutex_lock(&fs->lock); mutex_lock(&fs->lock);
cookie->s = &vnode->stream; cookie->stream = &vnode->stream;
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head; cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
*_cookie = cookie; *_cookie = cookie;
@@ -814,7 +810,10 @@ devfs_read_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie, struct diren
struct devfs *fs = _fs; struct devfs *fs = _fs;
status_t status = 0; 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); mutex_lock(&fs->lock);
@@ -850,12 +849,16 @@ static int
devfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie) devfs_rewind_dir(fs_cookie _fs, fs_vnode _vnode, file_cookie _cookie)
{ {
struct devfs *fs = _fs; struct devfs *fs = _fs;
struct devfs_vnode *vnode = _vnode;
struct devfs_cookie *cookie = _cookie; 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); 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); mutex_unlock(&fs->lock);
return B_OK; 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_vnode *v = _v;
struct devfs_cookie *cookie = _cookie; 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) { if (v->stream.type == STREAM_TYPE_DEVICE) {
switch (op) { switch (op) {
case IOCTL_DEVFS_GET_PARTITION_INFO: case IOCTL_DEVFS_GET_PARTITION_INFO:
return devfs_get_partition_info( fs, v, cookie, buf, len ); return devfs_get_partition_info(fs, v, cookie, buf, len);
case IOCTL_DEVFS_SET_PARTITION: case IOCTL_DEVFS_SET_PARTITION:
return devfs_set_partition( fs, v, cookie, buf, len ); return devfs_set_partition(fs, v, cookie, buf, len);
} }
return v->stream.u.dev.calls->control(cookie->u.dev.dcookie, op, buf, len); return v->stream.u.dev.calls->control(cookie->u.dev.dcookie, op, buf, len);
@@ -1008,15 +1011,16 @@ devfs_rename(fs_cookie _fs, fs_vnode _olddir, const char *oldname, fs_vnode _new
static int static int
devfs_read_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat) devfs_read_stat(fs_cookie _fs, fs_vnode _v, struct stat *stat)
{ {
struct devfs_vnode *v = _v; struct devfs_vnode *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_mode = DEFFILEMODE;
stat->st_size = 0; stat->st_size = 0;
if (v->stream.type == STREAM_TYPE_DIR) if (vnode->stream.type == STREAM_TYPE_DIR)
stat->st_mode |= S_IFDIR; stat->st_mode |= S_IFDIR;
else else
stat->st_mode |= S_IFCHR; 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 #if DEVFS_TRACE
struct devfs_vnode *v = _v; 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 #endif
// cannot change anything // cannot change anything
return EPERM; return EPERM;
@@ -1089,7 +1093,7 @@ int
bootstrap_devfs(void) bootstrap_devfs(void)
{ {
dprintf("bootstrap_devfs: entry\n"); TRACE(("bootstrap_devfs: entry\n"));
return vfs_register_filesystem("devfs", &devfs_calls); 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; struct devfs_vnode *v;
bool at_leaf; 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"); panic("devfs_publish_device called before devfs mounted\n");
return ERR_GENERAL; 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); strncpy(temp, path, SYS_MAX_PATH_LEN);
temp[SYS_MAX_PATH_LEN] = 0; temp[SYS_MAX_PATH_LEN] = 0;
mutex_lock(&thedevfs->lock); mutex_lock(&gDeviceFileSystem->lock);
// create the path leading to the device // create the path leading to the device
// parse the path passed in, stripping out '/' // parse the path passed in, stripping out '/'
dir = thedevfs->root_vnode; dir = gDeviceFileSystem->root_vnode;
v = NULL; v = NULL;
i = 0; i = 0;
last = 0; last = 0;
at_leaf = false; at_leaf = false;
for(;;) { for (;;) {
if(temp[i] == 0) { if(temp[i] == 0) {
at_leaf = true; // we'll be done after this one at_leaf = true; // we'll be done after this one
} else if(temp[i] == '/') { } else if(temp[i] == '/') {
@@ -1141,10 +1150,10 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
// we have a path component // we have a path component
v = devfs_find_in_dir(dir, &temp[last]); v = devfs_find_in_dir(dir, &temp[last]);
if (v) { if (v) {
if(!at_leaf) { if (!at_leaf) {
// we are not at the leaf of the path, so as long as // we are not at the leaf of the path, so as long as
// this is a dir we're okay // this is a dir we're okay
if(v->stream.type == STREAM_TYPE_DIR) { if (v->stream.type == STREAM_TYPE_DIR) {
last = i; last = i;
dir = v; dir = v;
continue; continue;
@@ -1156,8 +1165,8 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
err = ERR_VFS_ALREADY_EXISTS; err = ERR_VFS_ALREADY_EXISTS;
goto err; goto err;
} else { } else {
v = devfs_create_vnode(thedevfs, &temp[last]); v = devfs_create_vnode(gDeviceFileSystem, &temp[last]);
if(!v) { if (!v) {
err = ENOMEM; err = ENOMEM;
goto err; goto err;
} }
@@ -1176,7 +1185,7 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
v->stream.u.dir.jar_head = NULL; 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); devfs_insert_in_dir(dir, v);
@@ -1187,7 +1196,7 @@ devfs_publish_device(const char *path, void *ident, device_hooks *calls)
} }
err: err:
mutex_unlock(&thedevfs->lock); mutex_unlock(&gDeviceFileSystem->lock);
return err; return err;
} }
+20 -49
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 // cant delete it if it's in a directory or is a directory
// and has children // and has children
if (!force_delete && (v->stream.dir.dir_head != NULL || v->dir_next != NULL)) if (!force_delete && (v->stream.dir.dir_head != NULL || v->dir_next != NULL))
return ERR_NOT_ALLOWED; return EPERM;
// remove it from the global hash table // remove it from the global hash table
hash_remove(fs->vnode_list_hash, v); hash_remove(fs->vnode_list_hash, v);
if(v->name != NULL) if (v->name != NULL)
kfree(v->name); kfree(v->name);
kfree(v); 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")); TRACE(("rootfs_mount: entry\n"));
fs = kmalloc(sizeof(struct rootfs)); fs = kmalloc(sizeof(struct rootfs));
if(fs == NULL) { if (fs == NULL)
err = ERR_NO_MEMORY; return ENOMEM;
goto err;
}
fs->id = id; fs->id = id;
fs->next_vnode_id = 0; 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, fs->vnode_list_hash = hash_init(ROOTFS_HASH_SIZE, (addr)&v->all_next - (addr)v,
&rootfs_vnode_compare_func, &rootfs_vnode_hash_func); &rootfs_vnode_compare_func, &rootfs_vnode_hash_func);
if(fs->vnode_list_hash == NULL) { if (fs->vnode_list_hash == NULL) {
err = ERR_NO_MEMORY; err = ENOMEM;
goto err2; goto err2;
} }
// create a vnode // create a vnode
v = rootfs_create_vnode(fs); v = rootfs_create_vnode(fs);
if(v == NULL) { if (v == NULL) {
err = ERR_NO_MEMORY; err = ENOMEM;
goto err3; goto err3;
} }
// set it up // set it up
v->parent = v; v->parent = v;
v->name = kstrdup(""); v->name = kstrdup("");
if(v->name == NULL) { if (v->name == NULL) {
err = ERR_NO_MEMORY; err = ENOMEM;
goto err4; goto err4;
} }
@@ -273,7 +271,7 @@ err2:
mutex_destroy(&fs->lock); mutex_destroy(&fs->lock);
err1: err1:
kfree(fs); kfree(fs);
err:
return 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)); TRACE(("rootfs_getvnode: asking for vnode 0x%x 0x%x, r %d\n", id, r));
if(!r) if (!r)
mutex_lock(&fs->lock); mutex_lock(&fs->lock);
*v = hash_lookup(fs->vnode_list_hash, &id); *v = hash_lookup(fs->vnode_list_hash, &id);
if(!r) if (!r)
mutex_unlock(&fs->lock); mutex_unlock(&fs->lock);
TRACE(("rootfs_getnvnode: looked it up at 0x%x\n", *v)); TRACE(("rootfs_getnvnode: looked it up at 0x%x\n", *v));
if(*v) if (*v)
return 0; return B_NO_ERROR;
else
return ERR_NOT_FOUND; 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)); 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) rootfs_seek(fs_cookie _fs, fs_vnode _v, file_cookie _cookie, off_t pos, int st)
{ {
struct rootfs *fs = _fs; return ESPIPE;
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;
} }
+115 -127
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_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
static int common_read_stat(struct file_descriptor *, struct stat *); 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_read(struct file_descriptor *, void *, off_t, size_t *);
static ssize_t file_write(struct file_descriptor *, const 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_read(struct file_descriptor *,struct dirent *buffer,size_t bufferSize,uint32 *_count);
static status_t dir_rewind(struct file_descriptor *); static status_t dir_rewind(struct file_descriptor *);
static void file_free_fd(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 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(char *path, int omode, bool kernel);
static int vfs_open_dir(char *path, bool kernel); static int vfs_open_dir(char *path, bool kernel);
@@ -132,7 +133,7 @@ struct fd_ops file_ops = {
NULL, NULL,
NULL, NULL,
common_read_stat, common_read_stat,
common_close, file_close,
file_free_fd file_free_fd
}; };
@@ -145,7 +146,7 @@ struct fd_ops dir_ops = {
dir_read, dir_read,
dir_rewind, dir_rewind,
common_read_stat, common_read_stat,
common_close, dir_close,
dir_free_fd dir_free_fd
}; };
@@ -165,10 +166,10 @@ mount_compare(void *_m, const void *_key)
struct fs_mount *mount = _m; struct fs_mount *mount = _m;
const fs_id *id = _key; const fs_id *id = _key;
if(mount->id == *id) if (mount->id == *id)
return 0; 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; struct fs_mount *mount = _m;
const fs_id *id = _key; const fs_id *id = _key;
if(mount) if (mount)
return mount->id % range; 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); 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) { if (old_ref == 1) {
v->busy = true; v->busy = true;
@@ -350,7 +351,7 @@ static int
inc_vnode_ref_count(struct vnode *v) inc_vnode_ref_count(struct vnode *v)
{ {
atomic_add(&v->ref_count, 1); 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; return 0;
} }
@@ -373,7 +374,7 @@ get_vnode(fs_id fsid, vnode_id vnid, struct vnode **outv, int r)
struct vnode *v; struct vnode *v;
int err; 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); mutex_lock(&vfs_vnode_mutex);
@@ -389,7 +390,7 @@ get_vnode(fs_id fsid, vnode_id vnid, struct vnode **outv, int r)
} }
} while(0); } 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) { if (v) {
inc_vnode_ref_count(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); mutex_unlock(&vfs_vnode_mutex);
PRINT(("get_vnode: returning 0x%x\n", v)); PRINT(("get_vnode: returning 0x%p\n", v));
*outv = v; *outv = v;
return B_NO_ERROR; return B_NO_ERROR;
@@ -486,7 +487,7 @@ vfs_put_vnode(fs_id fsid, vnode_id vnid)
void void
vfs_vnode_acquire_ref(void *v) 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); inc_vnode_ref_count((struct vnode *)v);
} }
@@ -494,7 +495,7 @@ vfs_vnode_acquire_ref(void *v)
void void
vfs_vnode_release_ref(void *v) 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); 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; struct vnode *vnode = descriptor->vnode;
if (vnode != NULL) { 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); FS_CALL(vnode,fs_free_cookie)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
dec_vnode_ref_count(vnode, true, false); dec_vnode_ref_count(vnode, true, false);
} }
@@ -551,7 +552,7 @@ dir_free_fd(struct file_descriptor *descriptor)
struct vnode *vnode = descriptor->vnode; struct vnode *vnode = descriptor->vnode;
if (vnode != NULL) { 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); FS_CALL(vnode,fs_free_dir_cookie)(vnode->mount->cookie, vnode->priv_vnode, descriptor->cookie);
dec_vnode_ref_count(vnode, true, false); 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; struct vnode *covered_vnode = NULL;
vnode_id root_id; vnode_id root_id;
#if MAKE_NOIZE FUNCTION(("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name));
dprintf("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name);
#endif
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&vfs_mount_op_mutex);
mount = (struct fs_mount *)kmalloc(sizeof(struct fs_mount)); mount = (struct fs_mount *)kmalloc(sizeof(struct fs_mount));
if(mount == NULL) { if (mount == NULL) {
err = ENOMEM; err = ENOMEM;
goto err; goto err;
} }
mount->mount_point = kstrdup(path); mount->mount_point = kstrdup(path);
if(mount->mount_point == NULL) { if (mount->mount_point == NULL) {
err = ENOMEM; err = ENOMEM;
goto err1; goto err1;
} }
mount->fs = find_fs(fs_name); mount->fs = find_fs(fs_name);
if(mount->fs == NULL) { if (mount->fs == NULL) {
err = ERR_VFS_INVALID_FS; err = ERR_VFS_INVALID_FS;
goto err2; goto err2;
} }
@@ -972,13 +971,13 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
if(!root_vnode) { if(!root_vnode) {
// we haven't mounted anything yet // we haven't mounted anything yet
if(strcmp(path, "/") != 0) { if (strcmp(path, "/") != 0) {
err = ERR_VFS_GENERAL; err = ERR_VFS_GENERAL;
goto err3; goto err3;
} }
err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id); err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id);
if(err < 0) { if (err < 0) {
err = ERR_VFS_GENERAL; err = ERR_VFS_GENERAL;
goto err3; 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 mount->covers_vnode = NULL; // this is the root mount
} else { } else {
err = path_to_vnode(path,&covered_vnode,kernel); err = path_to_vnode(path,&covered_vnode,kernel);
if(err < 0) { if (err < 0)
goto err2; goto err2;
}
if(!covered_vnode) { if (!covered_vnode) {
err = ERR_VFS_GENERAL; err = ERR_VFS_GENERAL;
goto err2; goto err2;
} }
// XXX insert check to make sure covered_vnode is a DIR, or maybe it's okay for it not to be // 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; err = ERR_VFS_ALREADY_MOUNTPOINT;
goto err2; goto err2;
} }
@@ -1006,7 +1004,7 @@ vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool
// mount it // mount it
err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id); err = mount->fs->calls->fs_mount(&mount->cookie, mount->id, device, NULL, &root_id);
if(err < 0) if (err < 0)
goto err4; 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); mutex_unlock(&vfs_mount_mutex);
err = get_vnode(mount->id, root_id, &mount->root_vnode, 0); err = get_vnode(mount->id, root_id, &mount->root_vnode, 0);
if(err < 0) if (err < 0)
goto err5; goto err5;
// XXX may be a race here // XXX may be a race here
if(mount->covers_vnode) if (mount->covers_vnode)
mount->covers_vnode->covered_by = mount->root_vnode; mount->covers_vnode->covered_by = mount->root_vnode;
if(!root_vnode) if (!root_vnode)
root_vnode = mount->root_vnode; root_vnode = mount->root_vnode;
mutex_unlock(&vfs_mount_op_mutex); 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: err5:
mount->fs->calls->fs_unmount(mount->cookie); mount->fs->calls->fs_unmount(mount->cookie);
err4: err4:
if(mount->covers_vnode) if (mount->covers_vnode)
dec_vnode_ref_count(mount->covers_vnode, true, false); dec_vnode_ref_count(mount->covers_vnode, true, false);
err3: err3:
recursive_lock_destroy(&mount->rlock); recursive_lock_destroy(&mount->rlock);
@@ -1057,12 +1055,10 @@ vfs_unmount(char *path, bool kernel)
struct fs_mount *mount; struct fs_mount *mount;
int err; int err;
#if MAKE_NOIZE FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
dprintf("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel);
#endif
err = path_to_vnode(path, &v, kernel); err = path_to_vnode(path, &v, kernel);
if(err < 0) { if (err < 0) {
err = ERR_VFS_PATH_NOT_FOUND; err = ERR_VFS_PATH_NOT_FOUND;
goto err; goto err;
} }
@@ -1070,11 +1066,10 @@ vfs_unmount(char *path, bool kernel)
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&vfs_mount_op_mutex);
mount = fsid_to_mount(v->fsid); 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); 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 // not mountpoint
dec_vnode_ref_count(v, true, false); dec_vnode_ref_count(v, true, false);
err = ERR_VFS_NOT_MOUNTPOINT; err = ERR_VFS_NOT_MOUNTPOINT;
@@ -1147,16 +1142,14 @@ vfs_sync(void)
struct hash_iterator iter; struct hash_iterator iter;
struct fs_mount *mount; struct fs_mount *mount;
#if MAKE_NOIZE FUNCTION(("vfs_sync: entry.\n"));
dprintf("vfs_sync: entry.\n");
#endif
/* cycle through and call sync on each mounted fs */ /* cycle through and call sync on each mounted fs */
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&vfs_mount_op_mutex);
mutex_lock(&vfs_mount_mutex); mutex_lock(&vfs_mount_mutex);
hash_open(mounts_table, &iter); 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); mount->fs->calls->fs_sync(mount->cookie);
} }
hash_close(mounts_table, &iter, false); hash_close(mounts_table, &iter, false);
@@ -1200,7 +1193,7 @@ vfs_create(char *path, int omode, int perms, bool kernel)
vnode_id newID; vnode_id newID;
int status; 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); status = path_to_dir_vnode(path, &vnode, filename, kernel);
if (status < 0) if (status < 0)
@@ -1270,13 +1263,30 @@ err:
static int 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 struct vnode *vnode = descriptor->vnode;
// have access to the same fd - just remove it from our fd array
remove_fd(io, fd);
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; struct vnode *v;
int err; int err;
#if MAKE_NOIZE FUNCTION(("vfs_fsync: entry. fd %d kernel %d\n", fd, kernel));
dprintf("vfs_fsync: entry. fd %d kernel %d\n", fd, kernel);
#endif
f = get_fd(get_current_io_context(kernel), fd); f = get_fd(get_current_io_context(kernel), fd);
if (!f) 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; 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); 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; 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); return v->mount->fs->calls->fs_write(v->mount->cookie, v->priv_vnode, f->cookie, buffer, pos, length);
} }
static int static off_t
file_seek(struct file_descriptor *descriptor, off_t pos, int seek_type) file_seek(struct file_descriptor *descriptor, off_t pos, int seekType)
{ {
struct vnode *vnode = descriptor->vnode; 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 status;
int fd; 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); status = path_to_vnode(path, &vnode, kernel);
if (status < 0) if (status < 0)
@@ -1396,7 +1402,6 @@ vfs_open_dir(char *path, bool kernel)
status = ERR_VFS_FD_TABLE_FULL; status = ERR_VFS_FD_TABLE_FULL;
goto err1; goto err1;
} }
return fd; return fd;
err1: err1:
@@ -1505,8 +1510,7 @@ common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
{ {
struct vnode *vnode = descriptor->vnode; 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); 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; struct vnode *vnode;
int status; 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); status = path_to_vnode(path, &vnode, kernel);
if (status < 0) if (status < 0)
@@ -1556,15 +1560,13 @@ vfs_get_vnode_from_path(const char *path, bool kernel, void **vnode)
int err; int err;
char buf[SYS_MAX_PATH_LEN+1]; char buf[SYS_MAX_PATH_LEN+1];
#if MAKE_NOIZE PRINT(("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel));
dprintf("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel);
#endif
strncpy(buf, path, SYS_MAX_PATH_LEN); strncpy(buf, path, SYS_MAX_PATH_LEN);
buf[SYS_MAX_PATH_LEN] = 0; buf[SYS_MAX_PATH_LEN] = 0;
err = path_to_vnode(buf, &v, kernel); err = path_to_vnode(buf, &v, kernel);
if(err < 0) if (err < 0)
goto err; goto err;
*vnode = v; *vnode = v;
@@ -1590,7 +1592,7 @@ vfs_can_page(void *_v)
{ {
struct vnode *vnode = _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)) if (FS_CALL(vnode,fs_can_page))
return FS_CALL(vnode,fs_can_page)(vnode->mount->cookie, vnode->priv_vnode); 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; 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); 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; 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); 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 // Get current working directory from io context
struct vnode *cwd = get_current_io_context(kernel)->cwd; 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) if (cwd)
// //
@@ -1707,9 +1709,7 @@ vfs_dup(int fd, bool kernel)
struct file_descriptor *f; struct file_descriptor *f;
int rc; int rc;
#if MAKE_NOIZE FUNCTION(("vfs_dup: fd = %d\n", fd));
dprintf("vfs_dup: fd=%d\n", fd);
#endif
// Try to get the fd structure // Try to get the fd structure
f = get_fd(io, fd); f = get_fd(io, fd);
@@ -1736,9 +1736,7 @@ vfs_dup2(int ofd, int nfd, bool kernel)
struct file_descriptor *evicted; struct file_descriptor *evicted;
int rc; int rc;
#if MAKE_NOIZE FUNCTION(("vfs_dup2: ofd = %d, nfd = %d\n", ofd, nfd));
dprintf("vfs_dup2: ofd=%d nfd=%d\n", ofd, nfd);
#endif
// quick check // quick check
if ((ofd < 0) || (nfd < 0)) { 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); strncpy(buf, path, SYS_MAX_PATH_LEN);
buf[SYS_MAX_PATH_LEN] = 0; 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); status = path_to_vnode(buf, &vnode, true);
if (status < 0) if (status < 0)
@@ -1950,9 +1948,7 @@ sys_getcwd(char *buf, size_t size)
char path[SYS_MAX_PATH_LEN]; char path[SYS_MAX_PATH_LEN];
int rc; int rc;
#if MAKE_NOIZE PRINT(("sys_getcwd: buf %p, %ld\n", buf, size));
dprintf("sys_getcwd: buf 0x%x, 0x%x\n", buf, size);
#endif
// Call vfs to get current working directory // Call vfs to get current working directory
rc = vfs_get_cwd(path,SYS_MAX_PATH_LEN-1,true); rc = vfs_get_cwd(path,SYS_MAX_PATH_LEN-1,true);
@@ -1967,13 +1963,11 @@ sys_getcwd(char *buf, size_t size)
int int
sys_setcwd(const char* _path) sys_setcwd(const char *_path)
{ {
char path[SYS_MAX_PATH_LEN]; char path[SYS_MAX_PATH_LEN];
#if MAKE_NOIZE PRINT(("sys_setcwd: path = %s\n", _path));
dprintf("sys_setcwd: path=0x%x\n", _path);
#endif
// Copy new path to kernel space // Copy new path to kernel space
strncpy(path, _path, SYS_MAX_PATH_LEN-1); 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]; char path[SYS_MAX_PATH_LEN];
int rc, rc2; int rc, rc2;
#if MAKE_NOIZE PRINT(("user_getcwd: buf %p, %ld\n", buf, size));
dprintf("user_getcwd: buf 0x%x, 0x%x\n", buf, size);
#endif
// Check if userspace address is inside "shared" kernel space // Check if userspace address is inside "shared" kernel space
if((addr)buf >= KERNEL_BASE && (addr)buf <= KERNEL_TOP) if((addr)buf >= KERNEL_BASE && (addr)buf <= KERNEL_TOP)
@@ -2282,14 +2274,12 @@ user_getcwd(char *buf, size_t size)
int int
user_setcwd(const char* upath) user_setcwd(const char *upath)
{ {
char path[SYS_MAX_PATH_LEN]; char path[SYS_MAX_PATH_LEN];
int rc; int rc;
#if MAKE_NOIZE PRINT(("user_setcwd: path = %p\n", upath));
dprintf("user_setcwd: path=0x%x\n", upath);
#endif
// Check if userspace address is inside "shared" kernel space // Check if userspace address is inside "shared" kernel space
if((addr)upath >= KERNEL_BASE && (addr)upath <= KERNEL_TOP) if((addr)upath >= KERNEL_BASE && (addr)upath <= KERNEL_TOP)
@@ -2297,9 +2287,9 @@ user_setcwd(const char* upath)
// Copy new path to kernel space // Copy new path to kernel space
rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN-1); rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN-1);
if (rc < 0) { if (rc < 0)
return rc; return rc;
}
path[SYS_MAX_PATH_LEN-1] = 0; path[SYS_MAX_PATH_LEN-1] = 0;
// Call vfs to set new working directory // Call vfs to set new working directory
@@ -2458,9 +2448,7 @@ vfs_test(void)
sys_seek(fd, 0, SEEK_SET); sys_seek(fd, 0, SEEK_SET);
for (;;) { for (;;) {
len = sys_read(fd, buf, -1, sizeof(buf)); len = sys_read(fd, buf, -1, sizeof(buf));
// if(len <= 0) if (len > 0)
// panic("readdir returned %Ld\n", (long long)len);
if(len > 0)
dprintf("readdir returned name = '%s'\n", buf); dprintf("readdir returned name = '%s'\n", buf);
else { else {
dprintf("readdir returned %s\n", strerror(len)); dprintf("readdir returned %s\n", strerror(len));
@@ -2488,23 +2476,24 @@ vfs_test(void)
#endif #endif
#if 1 #if 1
fd = sys_open("/boot", STREAM_TYPE_DIR, 0); fd = sys_open_dir("/boot");
sys_close(fd); sys_close(fd);
fd = sys_open("/boot", STREAM_TYPE_DIR, 0); fd = sys_open_dir("/boot");
if(fd < 0) if (fd < 0)
panic("unable to open dir /boot\n"); panic("unable to open dir /boot\n");
{ {
char buf[64]; char buf[256];
struct dirent *dirent = (struct dirent *)buf;
ssize_t len; ssize_t len;
sys_seek(fd, 0, SEEK_SET); sys_rewind_dir(fd);
for(;;) { for (;;) {
len = sys_read(fd, buf, -1, sizeof(buf)); len = sys_read_dir(fd, dirent, sizeof(buf), 1);
// if(len < 0) // if(len < 0)
// panic("readdir returned %Ld\n", (long long)len); // panic("readdir returned %Ld\n", (long long)len);
if(len > 0) if (len > 0)
dprintf("sys_read returned name = '%s'\n", buf); dprintf("sys_read returned name = '%s'\n", dirent->d_name);
else { else {
dprintf("sys_read returned %s\n", strerror(len)); dprintf("sys_read returned %s\n", strerror(len));
break; break;
@@ -2513,15 +2502,15 @@ vfs_test(void)
} }
sys_close(fd); sys_close(fd);
fd = sys_open("/boot/kernel", STREAM_TYPE_FILE, 0); fd = sys_open("/boot/kernel", O_RDONLY);
if(fd < 0) if (fd < 0)
panic("unable to open kernel file '/boot/kernel'\n"); panic("unable to open kernel file '/boot/kernel'\n");
{ {
char buf[64]; char buf[64];
ssize_t len; ssize_t len;
len = sys_read(fd, buf, 0, sizeof(buf)); len = sys_read(fd, buf, 0, sizeof(buf));
if(len < 0) if (len < 0)
panic("failed on read\n"); panic("failed on read\n");
dprintf("read returned %Ld\n", (long long)len); dprintf("read returned %Ld\n", (long long)len);
} }
@@ -2529,8 +2518,8 @@ vfs_test(void)
{ {
struct stat stat; struct stat stat;
err = sys_rstat("/boot/kernel", &stat); err = sys_read_stat("/boot/kernel", &stat);
if(err < 0) if (err < 0)
panic("err stating '/boot/kernel'\n"); panic("err stating '/boot/kernel'\n");
dprintf("stat results:\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); 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 #endif
dprintf("vfs_test() done\n"); dprintf("vfs_test() done\n");
// panic("foo\n");
return 0; return 0;
} }
@@ -2555,11 +2543,11 @@ vfs_load_fs_module(const char *name)
// sprintf(path, "/boot/addons/fs/%s", name); // sprintf(path, "/boot/addons/fs/%s", name);
id = elf_load_kspace(path, ""); id = elf_load_kspace(path, "");
if(id < 0) if (id < 0)
return id; return id;
bootstrap = (void *)elf_lookup_symbol(id, "fs_bootstrap"); bootstrap = (void *)elf_lookup_symbol(id, "fs_bootstrap");
if(!bootstrap) if (!bootstrap)
return ERR_VFS_INVALID_FS; return ERR_VFS_INVALID_FS;
bootstrap(); bootstrap();
@@ -2621,7 +2609,7 @@ vfs_register_filesystem(const char *name, struct fs_calls *calls)
struct fs_container *container; struct fs_container *container;
container = (struct fs_container *)kmalloc(sizeof(struct fs_container)); container = (struct fs_container *)kmalloc(sizeof(struct fs_container));
if(container == NULL) if (container == NULL)
return ENOMEM; return ENOMEM;
container->name = name; container->name = name;
@@ -2644,29 +2632,29 @@ vfs_init(kernel_args *ka)
struct vnode *v; struct vnode *v;
vnode_table = hash_init(VNODE_HASH_TABLE_SIZE, (addr)&v->next - (addr)v, vnode_table = hash_init(VNODE_HASH_TABLE_SIZE, (addr)&v->next - (addr)v,
&vnode_compare, &vnode_hash); &vnode_compare, &vnode_hash);
if(vnode_table == NULL) if (vnode_table == NULL)
panic("vfs_init: error creating vnode hash table\n"); panic("vfs_init: error creating vnode hash table\n");
} }
{ {
struct fs_mount *mount; struct fs_mount *mount;
mounts_table = hash_init(MOUNTS_HASH_TABLE_SIZE, (addr)&mount->next - (addr)mount, mounts_table = hash_init(MOUNTS_HASH_TABLE_SIZE, (addr)&mount->next - (addr)mount,
&mount_compare, &mount_hash); &mount_compare, &mount_hash);
if(mounts_table == NULL) if (mounts_table == NULL)
panic("vfs_init: error creating mounts hash table\n"); panic("vfs_init: error creating mounts hash table\n");
} }
fs_list = NULL; fs_list = NULL;
root_vnode = 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"); 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"); 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"); 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"); panic("vfs_init: error allocating vfs_vnode lock\n");
return 0; return 0;