Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157310452
D14917.id40972.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D14917.id40972.diff
View Options
Index: sys/kern/vfs_bio.c
===================================================================
--- sys/kern/vfs_bio.c
+++ sys/kern/vfs_bio.c
@@ -3887,8 +3887,9 @@
*/
lockflags = LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK;
- if (flags & GB_LOCK_NOWAIT)
+ if ((flags & GB_LOCK_NOWAIT) != 0)
lockflags |= LK_NOWAIT;
+ bp->b_flags &= ~B_HOLE;
error = BUF_TIMELOCK(bp, lockflags,
BO_LOCKPTR(bo), "getblk", slpflag, slptimeo);
@@ -4006,10 +4007,10 @@
* here.
*/
if (flags & GB_NOCREAT)
- return NULL;
+ return (NULL);
if (bdomain[bo->bo_domain].bd_freebuffers == 0 &&
TD_IS_IDLETHREAD(curthread))
- return NULL;
+ return (NULL);
bsize = vn_isdisk(vp, NULL) ? DEV_BSIZE : bo->bo_bsize;
KASSERT(bsize != 0, ("bsize == 0, check bo->bo_bsize"));
@@ -4027,7 +4028,7 @@
bp = getnewbuf(vp, slpflag, slptimeo, maxsize, flags);
if (bp == NULL) {
if (slpflag || slptimeo)
- return NULL;
+ return (NULL);
/*
* XXX This is here until the sleep path is diagnosed
* enough to work under very low memory conditions.
@@ -4101,6 +4102,10 @@
allocbuf(bp, size);
bufspace_release(bufdomain(bp), maxsize);
bp->b_flags &= ~B_DONE;
+ if (flags & GB_HOLE)
+ bp->b_flags |= B_HOLE;
+ else
+ bp->b_flags &= ~B_HOLE;
}
CTR4(KTR_BUF, "getblk(%p, %ld, %d) = %p", vp, (long)blkno, size, bp);
BUF_ASSERT_HELD(bp);
@@ -4435,6 +4440,7 @@
KASSERT(buf_mapped(bp), ("bufdone: bp %p not mapped", bp));
(*bp->b_ckhashcalc)(bp);
}
+ bp->b_flags &= ~B_HOLE;
/*
* For asynchronous completions, release the buffer now. The brelse
* will do a wakeup there if necessary - so no need to do a wakeup
Index: sys/sys/buf.h
===================================================================
--- sys/sys/buf.h
+++ sys/sys/buf.h
@@ -225,7 +225,7 @@
#define B_NOCACHE 0x00008000 /* Do not cache block after use. */
#define B_MALLOC 0x00010000 /* malloced b_data */
#define B_CLUSTEROK 0x00020000 /* Pagein op, so swap() can count it. */
-#define B_00040000 0x00040000 /* Available flag. */
+#define B_HOLE 0x00040000 /* Do not instantiate hole. */
#define B_00080000 0x00080000 /* Available flag. */
#define B_00100000 0x00100000 /* Available flag. */
#define B_00200000 0x00200000 /* Available flag. */
@@ -479,6 +479,7 @@
#define GB_UNMAPPED 0x0008 /* Do not mmap buffer pages. */
#define GB_KVAALLOC 0x0010 /* But allocate KVA. */
#define GB_CKHASH 0x0020 /* If reading, calc checksum hash */
+#define GB_HOLE 0x0040 /* Do not instantiate holes */
#ifdef _KERNEL
extern int nbuf; /* The number of buffer headers */
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
--- sys/ufs/ffs/ffs_vnops.c
+++ sys/ufs/ffs/ffs_vnops.c
@@ -462,6 +462,26 @@
#endif
}
+static int
+ffs_read_hole(struct uio *uio, long xfersize, long *size)
+{
+ ssize_t saved_resid, tlen;
+ int error;
+
+ while (xfersize > 0) {
+ tlen = min(xfersize, ZERO_REGION_SIZE);
+ saved_resid = uio->uio_resid;
+ error = vn_io_fault_uiomove(__DECONST(void *, zero_region),
+ tlen, uio);
+ if (error != 0)
+ return (error);
+ tlen = saved_resid - uio->uio_resid;
+ xfersize -= tlen;
+ *size -= tlen;
+ }
+ return (0);
+}
+
/*
* Vnode op for reading.
*/
@@ -566,7 +586,7 @@
* Don't do readahead if this is the end of the file.
*/
error = bread_gb(vp, lbn, size, NOCRED,
- GB_UNMAPPED, &bp);
+ GB_UNMAPPED | GB_HOLE, &bp);
} else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
/*
* Otherwise if we are allowed to cluster,
@@ -577,7 +597,7 @@
*/
error = cluster_read(vp, ip->i_size, lbn,
size, NOCRED, blkoffset + uio->uio_resid,
- seqcount, GB_UNMAPPED, &bp);
+ seqcount, GB_UNMAPPED | GB_HOLE, &bp);
} else if (seqcount > 1) {
/*
* If we are NOT allowed to cluster, then
@@ -589,7 +609,8 @@
*/
u_int nextsize = blksize(fs, ip, nextlbn);
error = breadn_flags(vp, lbn, size, &nextlbn,
- &nextsize, 1, NOCRED, GB_UNMAPPED, NULL, &bp);
+ &nextsize, 1, NOCRED, GB_UNMAPPED | GB_HOLE,
+ NULL, &bp);
} else {
/*
* Failing all of the above, just read what the
@@ -597,9 +618,14 @@
* the first option above.
*/
error = bread_gb(vp, lbn, size, NOCRED,
- GB_UNMAPPED, &bp);
+ GB_UNMAPPED | GB_HOLE, &bp);
}
- if (error) {
+ if (error == EJUSTRETURN) {
+ error = ffs_read_hole(uio, xfersize, &size);
+ if (error == 0)
+ continue;
+ }
+ if (error != 0) {
brelse(bp);
bp = NULL;
break;
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
--- sys/ufs/ufs/ufs_vnops.c
+++ sys/ufs/ufs/ufs_vnops.c
@@ -2334,10 +2334,14 @@
bufdone(bp);
return (0);
}
- if ((long)bp->b_blkno == -1)
+ if ((long)bp->b_blkno == -1 && (bp->b_flags & B_HOLE) == 0)
vfs_bio_clrbuf(bp);
}
if ((long)bp->b_blkno == -1) {
+ if ((bp->b_flags & B_HOLE) != 0) {
+ bp->b_error = EJUSTRETURN;
+ bp->b_ioflags |= BIO_ERROR;
+ }
bufdone(bp);
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 21, 5:33 AM (16 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33375890
Default Alt Text
D14917.id40972.diff (4 KB)
Attached To
Mode
D14917: Detect reads from the hole.
Attached
Detach File
Event Timeline
Log In to Comment