int linux_devfile_write(int fd, void *base, size_t len, size_t * copied_store) { int ret = -E_INVAL; struct file *file; /* use 8byte int, in case of 64bit off_t * config in linux kernel */ int64_t offset; if ((ret = fd2file(fd, &file)) != 0) { return 0; } if (!file->writable) { return -E_INVAL; } filemap_acquire(file); offset = file->pos; struct device *dev = vop_info(file->node, device); assert(dev); ret = dev->d_linux_write(dev, base, len, (size_t *) & offset); if (ret >= 0) { *copied_store = (size_t) ret; file->pos += ret; ret = 0; } filemap_release(file); return ret; }
int file_seek(int fd, off_t pos, int whence) { struct stat __stat, *stat = &__stat; int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); switch (whence) { case LSEEK_SET: break; case LSEEK_CUR: pos += file->pos; break; case LSEEK_END: if ((ret = vop_fstat(file->node, stat)) == 0) { pos += stat->st_size; } break; default: ret = -E_INVAL; } if (ret == 0) { if ((ret = vop_tryseek(file->node, pos)) == 0) { file->pos = pos; } } filemap_release(file); return ret; }
int file_fsync(int fd) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); ret = vop_fsync(file->node); filemap_release(file); return ret; }
int file_fstat(int fd, struct stat *stat) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); ret = vop_fstat(file->node, stat); filemap_release(file); return ret; }
static void vma_copymapfile(struct vma_struct *to, struct vma_struct *from) { /* kprintf("copy_mapfile:0x%08x\n", from->mfile.file); */ to->mfile = from->mfile; if (to->mfile.file != NULL) { to->mfile.offset += to->vm_start - from->vm_start; filemap_acquire(to->mfile.file); } }
int linux_devfile_ioctl(int fd, unsigned int cmd, unsigned long arg) { int ret = -E_INVAL; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return 0; } filemap_acquire(file); struct device *dev = vop_info(file->node, device); assert(dev); ret = dev->d_linux_ioctl(dev, cmd, arg); filemap_release(file); return ret; }
void *linux_devfile_mmap2(void *addr, size_t len, int prot, int flags, int fd, size_t pgoff) { int ret = -E_INVAL; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return NULL; } filemap_acquire(file); struct device *dev = vop_info(file->node, device); assert(dev); void* r = dev->d_linux_mmap(dev, addr, len, prot, flags, pgoff); filemap_release(file); return r; }
int file_getdirentry(int fd, struct dirent *direntp) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); struct iobuf __iob, *iob = iobuf_init(&__iob, direntp->d_name, sizeof(direntp->d_name), direntp->d_off); if ((ret = vop_getdirentry(file->node, iob)) == 0) { direntp->d_off += iobuf_used(iob); } filemap_release(file); return ret; }
void vma_mapfile(struct vma_struct *vma, int fd, off_t off, struct fs_struct *fs_struct) { if(fs_struct == NULL) { fs_struct = current->fs_struct; } /* kprintf("mapfile:0x%08x fs_struct:0x%08x\n", vma->mfile.file, fs_struct); */ vma->mfile.offset = off; assert(vma != NULL); assert((vma->mfile.file = fd2file_onfs(fd, fs_struct)) != NULL); filemap_acquire(vma->mfile.file); }
int file_getdirentry(int fd, struct dirent *direntp) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); // kprintf("%s %s %d\n", __FILE__, __func__, __LINE__); struct iobuf __iob, *iob = iobuf_init(&__iob, direntp->name, sizeof(direntp->name), direntp->offset); if ((ret = vop_getdirentry(file->node, iob)) == 0) { direntp->offset += iobuf_used(iob); } filemap_release(file); return ret; }
int file_write(int fd, void *base, size_t len, size_t * copied_store) { int ret; struct file *file; *copied_store = 0; if ((ret = fd2file(fd, &file)) != 0) { return ret; } if (!file->writable) { return -E_INVAL; } filemap_acquire(file); struct iobuf __iob, *iob = iobuf_init(&__iob, base, len, file->pos); ret = vop_write(file->node, iob, file->io_flags); size_t copied = iobuf_used(iob); file->pos += copied; *copied_store = copied; filemap_release(file); return ret; }
/* * file_read - read file * */ int file_read(int fd, void *base, size_t len, size_t * copied_store) { int ret; struct file *file; *copied_store = 0; if ((ret = fd2file(fd, &file)) != 0) { return ret; } if (!file->readable) { return -E_INVAL; } filemap_acquire(file); struct iobuf __iob, *iob = iobuf_init(&__iob, base, len, file->pos); ret = vop_read(file->node, iob); size_t copied = iobuf_used(iob); if (file->status == FD_OPENED) { file->pos += copied; } *copied_store = copied; filemap_release(file); return ret; }
int do_mprotect(void *addr, size_t len, int prot) { /* return 0; */ struct mm_struct *mm = current->mm; assert(mm != NULL); if (len == 0) { return -E_INVAL; } uintptr_t start = ROUNDDOWN(addr, PGSIZE); uintptr_t end = ROUNDUP(addr + len, PGSIZE); int ret = -E_INVAL; lock_mm(mm); while (1) { struct vma_struct *vma = find_vma(mm, start); uintptr_t last_end; if (vma != NULL) { last_end = vma->vm_end; } if (vma == NULL) { goto out; } else if (vma->vm_start == start && vma->vm_end == end) { if (prot & PROT_WRITE) { vma->vm_flags |= VM_WRITE; } else { vma->vm_flags &= ~VM_WRITE; } } else { uintptr_t this_end = (end <= vma->vm_end) ? end : vma->vm_end; uintptr_t this_start = (start >= vma->vm_start) ? start : vma->vm_start; struct mapped_file_struct mfile = vma->mfile; mfile.offset += this_start - vma->vm_start; uint32_t flags = vma->vm_flags; if ((ret = mm_unmap_keep_pages(mm, this_start, this_end - this_start)) != 0) { goto out; } if (prot & PROT_WRITE) { flags |= VM_WRITE; } else { flags &= ~VM_WRITE; } if ((ret = mm_map(mm, this_start, this_end - this_start, flags, &vma)) != 0) { goto out; } vma->mfile = mfile; if (vma->mfile.file != NULL) { filemap_acquire(mfile.file); } } ret = 0; if (end <= last_end) break; start = last_end; } out: unlock_mm(mm); return ret; }