static void free_unclaimed_pages(int fd) { int i, j; int start; sigset_t mask, old_mask; if(fd == -1) return; sigfillset(&mask); sigprocmask(SIG_BLOCK, &mask, &old_mask); pthread_mutex_lock(&lock); for(i = 0; i < max_fds; i++) if(fds[i].fd == fd) break; pthread_mutex_unlock(&lock); if(i == max_fds) goto restoresigset; /* not found */ sync_if_writable(fd); start = j = 0; while(j < fds[i].nr_pages) { if(fds[i].info[j] & 1) { if(start < j) { DEBUG("fadv_dontneed(fd=%d, frompage=%d, topage=%d)\n", fd, start, j); fadv_dontneed(fd, start*PAGESIZE, (j - start) * PAGESIZE, nr_fadvise); } start = j + 1; } j++; } /* forget written contents that go beyond previous file size */ start = start < j ? start*PAGESIZE : fds[i].size; DEBUG("fadv_dontneed(fd=%d, rest of pages, starting at byte %d / page %zd)\n", fd, start, start/PAGESIZE); fadv_dontneed(fd, start, 0, nr_fadvise); free(fds[i].info); fds[i].fd = -1; restoresigset: sigprocmask(SIG_SETMASK, &old_mask, NULL); }
static void free_unclaimed_pages(int fd) { int i; struct stat st; sigset_t mask, old_mask; if(fd == -1) return; sigfillset(&mask); sigprocmask(SIG_BLOCK, &mask, &old_mask); pthread_mutex_lock(&lock); for(i = 0; i < max_fds; i++) if(fds[i].fd == fd) break; pthread_mutex_unlock(&lock); if(i == max_fds) goto restoresigset; /* not found */ sync_if_writable(fd); if(fstat(fd, &st) == -1) goto restoresigset; struct byterange *br; for(br = fds[i].unmapped; br; br = br->next) { DEBUG("fadv_dontneed(fd=%d, from=%zd, len=%zd)\n", fd, br->pos, br->len); fadv_dontneed(fd, br->pos, br->len, nr_fadvise); } /* Has the file grown bigger? */ if(st.st_size > fds[i].size) { DEBUG("fadv_dontneed(fd=%d, from=%lld, len=0 [till new end, file has grown])\n", fd, (long long)fds[i].size); fadv_dontneed(fd, fds[i].size, 0, nr_fadvise); } free_br_list(&fds[i].unmapped); fds[i].fd = -1; restoresigset: sigprocmask(SIG_SETMASK, &old_mask, NULL); }