int mappedfile_copy(struct vir_region *vr, struct vir_region *newvr) { assert(vr->param.file.inited); mappedfile_setfile(newvr->parent, newvr, vr->param.file.fdref->fd, vr->param.file.offset, vr->param.file.fdref->dev, vr->param.file.fdref->ino, vr->param.file.clearend, 0, 0); assert(newvr->param.file.inited); return OK; }
static int mmap_file(struct vmproc *vmp, int vmfd, off_t file_offset, int flags, ino_t ino, dev_t dev, u64_t filesize, vir_bytes addr, vir_bytes len, vir_bytes *retaddr, u16_t clearend, int writable, int mayclosefd) { /* VFS has replied to a VMVFSREQ_FDLOOKUP request. */ struct vir_region *vr; u64_t page_offset; int result = OK; u32_t vrflags = 0; if(writable) vrflags |= VR_WRITABLE; /* Do some page alignments. */ if((page_offset = (file_offset % VM_PAGE_SIZE))) { file_offset -= page_offset; len += page_offset; } len = roundup(len, VM_PAGE_SIZE); /* All numbers should be page-aligned now. */ assert(!(len % VM_PAGE_SIZE)); assert(!(filesize % VM_PAGE_SIZE)); assert(!(file_offset % VM_PAGE_SIZE)); #if 0 /* XXX ld.so relies on longer-than-file mapping */ if((u64_t) len + file_offset > filesize) { printf("VM: truncating mmap dev 0x%x ino %d beyond file size in %d; offset %llu, len %lu, size %llu; ", dev, ino, vmp->vm_endpoint, file_offset, len, filesize); len = filesize - file_offset; return EINVAL; } #endif if(!(vr = mmap_region(vmp, addr, flags, len, vrflags, &mem_type_mappedfile, 0))) { result = ENOMEM; } else { *retaddr = vr->vaddr + page_offset; result = OK; mappedfile_setfile(vmp, vr, vmfd, file_offset, dev, ino, clearend, 1, mayclosefd); } return result; }