diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -2099,7 +2099,7 @@ tmpfs_seek_data_locked(vm_object_t obj, off_t noff) { vm_page_t m; - vm_pindex_t p, p_m, p_swp; + vm_pindex_t p, p_swp; p = OFF_TO_IDX(noff); m = vm_page_find_least(obj, p); @@ -2108,15 +2108,24 @@ * Microoptimize the most common case for SEEK_DATA, where * there is no hole and the page is resident. */ - if (m != NULL && vm_page_any_valid(m) && m->pindex == p) + if (m != NULL && m->pindex == p && vm_page_any_valid(m)) return (noff); p_swp = swap_pager_find_least(obj, p); if (p_swp == p) return (noff); - p_m = m == NULL ? obj->size : m->pindex; - return (IDX_TO_OFF(MIN(p_m, p_swp))); + /* + * Find the first resident page after p, before p_swp. + */ + while (m != NULL && m->pindex < p_swp) { + if (vm_page_any_valid(m)) + return (IDX_TO_OFF(m->pindex)); + m = TAILQ_NEXT(m, listq); + } + if (p_swp == OBJ_MAX_SIZE) + p_swp = obj->size; + return (IDX_TO_OFF(p_swp)); } static off_t