babyos2(20) simple file system (2), file, open, close, read, write
2018-01-06 18:02
281 查看
前面已经探究了super block, inode, bitmap等基本的结构、读写,以及实现了一个简单的namei实现从path找到inode。现在准备为babyos2实现基本的文件操作,打开,创建、读写等。为简单起见,还是先不考虑多进程访问需要的锁,等功能完成后再增加锁。
1.open, close, create
2.read
3.write
1.open, close, create
int file_system_t::write_inode(inode_t* inode, void* src, uint32 offset, uint32 size) { if (offset > inode->m_size) { return -1; } if (offset + size > MAX_FILE_SIZE * BSIZE) { return -1; } int nbyte = 0, total = 0; while (total < size) { io_clb_t clb; clb.init(m_dev, 1, block_map(inode, offset/ BSIZE)); os()->get_ide()->request(&clb); nbyte = BSIZE - offset % BSIZE; if (nbyte > size - total) { nbyte = size - total; } memcpy(clb.buffer + offset % BSIZE, src, nbyte); clb.init(m_dev, 0, block_map(inode, offset/ BSIZE)); os()->get_ide()->request(&clb); total += nbyte; offset += nbyte; src += nbyte; } if (total > 0 && offset > inode->m_size) { inode->m_size = offset; update_disk_inode(inode); } return total; } int file_system_t::dir_link(inode_t* inode, char* name, uint32 inum) { // already present in the dir inode_t* find = NULL; unsigned offset = 0; if ((find = dir_lookup(inode, name, offset)) != NULL) { put_inode(inode); return -1; } // find an empty dir_entry dir_entry_t dir; for (offset = 0; offset < inode->m_size; offset += sizeof(dir)) { if (read_inode(inode, (char *) &dir, offset, sizeof(dir)) != sizeof(dir)) { return -1; } if (dir.m_inum == 0) { break; } } dir.m_inum = inum; memset(dir.m_name, 0, MAX_PATH); strncpy(dir.m_name, name, MAX_PATH); write_inode(inode, &dir, offset, sizeof(dir)); return 0; } inode_t* file_system_t::create(const char* path, uint16 type, uint16 major, uint16 minor) { char name[MAX_PATH] = {0}; inode_t* inode_dir = NULL; if ((inode_dir = nameiparent(path, name)) == NULL) { return NULL; } inode_t* inode = NULL; unsigned offset = 0; if ((inode = dir_lookup(inode_dir, name, offset)) != NULL) { if (inode->m_type == inode_t::I_TYPE_FILE && type == inode_t::I_TYPE_FILE) { return inode; } return NULL; } if ((inode = alloc_inode(inode_dir->m_dev, type)) == NULL) { return NULL; } inode->init(major, minor, 1); inode->m_type = type; update_disk_inode(inode); if (inode->m_type == inode_t::I_TYPE_DIR) { inode_dir->m_nlinks++; update_disk_inode(inode_dir); if (dir_link(inode, (char *) ".", inode->m_inum) < 0 || dir_link(inode, (char *) "..", inode->m_inum) < 0) { return NULL; } } dir_link(inode_dir, name, inode->m_inum); return inode; } file_t* file_system_t::alloc_file() { for (int i = 0; i < MAX_FILE_NUM; i++) { if (m_file_table[i].m_type == file_t::TYPE_NONE) { return &m_file_table[i]; } } return NULL; } int file_system_t::close_file(file_t* file) { if (file->m_ref < 1) { return -1; } if (--file->m_ref > 0) { return 0; } if (file->m_type == file_t::TYPE_INODE) { file->m_type = file_t::TYPE_NONE; put_inode(file->m_inode); } } int file_system_t::do_open(const char* path, int mode) { inode_t* inode = NULL; file_t* file = NULL; if (mode & file_t::MODE_CREATE) { if ((inode = create(path, inode_t::I_TYPE_FILE, 0, 0)) == NULL) { return -1; } } else { if ((inode = namei(path)) == NULL) { return -1; } } int fd = -1; do { if (inode->m_type == inode_t::I_TYPE_DIR) { break; } if ((file = alloc_file()) == NULL) { break; } if ((fd = current->alloc_fd(file)) < 0) { close_file(file); break; } } while (0); if (fd >= 0) { file->init(file_t::TYPE_INODE, inode, 0, !(mode & file_t::MODE_WRONLY), (mode & file_t::MODE_WRONLY) || (mode & file_t::MODE_RDWR)); } return fd; } int file_system_t::do_close(int fd) { file_t* file = current->get_file(fd); if (file != NULL) { close_file(file); } return 0; }
2.read
int file_system_t::do_read(int fd, void* buffer, uint32 count) { file_t* file = current->get_file(fd); if (file == NULL || file->m_readable == 0) { return -1; } if (file->m_type == file_t::TYPE_INODE) { int nbyte = 0; if ((nbyte = read_inode(file->m_inode, (char *) buffer, file->m_offset, count)) > 0) { file->m_offset += nbyte; } return nbyte; } return -1; } void file_system_t::test_read() { console()->kprintf(YELLOW, "test read: \n"); int fd = do_open((char *) "/test", 0); if (fd < 0) { return; } char buffer[512] = {0}; int n = do_read(fd, buffer, 512); console()->kprintf(YELLOW, "%u bytes read from file test: \n%s\n", n, buffer); do_close(fd); }
3.write
int file_system_t::do_write(int fd, void* buffer, uint32 count) { file_t* file = current->get_file(fd); if (file == NULL || file->m_writeable == 0) { return -1; } if (file->m_type == file_t::TYPE_INODE) { int nbyte = 0; if ((nbyte = write_inode(file->m_inode, (char *) buffer, file->m_offset, count)) > 0) { file->m_offset += nbyte; } return nbyte; } return -1; } void file_system_t::test_write() { console()->kprintf(PINK, "test write: \n"); int fd = do_open((char *) "/test", file_t::MODE_RDWR); if (fd < 0) { return; } // read char buffer[512] = {0}; int n = do_read(fd, buffer, 512); console()->kprintf(WHITE, "%u bytes read from file test: \n%s\n", n, buffer); do_close(fd); // write strcpy(buffer + 37, "2) test write...\n"); fd = do_open((char *) "/test", file_t::MODE_RDWR); n = do_write(fd, buffer, strlen(buffer)); console()->kprintf(WHITE, "%u bytes write to file\n", n); do_close(fd); // re-read fd = do_open((char *) "/test", file_t::MODE_RDWR); memset(buffer, 0, 512); n = do_read(fd, buffer, 512); console()->kprintf(WHITE, "%u bytes read from file test: \n%s\n", n, buffer); do_close(fd); }
相关文章推荐
- 了解open/read/write/close等文件相关系统调用接口,纵向对比fd与FILE结构体
- open/read/write/close等文件系统调用接口以及fd与FILE的比较
- 【体会Python之美】【文件】file,open,read,readline,readlines,write,close
- file operate in python (open write read close )
- 应用层open(read、write、close)如何调用驱动open(read、write、close)函数的?
- Liunx FS 高层函数 Create/Open/Close/Read/Write
- open,lseek,read,write,close系统调用《unix环境高级编程读书笔记》(1)
- linux文件操作函数(open、write、read、close)
- 20121025总结——system call ——write,read,open,close,fstat
- fts fts_open fts_read fts_children fts_set fts_close - traverse a file hierarchy
- linux设备驱动归纳总结(三):2open.close.read.write (2010-12-25 10:01)
- Android filesystem system rw(read/write) permission
- 【Linux&Unix--open/close/write/read系统调用】
- 文件操作-open、read、write、close、lseek函数
- linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write
- How to open/read/write a local file from an applet
- [zz]linux IO(function open read write close)
- 嵌入式linux文件I/O编程 (open、read、write、lseek、close)
- linux文件I/O编程 (open、read、write、lseek、close)
- 文件I/O函数(open,read,write,lseek,close)