fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */ unsigned int pages, mapsz, hdrsz; int pgsz = cli_getpagesize(); STATBUF st; fmap_t *m; const void *data; HANDLE fh; HANDLE mh; *empty = 0; if(FSTAT(fd, &st)) { cli_warnmsg("fmap: fstat failed\n"); return NULL; } if(offset < 0 || offset != fmap_align_to(offset, pgsz)) { cli_warnmsg("fmap: attempted mapping with unaligned offset\n"); return NULL; } if(!len) len = st.st_size - offset; /* bound checked later */ if(!len) { cli_dbgmsg("fmap: attempted void mapping\n"); *empty = 1; return NULL; } if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) { cli_warnmsg("fmap: attempted oof mapping\n"); return NULL; } pages = fmap_align_items(len, pgsz); hdrsz = fmap_align_to(sizeof(fmap_t), pgsz); if((fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) { cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd); return NULL; } if(!(mh = CreateFileMapping(fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) { cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd); CloseHandle(fh); return NULL; } if(!(data = MapViewOfFile(mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) { cli_errmsg("fmap: cannot map file descriptor %d\n", fd); CloseHandle(mh); CloseHandle(fh); return NULL; } if(!(m = cl_fmap_open_memory(data, len))) { cli_errmsg("fmap: canot allocate fmap_t\n", fd); CloseHandle(mh); CloseHandle(fh); return NULL; } m->handle = (void*)(ssize_t)fd; m->handle_is_fd = 1; m->fh = fh; m->mh = mh; m->unmap = unmap_win32; return m; }
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { unsigned int pages, mapsz, hdrsz; unsigned short dumb = 1; int pgsz = cli_getpagesize(); struct stat st; fmap_t *m; *empty = 0; if(fstat(fd, &st)) { cli_warnmsg("fmap: fstat failed\n"); return NULL; } if(offset < 0 || offset != fmap_align_to(offset, pgsz)) { cli_warnmsg("fmap: attempted mapping with unaligned offset\n"); return NULL; } if(!len) len = st.st_size - offset; /* bound checked later */ if(!len) { cli_dbgmsg("fmap: attempted void mapping\n"); *empty = 1; return NULL; } if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) { cli_warnmsg("fmap: attempted oof mapping\n"); return NULL; } pages = fmap_align_items(len, pgsz); hdrsz = fmap_align_to(sizeof(fmap_t) + (pages-1) * sizeof(uint32_t), pgsz); /* fmap_t includes 1 bitmap slot, hence (pages-1) */ mapsz = pages * pgsz + hdrsz; fmap_lock; #ifdef ANONYMOUS_MAP if ((m = (fmap_t *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) { m = NULL; } else { dumb = 0; #if HAVE_MADVISE madvise((void *)m, mapsz, MADV_RANDOM|MADV_DONTFORK); #endif /* madvise */ } #else /* ! ANONYMOUS_MAP */ m = (fmap_t *)cli_malloc(mapsz); #endif /* ANONYMOUS_MAP */ if(!m) { cli_warnmsg("fmap: map allocation failed\n"); fmap_unlock; return NULL; } /* fault the header while we still have the lock - we DO context switch here a lot here :@ */ memset(fmap_bitmap, 0, sizeof(uint32_t) * pages); fmap_unlock; m->fd = fd; m->dumb = dumb; m->mtime = st.st_mtime; m->offset = offset; m->len = len; m->pages = pages; m->hdrsz = hdrsz; m->pgsz = pgsz; m->paged = 0; m->dont_cache_flag = 0; return m; }
extern cl_fmap_t *cl_fmap_open_handle(void *handle, size_t offset, size_t len, clcb_pread pread_cb, int use_aging) { unsigned int pages, mapsz, hdrsz; cl_fmap_t *m; int pgsz = cli_getpagesize(); if((off_t)offset < 0 || offset != fmap_align_to(offset, pgsz)) { cli_warnmsg("fmap: attempted mapping with unaligned offset\n"); return NULL; } if(!len) { cli_dbgmsg("fmap: attempted void mapping\n"); return NULL; } if (offset >= len) { cli_warnmsg("fmap: attempted oof mapping\n"); return NULL; } pages = fmap_align_items(len, pgsz); hdrsz = fmap_align_to(sizeof(fmap_t) + (pages-1) * sizeof(uint32_t), pgsz); /* fmap_t includes 1 bitmap slot, hence (pages-1) */ mapsz = pages * pgsz + hdrsz; #ifndef ANONYMOUS_MAP use_aging = 0; #endif #ifdef ANONYMOUS_MAP if (use_aging) { fmap_lock; if ((m = (fmap_t *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) { m = NULL; } else { #if HAVE_MADVISE madvise((void *)m, mapsz, MADV_RANDOM|MADV_DONTFORK); #endif /* madvise */ /* fault the header while we still have the lock - we DO context switch here a lot here :@ */ memset(fmap_bitmap, 0, sizeof(uint32_t) * pages); } fmap_unlock; } #endif /* ANONYMOUS_MAP */ if (!use_aging) { m = (fmap_t *)cli_malloc(mapsz); if (!(m)) { cli_warnmsg("fmap: map allocation failed\n"); return NULL; } memset(m, 0, hdrsz); } if(!m) { cli_warnmsg("fmap: map allocation failed\n"); return NULL; } m->handle = handle; m->pread_cb = pread_cb; m->aging = use_aging; m->offset = offset; m->nested_offset = 0; m->len = len;/* m->nested_offset + m->len = m->real_len */ m->real_len = len; m->pages = pages; m->hdrsz = hdrsz; m->pgsz = pgsz; m->paged = 0; m->dont_cache_flag = 0; m->unmap = use_aging ? unmap_mmap : unmap_malloc; m->need = handle_need; m->need_offstr = handle_need_offstr; m->gets = handle_gets; m->unneed_off = handle_unneed_off; return m; }
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */ unsigned int pages, mapsz, hdrsz; unsigned short dumb = 1; int pgsz = cli_getpagesize(); struct stat st; fmap_t *m; *empty = 0; if(fstat(fd, &st)) { cli_warnmsg("fmap: fstat failed\n"); return NULL; } if(offset < 0 || offset != fmap_align_to(offset, pgsz)) { cli_warnmsg("fmap: attempted mapping with unaligned offset\n"); return NULL; } if(!len) len = st.st_size - offset; /* bound checked later */ if(!len) { cli_dbgmsg("fmap: attempted void mapping\n"); *empty = 1; return NULL; } if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) { cli_warnmsg("fmap: attempted oof mapping\n"); return NULL; } pages = fmap_align_items(len, pgsz); hdrsz = fmap_align_to(sizeof(fmap_t), pgsz); if(!(m = (fmap_t *)cli_malloc(sizeof(fmap_t)))) { cli_errmsg("fmap: canot allocate fmap_t\n", fd); return NULL; } if((m->fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) { cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd); free(m); return NULL; } if(!(m->mh = CreateFileMapping(m->fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) { cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd); free(m); return NULL; } if(!(m->data = MapViewOfFile(m->mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) { cli_errmsg("fmap: cannot map file descriptor %d\n", fd); CloseHandle(m->mh); free(m); return NULL; } m->fd = fd; m->dumb = dumb; m->mtime = st.st_mtime; m->offset = offset; m->len = len; m->pages = pages; m->hdrsz = hdrsz; m->pgsz = pgsz; m->paged = 0; m->dont_cache_flag = 0; return m; }