static const void *handle_need(fmap_t *m, size_t at, size_t len, int lock) { unsigned int first_page, last_page, lock_count; char *ret; if(!len) return NULL; at += m->nested_offset; if(!CLI_ISCONTAINED(0, m->real_len, at, len)) return NULL; fmap_aging(m); first_page = fmap_which_page(m, at); last_page = fmap_which_page(m, at + len - 1); lock_count = (lock!=0) * (last_page-first_page+1); #ifdef READAHED_PAGES last_page += READAHED_PAGES; if(last_page >= m->pages) last_page = m->pages - 1; #endif if(fmap_readpage(m, first_page, last_page-first_page+1, lock_count)) return NULL; ret = (char *)m; ret += at + m->hdrsz; return (void *)ret; }
static const void *handle_gets(fmap_t *m, char *dst, size_t *at, size_t max_len) { unsigned int i, first_page, last_page; char *src = (void *)((char *)m + m->hdrsz + *at), *endptr = NULL; size_t len = MIN(max_len-1, m->real_len - *at), fullen = len; if(!len || !CLI_ISCONTAINED(0, m->real_len, *at, len)) return NULL; fmap_aging(m); first_page = fmap_which_page(m, *at); last_page = fmap_which_page(m, *at + len - 1); for(i=first_page; i<=last_page; i++) { char *thispage = (char *)m + m->hdrsz + i * m->pgsz; unsigned int scanat, scansz; if(fmap_readpage(m, i, 1, 0)) return NULL; if(i == first_page) { scanat = *at % m->pgsz; scansz = MIN(len, m->pgsz - scanat); } else { scanat = 0; scansz = MIN(len, m->pgsz); } len -= scansz; if((endptr = memchr(&thispage[scanat], '\n', scansz))) { endptr++; break; } } if(endptr) { memcpy(dst, src, endptr - src); dst[endptr - src] = '\0'; *at += endptr - src; } else { memcpy(dst, src, fullen); dst[fullen] = '\0'; *at += fullen; } return dst; }
void fmap_unneed_off(fmap_t *m, size_t at, size_t len) { unsigned int i, first_page, last_page; if(m->dumb) return; if(!len) { cli_warnmsg("fmap_unneed: attempted void unneed\n"); return; } if(!CLI_ISCONTAINED(0, m->len, at, len)) { cli_warnmsg("fmap: attempted oof unneed\n"); return; } first_page = fmap_which_page(m, at); last_page = fmap_which_page(m, at + len - 1); for(i=first_page; i<=last_page; i++) { fmap_unneed_page(m, i); } }
static void handle_unneed_off(fmap_t *m, size_t at, size_t len) { unsigned int i, first_page, last_page; if(!m->aging) return; if(!len) { cli_warnmsg("fmap_unneed: attempted void unneed\n"); return; } at += m->nested_offset; if(!CLI_ISCONTAINED(0, m->real_len, at, len)) { cli_warnmsg("fmap: attempted oof unneed\n"); return; } first_page = fmap_which_page(m, at); last_page = fmap_which_page(m, at + len - 1); for(i=first_page; i<=last_page; i++) { fmap_unneed_page(m, i); } }
static const void *handle_need_offstr(fmap_t *m, size_t at, size_t len_hint) { unsigned int i, first_page, last_page; void *ptr = (void *)((char *)m + m->hdrsz + at); if(!len_hint || len_hint > m->real_len - at) len_hint = m->real_len - at; if(!CLI_ISCONTAINED(0, m->real_len, at, len_hint)) return NULL; fmap_aging(m); first_page = fmap_which_page(m, at); last_page = fmap_which_page(m, at + len_hint - 1); for(i=first_page; i<=last_page; i++) { char *thispage = (char *)m + m->hdrsz + i * m->pgsz; unsigned int scanat, scansz; if(fmap_readpage(m, i, 1, 1)) { last_page = i-1; break; } if(i == first_page) { scanat = at % m->pgsz; scansz = MIN(len_hint, m->pgsz - scanat); } else { scanat = 0; scansz = MIN(len_hint, m->pgsz); } len_hint -= scansz; if(memchr(&thispage[scanat], 0, scansz)) return ptr; } for(i=first_page; i<=last_page; i++) fmap_unneed_page(m, i); return NULL; }