Page MenuHomeFreeBSD

D14917.id40972.diff
No OneTemporary

D14917.id40972.diff

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

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)

Event Timeline