Page MenuHomeFreeBSD

D37076.id113222.diff
No OneTemporary

D37076.id113222.diff

diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3266,7 +3266,7 @@
int error, interrupted;
bool cantseek, readzeros, eof, lastblock, holetoeof;
ssize_t aresid, r = 0;
- size_t copylen, len, rem, savlen;
+ size_t copylen, len, savlen;
char *dat;
long holein, holeout;
struct timespec curts, endts;
@@ -3338,31 +3338,38 @@
if (error != 0)
goto out;
- /*
- * Set the blksize to the larger of the hole sizes for invp and outvp.
- * If hole sizes aren't available, set the blksize to the larger
- * f_iosize of invp and outvp.
- * This code expects the hole sizes and f_iosizes to be powers of 2.
- * This value is clipped at 4Kbytes and 1Mbyte.
- */
- blksize = MAX(holein, holeout);
-
- /* Clip len to end at an exact multiple of hole size. */
- if (blksize > 1) {
- rem = *inoffp % blksize;
- if (rem > 0)
- rem = blksize - rem;
- if (len > rem && len - rem > blksize)
- len = savlen = rounddown(len - rem, blksize) + rem;
- }
-
- if (blksize <= 1)
+ if (holein == 0 && holeout > 0) {
+ /*
+ * For this special case, the input data will be scanned
+ * for blocks of all 0 bytes. For these blocks, the
+ * write can be skipped for the output file to create
+ * an unallocated region.
+ * Therefore, use the appropriate size for the output file.
+ */
+ blksize = holeout;
+ if (blksize <= 512) {
+ /*
+ * Use f_iosize, since ZFS reports a _PC_MIN_HOLE_SIZE
+ * of 512, although it actually only creates
+ * unallocated regions for blocks >= f_iosize.
+ */
+ blksize = outvp->v_mount->mnt_stat.f_iosize;
+ }
+ } else {
+ /*
+ * Use the larger of the two f_iosize values. If they are
+ * not the same size, one will normally be an exact multiple of
+ * the other, since they are both likely to be a power of 2.
+ */
blksize = MAX(invp->v_mount->mnt_stat.f_iosize,
outvp->v_mount->mnt_stat.f_iosize);
+ }
+
+ /* Clip to sane limits. */
if (blksize < 4096)
blksize = 4096;
- else if (blksize > 1024 * 1024)
- blksize = 1024 * 1024;
+ else if (blksize > maxphys)
+ blksize = maxphys;
dat = malloc(blksize, M_TEMP, M_WAITOK);
/*

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 28, 6:08 AM (8 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37398117
Default Alt Text
D37076.id113222.diff (2 KB)

Event Timeline