Skip to content

Commit

Permalink
fs: implement FIFO file
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Jun 18, 2024
1 parent 2ddffb4 commit 1cffe1e
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
8 changes: 8 additions & 0 deletions kernel/fs/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,19 @@ static int fifo_open(file_description* desc, mode_t mode) {
(void)mode;
if ((desc->flags & O_RDONLY) && (desc->flags & O_WRONLY))
return -EINVAL;

struct fifo* fifo = (struct fifo*)desc->inode;
if (desc->flags & O_RDONLY)
++fifo->num_readers;
if (desc->flags & O_WRONLY)
++fifo->num_writers;

if (desc->inode->dev == 0) {
// This is a fifo created by pipe syscall.
// We don't need to block here.
return 0;
}

int rc = file_description_block(desc, open_should_unblock);
if (rc == -EAGAIN && (desc->flags & O_WRONLY))
return -ENXIO;
Expand Down
2 changes: 2 additions & 0 deletions kernel/fs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ void inode_unref(struct inode* inode) {
void inode_destroy(struct inode* inode) {
ASSERT(inode->ref_count == 0 && inode->num_links == 0);
ASSERT(inode->fops->destroy_inode);
inode_unref(inode->fifo);
inode_unref((struct inode*)inode->bound_socket);
inode->fops->destroy_inode(inode);
}

Expand Down
1 change: 1 addition & 0 deletions kernel/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct inode {
file_ops* fops;
dev_t dev; // Device number of device containing this inode
dev_t rdev; // Device number (if this inode is a special file)
_Atomic(struct inode*) fifo;
_Atomic(unix_socket*) bound_socket;
_Atomic(nlink_t) num_links;
atomic_size_t ref_count;
Expand Down
25 changes: 25 additions & 0 deletions kernel/fs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,31 @@ static struct inode* resolve_special_file(struct inode* inode) {
return ERR_PTR(-ENODEV);
return device;
}

if (S_ISFIFO(inode->mode)) {
if (inode->fifo) {
struct inode* fifo = inode->fifo;
inode_ref(fifo);
inode_unref(inode);
return fifo;
}

struct inode* new_fifo = fifo_create();
if (IS_ERR(new_fifo))
return ERR_CAST(new_fifo);
new_fifo->dev = inode->dev; // Signal that this fifo is bound to a file
inode_ref(new_fifo);

struct inode* expected = NULL;
if (atomic_compare_exchange_strong(&inode->fifo, &expected, new_fifo)) {
inode_unref(inode);
return new_fifo;
}
inode_ref(expected);
inode_unref(new_fifo);
return expected;
}

return inode;
}

Expand Down

0 comments on commit 1cffe1e

Please sign in to comment.