distinguish between a file's in-memory EOF (which marks the offset at

which we disallow creation of page cache pages) and its on-disk EOF
(which marks the offset at which there is not (yet) data on disk that
we need to read when creating pages).  for requests with PGO_PASTEOF,
the in-memory EOF maybe be much larger than the on-disk EOF.
This commit is contained in:
chs 2001-02-27 02:57:02 +00:00
parent dfd2654fd2
commit f87a22a66b
1 changed files with 26 additions and 33 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs_vnops.c,v 1.29 2001/02/18 15:03:42 chs Exp $ */
/* $NetBSD: genfs_vnops.c,v 1.30 2001/02/27 02:57:02 chs Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -439,7 +439,7 @@ genfs_getpages(v)
int a_flags;
} */ *ap = v;
off_t newsize, eof;
off_t newsize, diskeof, memeof;
off_t offset, origoffset, startoffset, endoffset, raoffset;
daddr_t lbn, blkno;
int s, i, error, npages, orignpages, npgs, run, ridx, pidx, pcount;
@ -457,6 +457,9 @@ genfs_getpages(v)
boolean_t sawhole = FALSE;
UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist);
UVMHIST_LOG(ubchist, "vp %p off 0x%x/%x count %d",
vp, ap->a_offset >> 32, ap->a_offset, *ap->a_count);
/* XXXUBC temp limit */
if (*ap->a_count > 16) {
return EINVAL;
@ -465,41 +468,34 @@ genfs_getpages(v)
error = 0;
origoffset = ap->a_offset;
orignpages = *ap->a_count;
if (flags & PGO_PASTEOF) {
newsize = MAX(vp->v_uvm.u_size,
origoffset + (orignpages << PAGE_SHIFT));
} else {
newsize = vp->v_uvm.u_size;
}
error = VOP_SIZE(vp, newsize, &eof);
error = VOP_SIZE(vp, vp->v_uvm.u_size, &diskeof);
if (error) {
return error;
}
#ifdef DIAGNOSTIC
if (ap->a_centeridx < 0 || ap->a_centeridx > *ap->a_count) {
panic("genfs_getpages: centeridx %d out of range",
ap->a_centeridx);
if (flags & PGO_PASTEOF) {
newsize = MAX(vp->v_uvm.u_size,
origoffset + (orignpages << PAGE_SHIFT));
error = VOP_SIZE(vp, newsize, &memeof);
if (error) {
return error;
}
} else {
memeof = diskeof;
}
if (origoffset & (PAGE_SIZE - 1) || origoffset < 0) {
panic("genfs_getpages: offset 0x%x", (int)ap->a_offset);
}
if (*ap->a_count < 0) {
panic("genfs_getpages: count %d < 0", *ap->a_count);
}
#endif
KASSERT(ap->a_centeridx >= 0 || ap->a_centeridx <= orignpages);
KASSERT((origoffset & (PAGE_SIZE - 1)) == 0 && origoffset >= 0);
KASSERT(orignpages > 0);
/*
* Bounds-check the request.
*/
if (origoffset + (ap->a_centeridx << PAGE_SHIFT) >= eof &&
(flags & PGO_PASTEOF) == 0) {
if (origoffset + (ap->a_centeridx << PAGE_SHIFT) >= memeof) {
if ((flags & PGO_LOCKED) == 0) {
simple_unlock(&uobj->vmobjlock);
}
UVMHIST_LOG(ubchist, "off 0x%x count %d goes past EOF 0x%x",
origoffset, *ap->a_count, eof,0);
origoffset, *ap->a_count, memeof,0);
return EINVAL;
}
@ -529,19 +525,16 @@ genfs_getpages(v)
fs_bsize = 1 << fs_bshift;
dev_bshift = vp->v_mount->mnt_dev_bshift;
dev_bsize = 1 << dev_bshift;
KASSERT((eof & (dev_bsize - 1)) == 0);
KASSERT((diskeof & (dev_bsize - 1)) == 0);
KASSERT((memeof & (dev_bsize - 1)) == 0);
if ((flags & PGO_PASTEOF) == 0) {
orignpages = MIN(orignpages,
round_page(eof - origoffset) >> PAGE_SHIFT);
}
orignpages = MIN(orignpages,
round_page(memeof - origoffset) >> PAGE_SHIFT);
npages = orignpages;
startoffset = origoffset & ~(fs_bsize - 1);
endoffset = round_page((origoffset + (npages << PAGE_SHIFT)
+ fs_bsize - 1) & ~(fs_bsize - 1));
if ((flags & PGO_PASTEOF) == 0) {
endoffset = MIN(endoffset, round_page(eof));
}
endoffset = MIN(endoffset, round_page(memeof));
ridx = (origoffset - startoffset) >> PAGE_SHIFT;
memset(pgs, 0, sizeof(pgs));
@ -626,7 +619,7 @@ genfs_getpages(v)
*/
totalbytes = npages << PAGE_SHIFT;
bytes = MIN(totalbytes, eof - startoffset);
bytes = MIN(totalbytes, MAX(diskeof - startoffset, 0));
tailbytes = totalbytes - bytes;
skipbytes = 0;