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:
@@ -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);
|
int sys_write_stat(const char *path, struct stat *stat, int stat_mask);
|
||||||
char *sys_getcwd(char *buf, size_t size);
|
char *sys_getcwd(char *buf, size_t size);
|
||||||
int sys_setcwd(const char* path);
|
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 */
|
/* 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);
|
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_write_stat(const char *path, struct stat *stat, int stat_mask);
|
||||||
int user_getcwd(char *buf, size_t size);
|
int user_getcwd(char *buf, size_t size);
|
||||||
int user_setcwd(const char* path);
|
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) */
|
/* fd kernel prototypes (implementation located in fd.c) */
|
||||||
extern ssize_t sys_read(int fd, void *buf, off_t pos, size_t len);
|
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 status_t sys_rewind_dir(int fd);
|
||||||
extern int sys_read_stat(const char *path, struct stat *stat);
|
extern int sys_read_stat(const char *path, struct stat *stat);
|
||||||
extern int sys_close(int fd);
|
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) */
|
/* fd user prototypes (implementation located in fd.c) */
|
||||||
extern ssize_t user_read(int fd, void *buf, off_t pos, size_t len);
|
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 status_t user_rewind_dir(int fd);
|
||||||
extern int user_fstat(int, struct stat *);
|
extern int user_fstat(int, struct stat *);
|
||||||
extern int user_close(int fd);
|
extern int user_close(int fd);
|
||||||
|
extern int user_dup(int fd);
|
||||||
|
extern int user_dup2(int ofd, int nfd);
|
||||||
|
|
||||||
/* vfs entry points... */
|
/* vfs entry points... */
|
||||||
|
|
||||||
@@ -209,5 +208,4 @@ extern int user_close(int fd);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif /* _KERNEL_VFS_H */
|
||||||
|
|
||||||
|
|||||||
+131
-32
@@ -66,15 +66,15 @@ alloc_fd(void)
|
|||||||
|
|
||||||
|
|
||||||
int
|
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 fd = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mutex_lock(&ioctx->io_mutex);
|
mutex_lock(&context->io_mutex);
|
||||||
|
|
||||||
for (i = 0; i < ioctx->table_size; i++) {
|
for (i = 0; i < context->table_size; i++) {
|
||||||
if (!ioctx->fds[i]) {
|
if (!context->fds[i]) {
|
||||||
fd = i;
|
fd = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -84,11 +84,11 @@ new_fd(struct io_context *ioctx, struct file_descriptor *f)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioctx->fds[fd] = f;
|
context->fds[fd] = descriptor;
|
||||||
ioctx->num_used_fds++;
|
context->num_used_fds++;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&ioctx->io_mutex);
|
mutex_unlock(&context->io_mutex);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@@ -112,46 +112,117 @@ put_fd(struct file_descriptor *descriptor)
|
|||||||
|
|
||||||
|
|
||||||
struct file_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]) {
|
mutex_lock(&context->io_mutex);
|
||||||
// valid fd
|
|
||||||
f = ioctx->fds[fd];
|
|
||||||
atomic_add(&f->ref_count, 1);
|
|
||||||
} else {
|
|
||||||
f = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
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]) {
|
mutex_lock(&context->io_mutex);
|
||||||
// valid fd
|
|
||||||
f = ioctx->fds[fd];
|
if (fd < context->table_size)
|
||||||
ioctx->fds[fd] = NULL;
|
descriptor = context->fds[fd];
|
||||||
ioctx->num_used_fds--;
|
|
||||||
} else {
|
if (descriptor) { // fd is valid
|
||||||
f = NULL;
|
context->fds[fd] = NULL;
|
||||||
|
context->num_used_fds--;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&ioctx->io_mutex);
|
mutex_unlock(&context->io_mutex);
|
||||||
|
|
||||||
if (f)
|
if (descriptor)
|
||||||
put_fd(f);
|
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 -
|
// #pragma mark -
|
||||||
/*** SYSTEM functions ***/
|
/*** SYSTEM functions ***/
|
||||||
|
|
||||||
@@ -513,3 +598,17 @@ sys_close(int fd)
|
|||||||
return B_OK;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+1665
-1620
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user