From 3b120ea2404f552b0220d1dab969aacb7fa5e900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 14 Jul 2002 05:15:34 +0000 Subject: [PATCH] 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 --- src/kernel/core/addons/bus_managers/bus_man.c | 81 ++++++++++--------- src/kernel/core/console.c | 2 +- src/kernel/core/elf.c | 6 +- src/kernel/core/fd.c | 47 ++++++++++- src/kernel/core/module.c | 30 +++---- src/kernel/core/syscalls.c | 14 +++- src/kernel/core/vm/vm_store_vnode.c | 5 +- src/kernel/core/vm/vm_tests.c | 2 +- 8 files changed, 122 insertions(+), 65 deletions(-) diff --git a/src/kernel/core/addons/bus_managers/bus_man.c b/src/kernel/core/addons/bus_managers/bus_man.c index 554f81a06a..b9c111b58b 100755 --- a/src/kernel/core/addons/bus_managers/bus_man.c +++ b/src/kernel/core/addons/bus_managers/bus_man.c @@ -2,6 +2,7 @@ ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ + #include #include #include @@ -24,6 +25,7 @@ typedef struct bus { static bus *bus_list; static mutex bus_lock; + int bus_man_init(kernel_args *ka) { mutex_init(&bus_lock, "bus_lock"); @@ -37,8 +39,8 @@ static bus *find_bus(const char *path) { bus *b; - for(b = bus_list; b != NULL; b = b->next) { - if(!strcmp(b->path, path)) + for (b = bus_list; b != NULL; b = b->next) { + if (!strcmp(b->path, path)) break; } return b; @@ -53,15 +55,15 @@ int bus_register_bus(const char *path) mutex_lock(&bus_lock); - if(!find_bus(path)) { + if (!find_bus(path)) { b = (bus *)kmalloc(sizeof(bus)); - if(b == NULL) { + if (b == NULL) { err = ENOMEM; goto err; } b->path = kmalloc(strlen(path)+1); - if(b->path == NULL) { + if (b->path == NULL) { err = ENOMEM; kfree(b); goto err; @@ -80,51 +82,58 @@ 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); ssize_t len; - int fd; int err; struct stat stat; - while((len = sys_read(base_fd, &leaf, -1, sizeof(leaf))) > 0) { - // reset the base_path to the original string passed in - base_path[base_path_len] = 0; + while ((len = sys_read_dir(base_fd, dirent, sizeof(buffer), 1)) > 0) { + int fd; - strlcat(base_path, leaf, sizeof(leaf)); - fd = sys_open(base_path, STREAM_TYPE_ANY, 0); - if(fd < 0) + // reset the base_path to the original string passed in + base_path[base_path_len] = '\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; - 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); - continue; - } - 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) + if (err >= 0) return err; continue; - } else if(S_ISREG(stat.st_mode)) { + } else if (S_ISREG(stat.st_mode)) { // we opened the device // XXX assumes PCI struct pci_cfg cfg; 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)); - if(err >= 0) { + if (err >= 0) { // see if the vendor & device id matches - for(i=0; inum_ids; i++) { - if(cfg.vendor_id == vendor_ids->id[i]) { - for(j=0; jnum_ids; j++) { - if(cfg.device_id == device_ids->id[j]) { + for (i = 0; i < vendor_ids->num_ids; i++) { + if (cfg.vendor_id == vendor_ids->id[i]) { + for (j = 0; j < device_ids->num_ids; j++) { + if (cfg.device_id == device_ids->id[j]) { // found it (*n)--; - if(*n <= 0) + if (*n <= 0) return fd; } } @@ -145,22 +154,22 @@ int bus_find_device(int n, id_list *vendor_ids, id_list *device_ids, device *dev bus *b; int err = -1; - for(b = bus_list; b != NULL && err < 0; b = b->next) { - base_fd = sys_open(b->path, STREAM_TYPE_DIR, 0); - if(base_fd < 0) + for (b = bus_list; b != NULL && err < 0; b = b->next) { + base_fd = sys_open_dir(b->path); + if (base_fd < 0) continue; strlcpy(path, b->path, sizeof(path)); strlcat(path, "/", sizeof(path)); - fd = bus_find_device_recurse(&n, path, base_fd, vendor_ids, device_ids); - if(fd >= 0) { + fd = bus_find_device_recurse(&n, path, sizeof(path), base_fd, vendor_ids, device_ids); + if (fd >= 0) { // we have a device! // XXX assumes pci struct pci_cfg cfg; int i; 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 memset(dev, 0, sizeof(device)); dev->vendor_id = cfg.vendor_id; diff --git a/src/kernel/core/console.c b/src/kernel/core/console.c index 5f9431b6e8..687e96655f 100644 --- a/src/kernel/core/console.c +++ b/src/kernel/core/console.c @@ -68,7 +68,7 @@ int con_init(kernel_args *ka) { 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); return 0; diff --git a/src/kernel/core/elf.c b/src/kernel/core/elf.c index 78357decd9..f8f69da71c 100644 --- a/src/kernel/core/elf.c +++ b/src/kernel/core/elf.c @@ -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); - fd = sys_open(path, STREAM_TYPE_FILE, 0); + fd = sys_open(path, 0); if(fd < 0) 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); - fd = sys_open(path, STREAM_TYPE_FILE, 0); + fd = sys_open(path, 0); if(fd < 0) return fd; @@ -907,7 +907,7 @@ int elf_unload_kspace( const char *path ) void *vnode; struct elf_image_info *image; - fd = sys_open(path, STREAM_TYPE_FILE, 0); + fd = sys_open(path, 0); if(fd < 0) return fd; diff --git a/src/kernel/core/fd.c b/src/kernel/core/fd.c index 1c259ad31a..75c1325612 100644 --- a/src/kernel/core/fd.c +++ b/src/kernel/core/fd.c @@ -37,7 +37,7 @@ alloc_fd(void) struct file_descriptor *f; f = kmalloc(sizeof(struct file_descriptor)); - if(f) { + if (f) { f->vnode = NULL; f->cookie = NULL; 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 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 status = EOPNOTSUPP; + put_fd(descriptor); 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 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)); - descriptor = get_fd(get_current_io_context(false), fd); + descriptor = get_fd(get_current_io_context(true), fd); if (descriptor == NULL) return EBADF; @@ -421,7 +462,7 @@ sys_rewind_dir(int 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) return EBADF; diff --git a/src/kernel/core/module.c b/src/kernel/core/module.c index f6cf239ce9..155dcf66a8 100644 --- a/src/kernel/core/module.c +++ b/src/kernel/core/module.c @@ -426,8 +426,8 @@ static int recurse_directory(const char *path, const char *match) int res = 0, dir; int bufferSize = sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1; struct dirent *dirent; - - if ((dir = sys_open(path, STREAM_TYPE_DIR, 0)) < 0) + + if ((dir = sys_open_dir(path)) < 0) return -1; dirent = kmalloc(bufferSize); @@ -453,7 +453,7 @@ static int recurse_directory(const char *path, const char *match) strlcat(newpath, "/", 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); 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) { - int file; + int dir; int res; - file = sys_open( path, STREAM_TYPE_DIR, 0 ); - if (file < 0 ) { - SHOW_FLOW( 3, "couldn't open directory %s (%s)\n", path, strerror( file )); - + dir = sys_open_dir(path); + if (dir < 0 ) { + 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 // and always assume that the directory suddenly disappeared 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) { - sys_close(file); + sys_close(dir); return ENOMEM; } - - SHOW_FLOW( 3, "entered directory %s\n", path ); + + SHOW_FLOW(3, "entered directory %s\n", path); return B_NO_ERROR; } @@ -779,8 +779,8 @@ static inline int module_traverse_dir(module_iterator *iter) SHOW_FLOW( 3, "got %s\n", name ); - if (strcmp( name, "." ) == 0 || - strcmp( name, ".." ) == 0 ) + if (strcmp(name, ".") == 0 || + strcmp(name, "..") == 0 ) return B_NO_ERROR; /* 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->module_pos = 0; - if ((res = sys_rstat(path, &stat)) != B_NO_ERROR ) + if ((res = sys_read_stat(path, &stat)) != B_NO_ERROR) return res; if (S_ISREG(stat.st_mode)) { diff --git a/src/kernel/core/syscalls.c b/src/kernel/core/syscalls.c index 94cac2eb35..f5e86b25f9 100644 --- a/src/kernel/core/syscalls.c +++ b/src/kernel/core/syscalls.c @@ -61,7 +61,7 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re *call_ret = user_sync(); break; 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; case SYSCALL_CLOSE: *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: *call_ret = user_seek((int)arg0, (off_t)INT32TOINT64(arg1, arg2), (int)arg3); break; + case SYSCALL_OPEN_DIR: + *call_ret = user_open_dir((const char *)arg0); + break; case SYSCALL_READ_DIR: *call_ret = user_read_dir((int)arg0, (struct dirent *)arg1, (size_t)arg2, (uint32)arg3); 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); break; 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; case SYSCALL_UNLINK: *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); break; 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; case SYSCALL_FSTAT: *call_ret = user_fstat((int)arg0, (struct stat*)arg1); break; 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; case SYSCALL_SYSTEM_TIME: *call_ret = system_time(); diff --git a/src/kernel/core/vm/vm_store_vnode.c b/src/kernel/core/vm/vm_store_vnode.c index 1d7df01f23..30808db532 100755 --- a/src/kernel/core/vm/vm_store_vnode.c +++ b/src/kernel/core/vm/vm_store_vnode.c @@ -2,6 +2,7 @@ ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ + #include #include #include @@ -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) { - 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) { - return vfs_writepage(STORE_DATA(store)->vn, vecs, offset); + return vfs_write_page(STORE_DATA(store)->vn, vecs, offset); } /* unused diff --git a/src/kernel/core/vm/vm_tests.c b/src/kernel/core/vm/vm_tests.c index 1d1b7f03bf..5a2c8bc061 100755 --- a/src/kernel/core/vm/vm_tests.c +++ b/src/kernel/core/vm/vm_tests.c @@ -195,7 +195,7 @@ void vm_test() // char *blah; 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, PAGE_SIZE, LOCK_RW|LOCK_KERNEL, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0);