Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/fs/minix/file.c 3 * 4 * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/kernel.h> 9 #include <fiwix/types.h> 10 #include <fiwix/errno.h> 11 #include <fiwix/buffer.h> 12 #include <fiwix/fs.h> 13 #include <fiwix/filesystems.h> 14 #include <fiwix/mm.h> 15 #include <fiwix/mman.h> 16 #include <fiwix/fcntl.h> 17 #include <fiwix/stdio.h> 18 #include <fiwix/string.h> 19 20 struct fs_operations minix_file_fsop = { 21 0, 22 0, 23 24 minix_file_open, 25 minix_file_close, 26 file_read, 27 minix_file_write, 28 NULL, /* ioctl */ 29 minix_file_lseek, 30 NULL, /* readdir */ 31 NULL, /* mmap */ 32 NULL, /* select */ 33 34 NULL, /* readlink */ 35 NULL, /* followlink */ 36 minix_bmap, 37 NULL, /* lookup */ 38 NULL, /* rmdir */ 39 NULL, /* link */ 40 NULL, /* unlink */ 41 NULL, /* symlink */ 42 NULL, /* mkdir */ 43 NULL, /* mknod */ 44 minix_truncate, 45 NULL, /* create */ 46 NULL, /* rename */ 47 48 NULL, /* read_block */ 49 NULL, /* write_block */ 50 51 NULL, /* read_inode */ 52 NULL, /* write_inode */ 53 NULL, /* ialloc */ 54 NULL, /* ifree */ 55 NULL, /* statfs */ 56 NULL, /* read_superblock */ 57 NULL, /* remount_fs */ 58 NULL, /* write_superblock */ 59 NULL /* release_superblock */ 60 }; 61 62 int minix_file_open(struct inode *i, struct fd *fd_table) 63 { 64 if(fd_table->flags & O_APPEND) { 65 fd_table->offset = i->i_size; 66 } else { 67 fd_table->offset = 0; 68 } 69 if(fd_table->flags & O_TRUNC) { 70 i->i_size = 0; 71 minix_truncate(i, 0); 72 } 73 return 0; 74 } 75 76 int minix_file_close(struct inode *i, struct fd *fd_table) 77 { 78 return 0; 79 } 80 81 int minix_file_write(struct inode *i, struct fd *fd_table, const char *buffer, __size_t count) 82 { 83 __blk_t block; 84 __off_t total_written; 85 unsigned int boffset, bytes; 86 int blksize; 87 struct buffer *buf; 88 89 inode_lock(i); 90 91 blksize = i->sb->s_blocksize; 92 total_written = 0; 93 94 if(fd_table->flags & O_APPEND) { 95 fd_table->offset = i->i_size; 96 } 97 98 while(total_written < count) { 99 boffset = fd_table->offset % blksize; 100 if((block = bmap(i, fd_table->offset, FOR_WRITING)) < 0) { 101 inode_unlock(i); 102 return block; 103 } 104 bytes = blksize - boffset; 105 bytes = MIN(bytes, (count - total_written)); 106 if(!(buf = bread(i->dev, block, blksize))) { 107 inode_unlock(i); 108 return -EIO; 109 } 110 memcpy_b(buf->data + boffset, buffer + total_written, bytes); 111 update_page_cache(i, fd_table->offset, buffer + total_written, bytes); 112 bwrite(buf); 113 total_written += bytes; 114 fd_table->offset += bytes; 115 } 116 117 if(fd_table->offset > i->i_size) { 118 i->i_size = fd_table->offset; 119 } 120 i->i_ctime = CURRENT_TIME; 121 i->i_mtime = CURRENT_TIME; 122 i->dirty = 1; 123 124 inode_unlock(i); 125 return total_written; 126 } 127 128 int minix_file_lseek(struct inode *i, __off_t offset) 129 { 130 return offset; 131 }