int vfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct vfs_inode *node, *dir_list, *found_node; struct stat dst; int ret; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; if (!S_ISDIR(node->data.mode)) { vfs_node_deref(node); return -EINVAL; } vfs_stat_translate(&dst, &node->data); filler(buf, ".", &dst, 0); filler(buf, "..", NULL, 0); if ((ret = vfs_dir_read(node->data.ino, &dir_list, NULL)) != 0) { warning("File system missing data at inode %016" PRIx64, node->data.ino); vfs_node_deref(node); return ret; } for (found_node = dir_list; found_node; found_node = found_node->next) { vfs_stat_translate(&dst, &found_node->data); filler(buf, found_node->data.name, &dst, 0); } vfs_dir_read_free(dir_list); vfs_node_deref(node); return 0; }
int vfs_fuse_rmdir(const char *path) { struct vfs_inode *node, *dir_list; int ret; if (store_get_readonly()) return -EPERM; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; if (!S_ISDIR(node->data.mode)) { vfs_node_deref(node); return -ENOTDIR; } if ((ret = vfs_dir_read(node->data.ino, &dir_list, NULL)) != 0) { warning("File system missing data at inode %016" PRIx64, node->data.ino); vfs_node_deref(node); return ret; } if (dir_list) { ret = -ENOTEMPTY; } else { ret = vfs_node_delete(node, true); } vfs_dir_read_free(dir_list); vfs_node_deref(node); return ret; }
int vfs_fuse_unlink(const char *path) { struct vfs_inode *node; int ret; if (store_get_readonly()) return -EPERM; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; if ((ret = vfs_node_delete(node, true)) != 0) { vfs_node_deref(node); return ret; } vfs_node_deref(node); return 0; }
int vfs_node_commit_and_deref(struct vfs_inode *node) { int ret; ret = vfs_node_commit(node); vfs_node_deref(node); return ret; }
int vfs_fuse_getattr(const char *path, struct stat *stbuf) { struct vfs_inode *node; int ret; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; vfs_stat_translate(stbuf, &node->data); vfs_node_deref(node); return 0; }
void vfs_fd_clear() { struct vfs_fd *fd; while (vfs_fd_list) { fd = vfs_fd_list; vfs_fd_list = fd->next; vfs_node_deref(fd->node); free(fd); } }
int vfs_fuse_rename(const char *from, const char *to) { struct vfs_inode *old_node, *new_node; struct vfs_inode_ptr old_ptr; int ret; if (store_get_readonly()) return -EPERM; if ((ret = vfs_node_lookup(from, &old_node, false)) != 0) return ret; if ((ret = vfs_node_lookup(to, &new_node, true)) != 0) { if (ret != -EEXIST) { vfs_node_deref(old_node); return ret; } if ((ret = vfs_fuse_unlink(to)) != 0) { vfs_node_deref(old_node); return ret; } if ((ret = vfs_node_lookup(to, &new_node, true)) != 0) { vfs_node_deref(old_node); return ret; } } memcpy(&old_ptr, &old_node->ptr, sizeof(old_ptr)); memcpy(&old_node->ptr, &new_node->ptr, sizeof(old_node->ptr)); memcpy(&new_node->ptr, &old_ptr, sizeof(new_node->ptr)); memcpy(old_node->data.name, new_node->data.name, sizeof(old_node->data.name)); if ((ret = vfs_node_commit_and_deref(old_node)) != 0) { vfs_node_deref(new_node); return ret; } ret = vfs_node_delete(new_node, false); vfs_node_deref(new_node); return ret; }
int vfs_fuse_readlink(const char *path, char *buf, uint64_t size) { struct vfs_inode *node; int ret; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; if (!S_ISLNK(node->data.mode)) ret = -EINVAL; else ret = vfs_io_perform(node, VFS_IO_READ, buf, size, 0); vfs_node_deref(node); return ret; }
int vfs_fuse_open(const char *path, struct fuse_file_info *fi) { struct vfs_inode *node; int ret; if ((ret = vfs_node_lookup(path, &node, false)) != 0) return ret; if (!S_ISLNK(node->data.mode) && !S_ISREG(node->data.mode)) { vfs_node_deref(node); return -EISDIR; } fi->fh = vfs_fd_create(node); return vfs_node_commit_and_deref(node); }
bool vfs_fd_close(vfs_fd_handle fh) { struct vfs_fd *fd; for (fd = vfs_fd_list; fd; fd = fd->next) { if (fh == fd->fh) break; } if (!fd) return false; vfs_node_deref(fd->node); if (fd->prev) fd->prev->next = fd->next; else vfs_fd_list = fd->next; if (fd->next) fd->next->prev = fd->prev; free(fd); return true; }
static int devfs_close(struct vfs_node *node) { int rc = 0; if (!node || !node->data) { rc = EINVAL; goto out; } /* Close the device since we are the last reference */ if (node->ref_count == 1) { dev_close((struct dev *)node->data); } vfs_node_deref(node); DEBUG(DL_DBG, ("close(%s:%d).\n", node->name, node->ino)); out: return rc; }
int vfs_fuse_symlink(const char *from, const char *to) { struct vfs_inode *node; struct fuse_context *ctx; int ret; if (store_get_readonly()) return -EPERM; if (!(ctx = fuse_get_context())) return -EFAULT; if ((ret = vfs_node_lookup(to, &node, true)) != 0) return ret; node->data.mode = S_IFLNK | VFS_DEFAULT_MODE; node->data.uid = ctx->uid; node->data.gid = ctx->gid; if ((ret = vfs_io_perform(node, VFS_IO_WRITE, (char*) from, strlen(from), 0)) != 0) { vfs_node_deref(node); return ret; } return vfs_node_commit_and_deref(node); }
int floppy_init(void) { int rc = 0; int res, i; struct vfs_node *n = NULL; //struct dev *d = NULL; //dev_t devno; u_long cmos_drive0, cmos_drive1; rc = dev_register(FLPY_MAJOR, "flpy"); if (rc != 0) { DEBUG(DL_DBG, ("register FLPY device class failed.\n")); goto out; } /* Open the root of devfs */ n = vfs_lookup("/dev", VFS_DIRECTORY); if (!n) { rc = EGENERIC; DEBUG(DL_DBG, ("devfs not mounted.\n")); goto out; } /* Setup the interrupt handler */ register_irq_handler(IRQ6, &_flpy_hook, flpy_callback); /* Reset primary controller */ _primary_fdc.base_port = FDC_PRI; fdc_reset(&_primary_fdc); /* Get the FDC version */ fdc_out(_primary_fdc.base_port, FDC_VERSION); res = fdc_in(_primary_fdc.base_port); DEBUG(DL_DBG, ("FDC version(0x%x)\n", res)); switch (res) { case 0x80: DEBUG(DL_DBG, ("NEC765 FDC found on base port 0x%x\n", _primary_fdc.base_port)); break; case 0x90: DEBUG(DL_DBG, ("Enhanced FDC found on base port 0x%x\n", _primary_fdc.base_port)); break; default: DEBUG(DL_DBG, ("FDC not found on base port 0x%x\n", _primary_fdc.base_port)); } /* Read floppy drive type from CMOS memory (up to two drives). */ fdc_out(0x70, 0x10); res = fdc_in(0x71); cmos_drive0 = res >> 4; cmos_drive1 = res & 0x0F; /* Setup the two floppy drives */ setup_drive(&_primary_fdc, 0, cmos_drive0); setup_drive(&_primary_fdc, 0, cmos_drive1); for (res = 0, i = 0; i < NR_MAXDRIVES; i++) { if (_primary_fdc.drive[i].param->cmos_type) ; // Setup callback } DEBUG(DL_DBG, ("module flpy initialize successfully.\n")); out: if (n) { vfs_node_deref(n); } return 0; }