Skip to content

Commit

Permalink
Move pwd, root, uname out into its own struct
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Jan 22, 2018
1 parent bc55900 commit eddf023
Show file tree
Hide file tree
Showing 32 changed files with 303 additions and 208 deletions.
1 change: 1 addition & 0 deletions fs/adhoc.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <sys/stat.h>
#include "debug.h"
#include "kernel/fs.h"
#include "fs/fd.h"
#include "kernel/errno.h"

static struct mount adhoc_mount;
Expand Down
1 change: 1 addition & 0 deletions fs/dev.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "kernel/errno.h"
#include "fs/fd.h"
#include "fs/dev.h"
#include "fs/tty.h"

Expand Down
2 changes: 1 addition & 1 deletion fs/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#if __linux__
#include <sys/sysmacros.h>
#endif
#include "kernel/fs.h"
#include "fs/fd.h"

// a dev_t is encoded like this in hex, where M is major and m is minor:
// mmmMMMmm
Expand Down
2 changes: 1 addition & 1 deletion fs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "kernel/calls.h"
#include "kernel/errno.h"
#include "kernel/fs.h"
#include "fs/fdtable.h"
#include "fs/fd.h"

struct linux_dirent64 {
qword_t inode;
Expand Down
2 changes: 1 addition & 1 deletion fs/fake.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "debug.h"
#include "kernel/errno.h"
#include "kernel/task.h"
#include "kernel/fs.h"
#include "fs/fd.h"

// TODO document database

Expand Down
34 changes: 31 additions & 3 deletions fs/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,37 @@
#include "kernel/errno.h"
#include "kernel/resource.h"
#include "kernel/fs.h"
#include "fs/fdtable.h"
#include "fs/fd.h"

struct fd *fd_create() {
struct fd *fd = malloc(sizeof(struct fd));
*fd = (struct fd) {};
fd->refcount = 1;
fd->flags = 0;
fd->mount = NULL;
list_init(&fd->poll_fds);
lock_init(&fd->lock);
return fd;
}

struct fd *fd_retain(struct fd *fd) {
fd->refcount++;
return fd;
}

int fd_close(struct fd *fd) {
if (--fd->refcount == 0) {
if (fd->ops->close) {
int err = fd->ops->close(fd);
if (err < 0)
return err;
}
free(fd);
}
return 0;
}

struct fdtable *fdtable_alloc(unsigned size) {
struct fdtable *fdtable_new(unsigned size) {
struct fdtable *fdt = malloc(sizeof(struct fdtable));
if (fdt == NULL)
return ERR_PTR(_ENOMEM);
Expand Down Expand Up @@ -57,7 +85,7 @@ int fdtable_resize(struct fdtable *table, unsigned size) {

struct fdtable *fdtable_copy(struct fdtable *table) {
unsigned size = table->size;
struct fdtable *new_table = fdtable_alloc(size);
struct fdtable *new_table = fdtable_new(size);
if (IS_ERR(new_table))
return new_table;
memcpy(new_table->files, table->files, sizeof(struct fd *) * size);
Expand Down
99 changes: 99 additions & 0 deletions fs/fd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#ifndef FD_H
#define FD_H
#include <dirent.h>
#include "misc.h"
#include "emu/memory.h"
#include "util/list.h"
#include "util/bits.h"

struct fd {
atomic_uint refcount;
unsigned flags;
const struct fd_ops *ops;
struct list poll_fds;

// fd data
union {
struct {
DIR *dir;
};
struct {
struct tty *tty;
// links together fds pointing to the same tty
// locked by the tty
struct list other_fds;
};
};

// fs/inode data
struct mount *mount;
union {
int real_fd;
struct statbuf *stat;
};

lock_t lock;
};

typedef sdword_t fd_t;
#define FD_CLOEXEC_ 1
#define AT_FDCWD_ -100

struct fd *fd_create(void);
struct fd *fd_retain(struct fd *fd);
int fd_close(struct fd *fd);

#define NAME_MAX 255
struct dir_entry {
qword_t inode;
qword_t offset;
char name[NAME_MAX + 1];
};

struct fd_ops {
ssize_t (*read)(struct fd *fd, void *buf, size_t bufsize);
ssize_t (*write)(struct fd *fd, const void *buf, size_t bufsize);
off_t_ (*lseek)(struct fd *fd, off_t_ off, int whence);

// Reads a directory entry from the stream
int (*readdir)(struct fd *fd, struct dir_entry *entry);

// map the file
int (*mmap)(struct fd *fd, struct mem *mem, page_t start, pages_t pages, off_t offset, int prot, int flags);

// returns a bitmask of operations that won't block
int (*poll)(struct fd *fd);

// returns the size needed for the output of ioctl, 0 if the arg is not a
// pointer, -1 for invalid command
ssize_t (*ioctl_size)(struct fd *fd, int cmd);
// if ioctl_size returns non-zero, arg must point to ioctl_size valid bytes
int (*ioctl)(struct fd *fd, int cmd, void *arg);

// Returns the path of the file descriptor, buf must be at least MAX_PATH
int (*getpath)(struct fd *fd, char *buf);

int (*close)(struct fd *fd);
};

struct fdtable {
atomic_uint refcount;
unsigned size;
struct fd **files;
bits_t *cloexec;
};

struct fdtable *fdtable_new();
void fdtable_release(struct fdtable *table);
int fdtable_resize(struct fdtable *table, unsigned size);
struct fdtable *fdtable_copy(struct fdtable *table);
void fdtable_free(struct fdtable *table);

struct fd *f_get(fd_t f);
bool f_is_cloexec(fd_t f);
void f_put(fd_t f, struct fd *fd);
// steals a reference to the fd, gives it to the table on success and destroys it on error
fd_t f_install(struct fd *fd);
int f_close(fd_t f);

#endif
25 changes: 0 additions & 25 deletions fs/fdtable.h

This file was deleted.

32 changes: 3 additions & 29 deletions fs/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@
#include <sys/stat.h>

#include "kernel/fs.h"
#include "fs/fd.h"
#include "fs/path.h"
#include "fs/dev.h"
#include "kernel/task.h"
#include "kernel/errno.h"

struct fd *fd_create() {
struct fd *fd = malloc(sizeof(struct fd));
*fd = (struct fd) {};
fd->refcount = 1;
fd->flags = 0;
fd->mount = NULL;
list_init(&fd->poll_fds);
lock_init(&fd->lock);
return fd;
}

struct mount *find_mount(char *path) {
struct mount *mount;
for (mount = mounts; mount != NULL; mount = mount->next)
Expand Down Expand Up @@ -72,24 +63,7 @@ struct fd *generic_openat(struct fd *at, const char *path_raw, int flags, int mo
}

struct fd *generic_open(const char *path, int flags, int mode) {
return generic_openat(current->pwd, path, flags, mode);
}

int fd_close(struct fd *fd) {
if (--fd->refcount == 0) {
if (fd->ops->close) {
int err = fd->ops->close(fd);
if (err < 0)
return err;
}
free(fd);
}
return 0;
}

struct fd *fd_dup(struct fd *fd) {
fd->refcount++;
return fd;
return generic_openat(NULL, path, flags, mode);
}

int generic_access(const char *path_raw, int mode) {
Expand Down
9 changes: 6 additions & 3 deletions fs/path.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <string.h>
#include "kernel/calls.h"
#include "fs/path.h"

#define __NO_AT (struct fd *) 1

Expand All @@ -11,10 +12,12 @@ int path_normalize(struct fd *at, const char *path, char *out, bool follow_links

if (at != __NO_AT) {
// start with root or cwd, depending on whether it starts with a slash
lock(&current->fs->lock);
if (*p == '/')
at = current->root;
else if (at == NULL)
at = current->pwd;
at = current->fs->root;
else if (at == AT_PWD)
at = current->fs->pwd;
unlock(&current->fs->lock);
if (at != NULL) {
char at_path[MAX_PATH];
int err = at->ops->getpath(at, at_path);
Expand Down
25 changes: 25 additions & 0 deletions fs/path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef PATH_H
#define PATH_H

#define AT_PWD (struct fd *) -2

// Normalizes the path specified and writes the result into the out buffer.
//
// Normalization means:
// - prepending the current or root directory
// - converting multiple slashes into one
// - resolving . and ..
// - resolving symlinks, skipping the last path component if the follow_links
// argument is true
// The result will always begin with a slash or be empty.
//
// If the normalized path plus the null terminator would be longer than
// MAX_PATH, _ENAMETOOLONG is returned. The out buffer is expected to be at
// least MAX_PATH in size.
//
// at is the file descriptor to use as a base to interpret relative paths. If
// at is AT_PWD, uses current->pwd (with appropriate locking).
int path_normalize(struct fd *at, const char *path, char *out, bool follow_links);
bool path_is_normalized(const char *path);

#endif
2 changes: 1 addition & 1 deletion fs/pipe.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <unistd.h>
#include "kernel/calls.h"
#include "fs/fdtable.h"
#include "fs/fd.h"
#include "debug.h"

static fd_t pipe_f_create(int pipe_fd) {
Expand Down
2 changes: 1 addition & 1 deletion fs/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "util/list.h"
#include "kernel/errno.h"
#include "kernel/fs.h"
#include "fs/fdtable.h"
#include "fs/fd.h"
#include "fs/poll.h"

// lock order: fd, then poll
Expand Down
4 changes: 2 additions & 2 deletions fs/real.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ static void copy_stat(struct statbuf *fake_stat, struct stat *real_stat) {
/* fake_stat->ctime_nsec = real_stat->st_ctim.tv_nsec; */
}

int realfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat, bool follow_links) {
static int realfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat, bool follow_links) {
struct stat real_stat;
if (fstatat(mount->root_fd, fix_path(path), &real_stat, follow_links ? 0 : AT_SYMLINK_NOFOLLOW) < 0)
return errno_map();
copy_stat(fake_stat, &real_stat);
return 0;
}

int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
static int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
struct stat real_stat;
if (fstat(fd->real_fd, &real_stat) < 0)
return errno_map();
Expand Down
2 changes: 1 addition & 1 deletion fs/sock.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <sys/socket.h>
#include "kernel/calls.h"
#include "fs/fdtable.h"
#include "fs/fd.h"
#include "fs/sock.h"
#include "debug.h"

Expand Down
10 changes: 9 additions & 1 deletion fs/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#include "kernel/calls.h"
#include "kernel/errno.h"
#include "kernel/fs.h"
#include "fs/fdtable.h"
#include "fs/fd.h"
#include "fs/path.h"

struct newstat64 stat_convert_newstat64(struct statbuf stat) {
struct newstat64 newstat;
Expand Down Expand Up @@ -38,6 +39,13 @@ int generic_statat(struct fd *at, const char *path_raw, struct statbuf *stat, bo
return mount->fs->stat(mount, path, stat, follow_links);
}

// TODO get rid of this and maybe everything else in the file
static struct fd *at_fd(fd_t f) {
if (f == AT_FDCWD_)
return AT_PWD;
return f_get(f);
}

static dword_t sys_stat_path(fd_t at_f, addr_t path_addr, addr_t statbuf_addr, bool follow_links) {
int err;
char path[MAX_PATH];
Expand Down
Loading

0 comments on commit eddf023

Please sign in to comment.