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:
parent
dfd2654fd2
commit
f87a22a66b
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue