owned this note
owned this note
Published
Linked with GitHub
# Interface
```c++
spinlock open_files_lock;
file open_files[32];
struct file_descriptor {
int fd;
file* f;
}
struct file {
enum {F_FILE, F_PIPE, F_KB_C} f_type;
unsigned int f_perms; // PERM_READ/PERM_WRITE/PERM_EXEC
unsigned int f_offset;
v_node* f_vnode;
unsigned int f_refcount;
}
struct v_node {
virtual ssize_t read(char* buf, int index, size_t sz);
virtual ssize_t write(char* buf, int index, size_t sz);
virtual int open(struct inode*);
virtual int close();
}
int syscall_dup2(regstate* regs);
int syscall_close(regstate* regs);
```
We expect `v_node` to be subclassed with specific kinds of `v_nodes`, and different `read()`, `write()`, `open()`, and `close()` methods.
# Functionality
**Per process file descriptor table:**
Every process will have an eight member long array of struct file descriptors. A member will be present if a file is open. The struct `file_descriptor` contains its own index, and a `file*` that corresponds to its open file the system-wide `open_files` array.
**System-Wide `open_files` Array:**
There will be one system wide file array with 32 members of struct files.
A `file` contains
1. an enum corresponding to the type of file
2. an int for permissions, an int for offset,
3. a pointer to a `v_node`
4. a reference count.
**Struct `file` Content**
1. File types:
There are three types of files, keyboard console, disk file, and pipe.
2. Permissions:
A file can have user-level read (`R_PERM`), write (`W_PERM`), and/or executable (`X_PERM`) permissions.
3. Offset:
A file has a corresponding offset, utilized in during reading and writing.
4. `v_node*`:
Every file descriptor has a corresponding `v_node` pointer. Depending on the file type, it would point to different v_nodes (i.e. keyboard console v_node, pipe v_node, ...). The `v_node` pointer acts as an interface for a file's interaction based function calls (open, read, etc.).
5. Refcount:
Corresponding to the number of processes with a file descriptor entry (in the per-process file descriptor array) with a `file*` pointing to this file. When `refcount` becomes 0, we should clear out this `file`
**Struct `v_node` Content**
Each vnode will have an inode pointer, a lock, and function pointers pointing to the correct implementations dependent upon type of file. These function pointers will be set upon initialization.
**`v_node` Functions**
{`open(), read(), write(), close()`}
When a process calls one of these functions from a `v_node`, a file descriptor (from per process file descriptor array) and corresponding file (from system wide file array) must be valid. Each of these functions have to be separately implemented for each `v_node` subclass.
# Synchronization and Blocking
- The global `open_files_lock` protects the global `open_files` array that stores the `file` open file descriptor objects.
- When processes create new file descriptors that point to `file`s in the `open_files` array, it will grab this lock and increment refcount
- When processes close file decriptors, it will grab this lock and decrement refcount; if 0, then free it
- `read()` and `write()` should block, all other functions should not block
---
1. each process will have its own fd table of pointers
2. create struct file
1. start off with what is included in powerpoint:
1. perms; offset; vnode; refcount
2. (come back to vnode)
3. create system wide fd table (array type file) with max 32 files (he said thats okay). this is a small size, so free to initially initialize
(deal with synchronization later: ideally, would love to allow multiple reads and one write, but start with one write)
1. create subclasses vnode_data_file/data_file
1. functions vfs_write(); _read(); open(); close()
2. create subclasses vnode_pipe_file / pipe_file
1. functions vfs_write(); _read(); open(); close()
3. create class vnode
1. vnode has functions vfs_write(); _read(); open(); close()
2. when kernel calls vfs_EX, it should pass in the index of the system wide table. with that, get file. file's v_node is pointed to struct of that type of file. call that struct's appropriate function.