Major code cleanup and reorganisation.

Fixed many bugs.
Now, the vfs_ prefix is for functions that are called by other parts of the
kernel. file_ is for file related stuff, dir_ for directory related, and
common_ for both, fs_ for general file system stuff.
Put all prefixed functions together in the source.
Implemented (currently without a user/sys call) opening/creating of entry_refs,
and node_refs (the latter for opening directories only).
Moved vfs_dup(), and vfs_dup2() to fd.c, fd_dup(), and fd_dup2().


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@351 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2002-07-20 00:16:12 +00:00
parent 6ec6552ee4
commit 071f62bc36
3 changed files with 1801 additions and 1659 deletions

View File

@ -162,8 +162,6 @@ int sys_rename(const char *oldpath, const char *newpath);
int sys_write_stat(const char *path, struct stat *stat, int stat_mask);
char *sys_getcwd(char *buf, size_t size);
int sys_setcwd(const char* path);
int sys_dup(int fd);
int sys_dup2(int ofd, int nfd);
/* calls the syscall dispatcher should use for user file I/O */
int user_mount(const char *path, const char *device, const char *fs_name, void *args);
@ -181,8 +179,6 @@ int user_read_stat(const char *path, struct stat *stat);
int user_write_stat(const char *path, struct stat *stat, int stat_mask);
int user_getcwd(char *buf, size_t size);
int user_setcwd(const char* path);
int user_dup(int fd);
int user_dup2(int ofd, int nfd);
/* fd kernel prototypes (implementation located in fd.c) */
extern ssize_t sys_read(int fd, void *buf, off_t pos, size_t len);
@ -192,7 +188,8 @@ extern ssize_t sys_read_dir(int fd, struct dirent *buffer, size_t bufferSize, ui
extern status_t sys_rewind_dir(int fd);
extern int sys_read_stat(const char *path, struct stat *stat);
extern int sys_close(int fd);
extern int sys_dup(int fd);
extern int sys_dup2(int ofd, int nfd);
/* fd user prototypes (implementation located in fd.c) */
extern ssize_t user_read(int fd, void *buf, off_t pos, size_t len);
@ -202,6 +199,8 @@ extern ssize_t user_read_dir(int fd, struct dirent *buffer, size_t bufferSize, u
extern status_t user_rewind_dir(int fd);
extern int user_fstat(int, struct stat *);
extern int user_close(int fd);
extern int user_dup(int fd);
extern int user_dup2(int ofd, int nfd);
/* vfs entry points... */
@ -209,5 +208,4 @@ extern int user_close(int fd);
}
#endif
#endif
#endif /* _KERNEL_VFS_H */

View File

@ -66,15 +66,15 @@ alloc_fd(void)
int
new_fd(struct io_context *ioctx, struct file_descriptor *f)
new_fd(struct io_context *context, struct file_descriptor *descriptor)
{
int fd = -1;
int i;
mutex_lock(&ioctx->io_mutex);
mutex_lock(&context->io_mutex);
for (i = 0; i < ioctx->table_size; i++) {
if (!ioctx->fds[i]) {
for (i = 0; i < context->table_size; i++) {
if (!context->fds[i]) {
fd = i;
break;
}
@ -84,11 +84,11 @@ new_fd(struct io_context *ioctx, struct file_descriptor *f)
goto err;
}
ioctx->fds[fd] = f;
ioctx->num_used_fds++;
context->fds[fd] = descriptor;
context->num_used_fds++;
err:
mutex_unlock(&ioctx->io_mutex);
mutex_unlock(&context->io_mutex);
return fd;
}
@ -112,46 +112,117 @@ put_fd(struct file_descriptor *descriptor)
struct file_descriptor *
get_fd(struct io_context *ioctx, int fd)
get_fd(struct io_context *context, int fd)
{
struct file_descriptor *f;
struct file_descriptor *descriptor = NULL;
mutex_lock(&ioctx->io_mutex);
if (fd < 0)
return NULL;
if (fd >= 0 && fd < ioctx->table_size && ioctx->fds[fd]) {
// valid fd
f = ioctx->fds[fd];
atomic_add(&f->ref_count, 1);
} else {
f = NULL;
}
mutex_lock(&context->io_mutex);
mutex_unlock(&ioctx->io_mutex);
if (fd < context->table_size)
descriptor = context->fds[fd];
if (descriptor != NULL) // fd is valid
atomic_add(&descriptor->ref_count, 1);
return f;
mutex_unlock(&context->io_mutex);
return descriptor;
}
void
remove_fd(struct io_context *ioctx, int fd)
remove_fd(struct io_context *context, int fd)
{
struct file_descriptor *f;
struct file_descriptor *descriptor = NULL;
mutex_lock(&ioctx->io_mutex);
if (fd < 0)
return;
if (fd >= 0 && fd < ioctx->table_size && ioctx->fds[fd]) {
// valid fd
f = ioctx->fds[fd];
ioctx->fds[fd] = NULL;
ioctx->num_used_fds--;
} else {
f = NULL;
mutex_lock(&context->io_mutex);
if (fd < context->table_size)
descriptor = context->fds[fd];
if (descriptor) { // fd is valid
context->fds[fd] = NULL;
context->num_used_fds--;
}
mutex_unlock(&ioctx->io_mutex);
mutex_unlock(&context->io_mutex);
if (f)
put_fd(f);
if (descriptor)
put_fd(descriptor);
}
static int
fd_dup(int fd, bool kernel)
{
struct io_context *context = get_current_io_context(kernel);
struct file_descriptor *descriptor;
int status;
TRACE(("fd_dup: fd = %d\n", fd));
// Try to get the fd structure
descriptor = get_fd(context, fd);
if (descriptor == NULL)
return EBADF;
// now put the fd in place
status = new_fd(context, descriptor);
if (status < 0)
put_fd(descriptor);
return status;
}
static int
fd_dup2(int oldfd, int newfd, bool kernel)
{
struct file_descriptor *evicted = NULL;
struct io_context *context;
TRACE(("fd_dup2: ofd = %d, nfd = %d\n", oldfd, newfd));
// quick check
if (oldfd < 0 || newfd < 0)
return EBADF;
// Get current I/O context and lock it
context = get_current_io_context(kernel);
mutex_lock(&context->io_mutex);
// Check if the fds are valid (mutex must be locked because
// the table size could be changed)
if (oldfd >= context->table_size
|| newfd >= context->table_size
|| context->fds[oldfd] == NULL) {
mutex_unlock(&context->io_mutex);
return EBADF;
}
// Check for identity, note that it cannot be made above
// because we always want to return an error on invalid
// handles
if (oldfd != newfd) {
// Now do the work
evicted = context->fds[newfd];
context->fds[newfd] = context->fds[oldfd];
atomic_add(&context->fds[oldfd]->ref_count, 1);
}
mutex_unlock(&context->io_mutex);
// Say bye bye to the evicted fd
if (evicted)
put_fd(evicted);
return newfd;
}
@ -351,6 +422,20 @@ user_close(int fd)
}
int
user_dup(int fd)
{
return fd_dup(fd, false);
}
int
user_dup2(int ofd, int nfd)
{
return fd_dup2(ofd, nfd, false);
}
// #pragma mark -
/*** SYSTEM functions ***/
@ -513,3 +598,17 @@ sys_close(int fd)
return B_OK;
}
int
sys_dup(int fd)
{
return fd_dup(fd, true);
}
int
sys_dup2(int ofd, int nfd)
{
return fd_dup2(ofd, nfd, true);
}

File diff suppressed because it is too large Load Diff