Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/tmpfs/tmpfs_vnops.c
Show First 20 Lines • Show All 2,086 Lines • ▼ Show 20 Lines | tmpfs_setextattr(struct vop_setextattr_args *ap) | ||||
} | } | ||||
LIST_INSERT_HEAD(&node->tn_extattrs, new_ea, ea_extattrs); | LIST_INSERT_HEAD(&node->tn_extattrs, new_ea, ea_extattrs); | ||||
return (0); | return (0); | ||||
} | } | ||||
static off_t | static off_t | ||||
tmpfs_seek_data_locked(vm_object_t obj, off_t noff) | tmpfs_seek_data_locked(vm_object_t obj, off_t noff) | ||||
{ | { | ||||
vm_page_t m; | vm_pindex_t p; | ||||
vm_pindex_t p, p_swp; | |||||
p = OFF_TO_IDX(noff); | p = swap_pager_seek_data(obj, OFF_TO_IDX(noff)); | ||||
m = vm_page_find_least(obj, p); | return (p == OFF_TO_IDX(noff) ? noff : IDX_TO_OFF(p)); | ||||
/* | |||||
* Microoptimize the most common case for SEEK_DATA, where | |||||
* there is no hole and the page is resident. | |||||
*/ | |||||
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); | |||||
/* | |||||
* 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 | |||||
tmpfs_seek_next(off_t noff) | |||||
{ | |||||
return (noff + PAGE_SIZE - (noff & PAGE_MASK)); | |||||
} | |||||
static int | static int | ||||
tmpfs_seek_clamp(struct tmpfs_node *tn, off_t *noff, bool seekdata) | tmpfs_seek_clamp(struct tmpfs_node *tn, off_t *noff, bool seekdata) | ||||
{ | { | ||||
if (*noff < tn->tn_size) | if (*noff < tn->tn_size) | ||||
return (0); | return (0); | ||||
if (seekdata) | if (seekdata) | ||||
return (ENXIO); | return (ENXIO); | ||||
*noff = tn->tn_size; | *noff = tn->tn_size; | ||||
return (0); | return (0); | ||||
} | } | ||||
static off_t | static off_t | ||||
tmpfs_seek_hole_locked(vm_object_t obj, off_t noff) | tmpfs_seek_hole_locked(vm_object_t obj, off_t noff) | ||||
{ | { | ||||
vm_page_t m; | |||||
vm_pindex_t p, p_swp; | |||||
for (;; noff = tmpfs_seek_next(noff)) { | return (IDX_TO_OFF(swap_pager_seek_hole(obj, OFF_TO_IDX(noff)))); | ||||
/* | |||||
* Walk over the largest sequential run of the valid pages. | |||||
*/ | |||||
for (m = vm_page_lookup(obj, OFF_TO_IDX(noff)); | |||||
m != NULL && vm_page_any_valid(m); | |||||
m = vm_page_next(m), noff = tmpfs_seek_next(noff)) | |||||
; | |||||
/* | |||||
* Found a hole in the object's page queue. Check if | |||||
* there is a hole in the swap at the same place. | |||||
*/ | |||||
p = OFF_TO_IDX(noff); | |||||
p_swp = swap_pager_find_least(obj, p); | |||||
if (p_swp != p) { | |||||
noff = IDX_TO_OFF(p); | |||||
break; | |||||
} | |||||
} | |||||
return (noff); | |||||
} | } | ||||
static int | static int | ||||
tmpfs_seek_datahole(struct vnode *vp, off_t *off, bool seekdata) | tmpfs_seek_datahole(struct vnode *vp, off_t *off, bool seekdata) | ||||
{ | { | ||||
struct tmpfs_node *tn; | struct tmpfs_node *tn; | ||||
vm_object_t obj; | vm_object_t obj; | ||||
off_t noff; | off_t noff; | ||||
▲ Show 20 Lines • Show All 108 Lines • Show Last 20 Lines |