static int qnx6fs_close(struct file_desc *desc) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->file_op->close(desc); }
static size_t qnx6fs_write(struct file_desc *desc, void *buff, size_t size) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->file_op->write(desc, buff, size); }
static int qnx6fs_umount(void *dir) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->fsop->umount(dir); }
/* * file_operation */ static int qnx6fs_open(struct node *node, struct file_desc *desc, int flags) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->file_op->open(node, desc, flags); }
static int qnx6fs_delete(struct node *node) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->fsop->delete_node(node); }
static int qnx6fs_format(void *dev) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->fsop->format(dev); }
static int ext3fs_close(struct file_desc *desc) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } return drv->file_op->close(desc); }
static int qnx6fs_create(struct node *parent_node, struct node *node) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(PSEVDOFS_NAME))) { return -1; } return drv->fsop->create_node(parent_node, node); }
static size_t ext3fs_read(struct file_desc *desc, void *buff, size_t size) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } return drv->file_op->read(desc, buff, size); }
/* * file_operation */ static struct idesc *ext3fs_open(struct node *node, struct file_desc *desc, int flags) { struct fs_driver *drv; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return err_ptr(EINVAL); } return drv->file_op->open(node, desc, flags); }
static int rootfs_mount(const char *dev, const char *fs_type) { struct fs_driver *fsdrv; /* mount dev filesystem */ fsdrv = fs_driver_find_drv("devfs"); if (fsdrv) { fsdrv->fsop->mount("/dev", NULL); } if (-1 == mount((char *) dev, "/", (char *) fs_type)) { return -errno; } return 0; }
static int ext3fs_umount(void *dir) { struct fs_driver *drv; struct ext2_fs_info *fsi; ext3_journal_specific_t *data; int res; fsi = ((struct node *)dir)->nas->fs->fsi; data = fsi->journal->j_fs_specific.data; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } res = drv->fsop->umount(dir); journal_delete(fsi->journal); sysfree(data->ext3_journal_inode); journal_free_block(fsi->journal, data->j_sb_buffer); objfree(&ext3_journal_cache, data); return res; }
static int ext3fs_create(struct node *parent_node, struct node *node) { struct fs_driver *drv; struct ext2_fs_info *fsi; journal_handle_t *handle; int res = -1; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } fsi = parent_node->nas->fs->fsi; /** * ext3_trans_blocks(1) - to modify parent_node's data block * 2 blocks for child = 1 inode + 1 inode bitmap. * 2 * (ext3_trans_blocks(1) + 2) blocks to create "." and ".." */ if (!(handle = journal_start(fsi->journal, 3 * (ext3_trans_blocks(1) + 2)))) { return -1; } res = drv->fsop->create_node(parent_node, node); journal_stop(handle); return res; }
static size_t ext3fs_write(struct file_desc *desc, void *buff, size_t size) { struct fs_driver *drv; int res; size_t datablocks; struct ext2_fs_info *fsi; journal_handle_t *handle; if (NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } assert(desc->node); fsi = desc->node->nas->fs->fsi; /* N * SECTOR_SIZE + K bytes of data can dirty N + 2 only if K >= 2 */ datablocks = (size + SECTOR_SIZE - 2) / SECTOR_SIZE + 1; /* TODO recalculate */ if (!(handle = journal_start(fsi->journal, 4 * ext3_trans_blocks(datablocks)))) { return -1; } res = drv->file_op->write(desc, buff, size); journal_stop(handle); return res; }
static int ext3fs_delete(struct node *node) { struct fs_driver *drv; struct ext2_fs_info *fsi; journal_handle_t *handle; int res; if(NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } fsi = node->nas->fs->fsi; /** * Same as in ext3fs_create: * ext3_trans_blocks(1) - to modify parent_node's data block * 2 blocks for child = 1 inode + 1 inode bitmap */ if (!(handle = journal_start(fsi->journal, ext3_trans_blocks(1) + 2))) { return -1; } res = drv->fsop->delete_node(node); journal_stop(handle); return res; }
static int ext3fs_mount(void *dev, void *dir) { struct fs_driver *drv; struct ext2fs_dinode *dip = sysmalloc(sizeof(struct ext2fs_dinode)); char buf[SECTOR_SIZE * 2]; struct ext2_fs_info *fsi; int inode_sector, ret, rsize; struct node *dev_node = dev; struct nas *dir_nas = ((struct node *)dir)->nas; journal_t *jp = NULL; ext3_journal_specific_t *ext3_spec; journal_fs_specific_t spec = { .bmap = ext3_journal_bmap, .commit = ext3_journal_commit, .update = ext3_journal_update, .trans_freespace = ext3_journal_trans_freespace }; if (NULL == (drv = fs_driver_find_drv(EXT2_NAME))) { return -1; } if ((ret = drv->fsop->mount(dev, dir)) < 0) { return ret; } if (NULL == (ext3_spec = objalloc(&ext3_journal_cache))) { return -1; } spec.data = ext3_spec; if (NULL == (jp = journal_create(&spec))) { objfree(&ext3_journal_cache, ext3_spec); return -1; } /* Getting first block for inode number EXT3_JOURNAL_SUPERBLOCK_INODE */ dir_nas = ((struct node *)dir)->nas; fsi = dir_nas->fs->fsi; inode_sector = ino_to_fsba(fsi, EXT3_JOURNAL_SUPERBLOCK_INODE); rsize = ext2_read_sector(dir_nas, buf, 1, inode_sector); if (rsize * fsi->s_block_size != fsi->s_block_size) { return -EIO; } /* set pointer to inode struct in read buffer */ memcpy(dip, (buf + EXT2_DINODE_SIZE(fsi) * ino_to_fsbo(fsi, EXT3_JOURNAL_SUPERBLOCK_INODE)), sizeof(struct ext2fs_dinode)); /* XXX Hack to use ext2 functions */ dir_nas->fs->drv = &ext3fs_driver; ext3_spec->ext3_journal_inode = dip; if (0 > ext3_journal_load(jp, (struct block_dev *) dev_node->nas->fi->privdata, fsbtodb(fsi, dip->i_block[0]))) { return -EIO; } /* * FIXME Now journal supports block size only equal to filesystem block size * It is not critical but not flexible enough */ assert(jp->j_blocksize == fsi->s_block_size); fsi->journal = jp; return 0; }