Fix rounding in vop_stdadvise() for POSIX_FADV_NOREUSE (really
POSIX_FADV_DONTNEED). The most broken case was for applications that advise for the whole file and then do block-aligned i/o's 1 block at a time. Then advice is sent to VOP_ADVISE() 1 block at a time, but in vop_stdadvise() the 1-block advice was turned into 0-block advice for the buffer cache part. The bugs were caused partly by callers representing the region as (a_start, a_end), where a_end is actually the maximum, and everything else representing the region as (start, end) where 'end' is actually the end (1 after the maximum). The maximum a_end must be rounded up, but was rounded down. Also, rounding to page boundaries was inconsistent. The bugs and fixes have no effect for zfs and other file systems that don't use the buffer cache or the page cache. Most or all file systems currently use the default VOP_FADVISE(), but it finds a null buffer cache and a null page cache for file systems that don't use normal methods. Reviewed by: kib
This commit is contained in:
parent
b9ea8013d1
commit
97d496ecdd
@ -1063,7 +1063,7 @@ vop_stdadvise(struct vop_advise_args *ap)
|
||||
struct vnode *vp;
|
||||
struct bufobj *bo;
|
||||
daddr_t startn, endn;
|
||||
off_t start, end;
|
||||
off_t bstart, bend, start, end;
|
||||
int bsize, error;
|
||||
|
||||
vp = ap->a_vp;
|
||||
@ -1084,6 +1084,19 @@ vop_stdadvise(struct vop_advise_args *ap)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round to block boundaries (and later possibly further to
|
||||
* page boundaries). Applications cannot reasonably be aware
|
||||
* of the boundaries, and the rounding must be to expand at
|
||||
* both extremities to cover enough. It still doesn't cover
|
||||
* read-ahead. For partial blocks, this gives unnecessary
|
||||
* discarding of buffers but is efficient enough since the
|
||||
* pages usually remain in VMIO for some time.
|
||||
*/
|
||||
bsize = vp->v_bufobj.bo_bsize;
|
||||
bstart = roundup(ap->a_start, bsize);
|
||||
bend = roundup(ap->a_end, bsize);
|
||||
|
||||
/*
|
||||
* Deactivate pages in the specified range from the backing VM
|
||||
* object. Pages that are resident in the buffer cache will
|
||||
@ -1091,8 +1104,8 @@ vop_stdadvise(struct vop_advise_args *ap)
|
||||
* below.
|
||||
*/
|
||||
if (vp->v_object != NULL) {
|
||||
start = trunc_page(ap->a_start);
|
||||
end = round_page(ap->a_end);
|
||||
start = trunc_page(bstart);
|
||||
end = round_page(bend);
|
||||
VM_OBJECT_RLOCK(vp->v_object);
|
||||
vm_object_page_noreuse(vp->v_object, OFF_TO_IDX(start),
|
||||
OFF_TO_IDX(end));
|
||||
@ -1101,9 +1114,8 @@ vop_stdadvise(struct vop_advise_args *ap)
|
||||
|
||||
bo = &vp->v_bufobj;
|
||||
BO_RLOCK(bo);
|
||||
bsize = vp->v_bufobj.bo_bsize;
|
||||
startn = ap->a_start / bsize;
|
||||
endn = ap->a_end / bsize;
|
||||
startn = bstart / bsize;
|
||||
endn = bend / bsize;
|
||||
error = bnoreuselist(&bo->bo_clean, bo, startn, endn);
|
||||
if (error == 0)
|
||||
error = bnoreuselist(&bo->bo_dirty, bo, startn, endn);
|
||||
|
Loading…
x
Reference in New Issue
Block a user