Updated the code to reflect the changes in the VFS.

Fixed some bugs in fd.c (how many more bugs can be in a small file like this? :-).
Added the syscalls for sys_open_dir(), and sys_create_dir().


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@209 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2002-07-14 05:15:34 +00:00
parent ea536d2ba4
commit 3b120ea240
8 changed files with 122 additions and 65 deletions

View File

@ -2,6 +2,7 @@
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <OS.h> #include <OS.h>
#include <kernel.h> #include <kernel.h>
#include <lock.h> #include <lock.h>
@ -24,6 +25,7 @@ typedef struct bus {
static bus *bus_list; static bus *bus_list;
static mutex bus_lock; static mutex bus_lock;
int bus_man_init(kernel_args *ka) int bus_man_init(kernel_args *ka)
{ {
mutex_init(&bus_lock, "bus_lock"); mutex_init(&bus_lock, "bus_lock");
@ -37,8 +39,8 @@ static bus *find_bus(const char *path)
{ {
bus *b; bus *b;
for(b = bus_list; b != NULL; b = b->next) { for (b = bus_list; b != NULL; b = b->next) {
if(!strcmp(b->path, path)) if (!strcmp(b->path, path))
break; break;
} }
return b; return b;
@ -53,15 +55,15 @@ int bus_register_bus(const char *path)
mutex_lock(&bus_lock); mutex_lock(&bus_lock);
if(!find_bus(path)) { if (!find_bus(path)) {
b = (bus *)kmalloc(sizeof(bus)); b = (bus *)kmalloc(sizeof(bus));
if(b == NULL) { if (b == NULL) {
err = ENOMEM; err = ENOMEM;
goto err; goto err;
} }
b->path = kmalloc(strlen(path)+1); b->path = kmalloc(strlen(path)+1);
if(b->path == NULL) { if (b->path == NULL) {
err = ENOMEM; err = ENOMEM;
kfree(b); kfree(b);
goto err; goto err;
@ -80,51 +82,58 @@ err:
return err; return err;
} }
static int bus_find_device_recurse(int *n, char *base_path, int base_fd, id_list *vendor_ids, id_list *device_ids) static int bus_find_device_recurse(int *n, char *base_path, int max_path_len, int base_fd, id_list *vendor_ids, id_list *device_ids)
{ {
char leaf[256]; char buffer[sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1];
struct dirent *dirent = (struct dirent *)buffer;
int base_path_len = strlen(base_path); int base_path_len = strlen(base_path);
ssize_t len; ssize_t len;
int fd;
int err; int err;
struct stat stat; struct stat stat;
while((len = sys_read(base_fd, &leaf, -1, sizeof(leaf))) > 0) { while ((len = sys_read_dir(base_fd, dirent, sizeof(buffer), 1)) > 0) {
// reset the base_path to the original string passed in int fd;
base_path[base_path_len] = 0;
strlcat(base_path, leaf, sizeof(leaf)); // reset the base_path to the original string passed in
fd = sys_open(base_path, STREAM_TYPE_ANY, 0); base_path[base_path_len] = '\0';
if(fd < 0) dirent->d_name[dirent->d_reclen] = '\0';
strlcat(base_path, dirent->d_name, max_path_len);
err = sys_read_stat(base_path, &stat);
if (err < 0)
continue; continue;
err = sys_rstat(base_path, &stat);
if(err < 0) { if (S_ISDIR(stat.st_mode)) {
fd = sys_open_dir(base_path);
if (fd < 0)
continue;
strlcat(base_path, "/", max_path_len);
err = bus_find_device_recurse(n, base_path, max_path_len, fd, vendor_ids, device_ids);
sys_close(fd); sys_close(fd);
continue; if (err >= 0)
}
if(S_ISDIR(stat.st_mode)) {
strcat(base_path, "/"); /* XXXfreston... this is unsafe!!!! */
err = bus_find_device_recurse(n, base_path, fd, vendor_ids, device_ids);
sys_close(fd);
if(err >= 0)
return err; return err;
continue; continue;
} else if(S_ISREG(stat.st_mode)) { } else if (S_ISREG(stat.st_mode)) {
// we opened the device // we opened the device
// XXX assumes PCI // XXX assumes PCI
struct pci_cfg cfg; struct pci_cfg cfg;
uint32 i, j; uint32 i, j;
fd = sys_open(base_path, 0);
if (fd < 0)
continue;
err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg)); err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg));
if(err >= 0) { if (err >= 0) {
// see if the vendor & device id matches // see if the vendor & device id matches
for(i=0; i<vendor_ids->num_ids; i++) { for (i = 0; i < vendor_ids->num_ids; i++) {
if(cfg.vendor_id == vendor_ids->id[i]) { if (cfg.vendor_id == vendor_ids->id[i]) {
for(j=0; j<device_ids->num_ids; j++) { for (j = 0; j < device_ids->num_ids; j++) {
if(cfg.device_id == device_ids->id[j]) { if (cfg.device_id == device_ids->id[j]) {
// found it // found it
(*n)--; (*n)--;
if(*n <= 0) if (*n <= 0)
return fd; return fd;
} }
} }
@ -145,22 +154,22 @@ int bus_find_device(int n, id_list *vendor_ids, id_list *device_ids, device *dev
bus *b; bus *b;
int err = -1; int err = -1;
for(b = bus_list; b != NULL && err < 0; b = b->next) { for (b = bus_list; b != NULL && err < 0; b = b->next) {
base_fd = sys_open(b->path, STREAM_TYPE_DIR, 0); base_fd = sys_open_dir(b->path);
if(base_fd < 0) if (base_fd < 0)
continue; continue;
strlcpy(path, b->path, sizeof(path)); strlcpy(path, b->path, sizeof(path));
strlcat(path, "/", sizeof(path)); strlcat(path, "/", sizeof(path));
fd = bus_find_device_recurse(&n, path, base_fd, vendor_ids, device_ids); fd = bus_find_device_recurse(&n, path, sizeof(path), base_fd, vendor_ids, device_ids);
if(fd >= 0) { if (fd >= 0) {
// we have a device! // we have a device!
// XXX assumes pci // XXX assumes pci
struct pci_cfg cfg; struct pci_cfg cfg;
int i; int i;
err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg)); err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg));
if(err >= 0) { if (err >= 0) {
// copy the relevant data from the pci config to the more generic config // copy the relevant data from the pci config to the more generic config
memset(dev, 0, sizeof(device)); memset(dev, 0, sizeof(device));
dev->vendor_id = cfg.vendor_id; dev->vendor_id = cfg.vendor_id;

View File

@ -68,7 +68,7 @@ int con_init(kernel_args *ka)
{ {
dprintf("con_init: entry\n"); dprintf("con_init: entry\n");
console_fd = sys_open("/dev/console", STREAM_TYPE_DEVICE, 0); console_fd = sys_open("/dev/console", 0);
dprintf("console_fd = %d\n", console_fd); dprintf("console_fd = %d\n", console_fd);
return 0; return 0;

View File

@ -501,7 +501,7 @@ int elf_load_uspace(const char *path, struct proc *p, int flags, addr *entry)
dprintf("elf_load: entry path '%s', proc %p\n", path, p); dprintf("elf_load: entry path '%s', proc %p\n", path, p);
fd = sys_open(path, STREAM_TYPE_FILE, 0); fd = sys_open(path, 0);
if(fd < 0) if(fd < 0)
return fd; return fd;
@ -669,7 +669,7 @@ image_id elf_load_kspace(const char *path, const char *sym_prepend)
// dprintf("elf_load_kspace: entry path '%s'\n", path); // dprintf("elf_load_kspace: entry path '%s'\n", path);
fd = sys_open(path, STREAM_TYPE_FILE, 0); fd = sys_open(path, 0);
if(fd < 0) if(fd < 0)
return fd; return fd;
@ -907,7 +907,7 @@ int elf_unload_kspace( const char *path )
void *vnode; void *vnode;
struct elf_image_info *image; struct elf_image_info *image;
fd = sys_open(path, STREAM_TYPE_FILE, 0); fd = sys_open(path, 0);
if(fd < 0) if(fd < 0)
return fd; return fd;

View File

@ -37,7 +37,7 @@ alloc_fd(void)
struct file_descriptor *f; struct file_descriptor *f;
f = kmalloc(sizeof(struct file_descriptor)); f = kmalloc(sizeof(struct file_descriptor));
if(f) { if (f) {
f->vnode = NULL; f->vnode = NULL;
f->cookie = NULL; f->cookie = NULL;
f->ref_count = 1; f->ref_count = 1;
@ -185,6 +185,26 @@ user_write(int fd, const void *buffer, off_t pos, size_t length)
} }
int
user_seek(int fd, off_t pos, int seek_type)
{
struct file_descriptor *descriptor;
int status;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return EBADF;
if (descriptor->ops->fd_seek)
status = descriptor->ops->fd_seek(descriptor, pos, seek_type);
else
status = EOPNOTSUPP;
put_fd(descriptor);
return status;
}
int int
user_ioctl(int fd, ulong op, void *buffer, size_t length) user_ioctl(int fd, ulong op, void *buffer, size_t length)
{ {
@ -204,6 +224,7 @@ user_ioctl(int fd, ulong op, void *buffer, size_t length)
else else
status = EOPNOTSUPP; status = EOPNOTSUPP;
put_fd(descriptor);
return status; return status;
} }
@ -364,6 +385,26 @@ sys_write(int fd, const void *buffer, off_t pos, size_t length)
} }
int
sys_seek(int fd, off_t pos, int seek_type)
{
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);
else
status = EOPNOTSUPP;
put_fd(descriptor);
return status;
}
int int
sys_ioctl(int fd, ulong op, void *buffer, size_t length) sys_ioctl(int fd, ulong op, void *buffer, size_t length)
{ {
@ -396,7 +437,7 @@ sys_read_dir(int fd, struct dirent *buffer,size_t bufferSize,uint32 maxCount)
PRINT(("sys_read_dir(fd = %d, buffer = 0x%p, bufferSize = %ld, count = %u)\n",fd,buffer,bufferSize,maxCount)); PRINT(("sys_read_dir(fd = %d, buffer = 0x%p, bufferSize = %ld, count = %u)\n",fd,buffer,bufferSize,maxCount));
descriptor = get_fd(get_current_io_context(false), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
@ -421,7 +462,7 @@ sys_rewind_dir(int fd)
PRINT(("user_rewind_dir(fd = %d)\n",fd)); PRINT(("user_rewind_dir(fd = %d)\n",fd));
descriptor = get_fd(get_current_io_context(false), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;

View File

@ -426,8 +426,8 @@ static int recurse_directory(const char *path, const char *match)
int res = 0, dir; int res = 0, dir;
int bufferSize = sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1; int bufferSize = sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1;
struct dirent *dirent; struct dirent *dirent;
if ((dir = sys_open(path, STREAM_TYPE_DIR, 0)) < 0) if ((dir = sys_open_dir(path)) < 0)
return -1; return -1;
dirent = kmalloc(bufferSize); dirent = kmalloc(bufferSize);
@ -453,7 +453,7 @@ static int recurse_directory(const char *path, const char *match)
strlcat(newpath, "/", slen); strlcat(newpath, "/", slen);
strlcat(newpath, dirent->d_name, slen); strlcat(newpath, dirent->d_name, slen);
if ((res = sys_rstat(newpath, &stat)) != B_NO_ERROR) { if ((res = sys_read_stat(newpath, &stat)) != B_NO_ERROR) {
kfree(newpath); kfree(newpath);
break; break;
} }
@ -663,25 +663,25 @@ static inline int module_create_dir_iterator( module_iterator *iter, int file, c
static inline int module_enter_dir(module_iterator *iter, const char *path) static inline int module_enter_dir(module_iterator *iter, const char *path)
{ {
int file; int dir;
int res; int res;
file = sys_open( path, STREAM_TYPE_DIR, 0 ); dir = sys_open_dir(path);
if (file < 0 ) { if (dir < 0 ) {
SHOW_FLOW( 3, "couldn't open directory %s (%s)\n", path, strerror( file )); SHOW_FLOW(3, "couldn't open directory %s (%s)\n", path, strerror(dir));
// there are so many errors for "not found" that we don't bother // there are so many errors for "not found" that we don't bother
// and always assume that the directory suddenly disappeared // and always assume that the directory suddenly disappeared
return B_NO_ERROR; return B_NO_ERROR;
} }
res = module_create_dir_iterator(iter, file, path); res = module_create_dir_iterator(iter, dir, path);
if (res != B_NO_ERROR) { if (res != B_NO_ERROR) {
sys_close(file); sys_close(dir);
return ENOMEM; return ENOMEM;
} }
SHOW_FLOW( 3, "entered directory %s\n", path ); SHOW_FLOW(3, "entered directory %s\n", path);
return B_NO_ERROR; return B_NO_ERROR;
} }
@ -779,8 +779,8 @@ static inline int module_traverse_dir(module_iterator *iter)
SHOW_FLOW( 3, "got %s\n", name ); SHOW_FLOW( 3, "got %s\n", name );
if (strcmp( name, "." ) == 0 || if (strcmp(name, ".") == 0 ||
strcmp( name, ".." ) == 0 ) strcmp(name, "..") == 0 )
return B_NO_ERROR; return B_NO_ERROR;
/* currently, sys_read returns an error if buffer is too small /* currently, sys_read returns an error if buffer is too small
@ -796,7 +796,7 @@ static inline int module_traverse_dir(module_iterator *iter)
iter->cur_header = NULL; iter->cur_header = NULL;
iter->module_pos = 0; iter->module_pos = 0;
if ((res = sys_rstat(path, &stat)) != B_NO_ERROR ) if ((res = sys_read_stat(path, &stat)) != B_NO_ERROR)
return res; return res;
if (S_ISREG(stat.st_mode)) { if (S_ISREG(stat.st_mode)) {

View File

@ -61,7 +61,7 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
*call_ret = user_sync(); *call_ret = user_sync();
break; break;
case SYSCALL_OPEN: case SYSCALL_OPEN:
*call_ret = user_open((const char *)arg0, (stream_type)arg1, (int)arg2); *call_ret = user_open((const char *)arg0, (int)arg1);
break; break;
case SYSCALL_CLOSE: case SYSCALL_CLOSE:
*call_ret = user_close((int)arg0); *call_ret = user_close((int)arg0);
@ -78,6 +78,9 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
case SYSCALL_SEEK: case SYSCALL_SEEK:
*call_ret = user_seek((int)arg0, (off_t)INT32TOINT64(arg1, arg2), (int)arg3); *call_ret = user_seek((int)arg0, (off_t)INT32TOINT64(arg1, arg2), (int)arg3);
break; break;
case SYSCALL_OPEN_DIR:
*call_ret = user_open_dir((const char *)arg0);
break;
case SYSCALL_READ_DIR: case SYSCALL_READ_DIR:
*call_ret = user_read_dir((int)arg0, (struct dirent *)arg1, (size_t)arg2, (uint32)arg3); *call_ret = user_read_dir((int)arg0, (struct dirent *)arg1, (size_t)arg2, (uint32)arg3);
break; break;
@ -88,7 +91,10 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
*call_ret = user_ioctl((int)arg0, (ulong)arg1, (void *)arg2, (size_t)arg3); *call_ret = user_ioctl((int)arg0, (ulong)arg1, (void *)arg2, (size_t)arg3);
break; break;
case SYSCALL_CREATE: case SYSCALL_CREATE:
*call_ret = user_create((const char *)arg0, (stream_type)arg1); *call_ret = user_create((const char *)arg0, (int)arg1, (int)arg2);
break;
case SYSCALL_CREATE_DIR:
*call_ret = user_create_dir((const char *)arg0, (int)arg1);
break; break;
case SYSCALL_UNLINK: case SYSCALL_UNLINK:
*call_ret = user_unlink((const char *)arg0); *call_ret = user_unlink((const char *)arg0);
@ -97,13 +103,13 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
*call_ret = user_rename((const char *)arg0, (const char *)arg1); *call_ret = user_rename((const char *)arg0, (const char *)arg1);
break; break;
case SYSCALL_RSTAT: case SYSCALL_RSTAT:
*call_ret = user_rstat((const char *)arg0, (struct stat *)arg1); *call_ret = user_read_stat((const char *)arg0, (struct stat *)arg1);
break; break;
case SYSCALL_FSTAT: case SYSCALL_FSTAT:
*call_ret = user_fstat((int)arg0, (struct stat*)arg1); *call_ret = user_fstat((int)arg0, (struct stat*)arg1);
break; break;
case SYSCALL_WSTAT: case SYSCALL_WSTAT:
*call_ret = user_wstat((const char *)arg0, (struct stat *)arg1, (int)arg2); *call_ret = user_write_stat((const char *)arg0, (struct stat *)arg1, (int)arg2);
break; break;
case SYSCALL_SYSTEM_TIME: case SYSCALL_SYSTEM_TIME:
*call_ret = system_time(); *call_ret = system_time();

View File

@ -2,6 +2,7 @@
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <kernel.h> #include <kernel.h>
#include <vm.h> #include <vm.h>
#include <memheap.h> #include <memheap.h>
@ -41,12 +42,12 @@ static int vnode_has_page(struct vm_store *store, off_t offset)
static ssize_t vnode_read(struct vm_store *store, off_t offset, iovecs *vecs) static ssize_t vnode_read(struct vm_store *store, off_t offset, iovecs *vecs)
{ {
return vfs_readpage(STORE_DATA(store)->vn, vecs, offset); return vfs_read_page(STORE_DATA(store)->vn, vecs, offset);
} }
static ssize_t vnode_write(struct vm_store *store, off_t offset, iovecs *vecs) static ssize_t vnode_write(struct vm_store *store, off_t offset, iovecs *vecs)
{ {
return vfs_writepage(STORE_DATA(store)->vn, vecs, offset); return vfs_write_page(STORE_DATA(store)->vn, vecs, offset);
} }
/* unused /* unused

View File

@ -195,7 +195,7 @@ void vm_test()
// char *blah; // char *blah;
int fd; int fd;
fd = sys_open("/boot/kernel", STREAM_TYPE_FILE, 0); fd = sys_open("/boot/kernel", 0);
rid = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test", &ptr, REGION_ADDR_ANY_ADDRESS, rid = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test", &ptr, REGION_ADDR_ANY_ADDRESS,
PAGE_SIZE, LOCK_RW|LOCK_KERNEL, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0); PAGE_SIZE, LOCK_RW|LOCK_KERNEL, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0);