Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148986267
D30076.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D30076.diff
View Options
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
@@ -3099,13 +3099,13 @@
struct vnode *outvp, off_t *outoffp, size_t *lenp, unsigned int flags,
struct ucred *incred, struct ucred *outcred, struct thread *fsize_td)
{
- struct vattr va;
+ struct vattr va, inva;
struct mount *mp;
struct uio io;
off_t startoff, endoff, xfer, xfer2;
u_long blksize;
int error, interrupted;
- bool cantseek, readzeros, eof, lastblock;
+ bool cantseek, readzeros, eof, lastblock, holetoeof;
ssize_t aresid;
size_t copylen, len, rem, savlen;
char *dat;
@@ -3122,7 +3122,11 @@
goto out;
if (VOP_PATHCONF(invp, _PC_MIN_HOLE_SIZE, &holein) != 0)
holein = 0;
+ if (holein > 0)
+ error = VOP_GETATTR(invp, &inva, incred);
VOP_UNLOCK(invp);
+ if (error != 0)
+ goto out;
mp = NULL;
error = vn_start_write(outvp, &mp, V_WAIT);
@@ -3203,7 +3207,7 @@
* Note that some file systems such as NFSv3, NFSv4.0 and NFSv4.1 may
* support holes on the server, but do not support FIOSEEKHOLE.
*/
- eof = false;
+ holetoeof = eof = false;
while (len > 0 && error == 0 && !eof && interrupted == 0) {
endoff = 0; /* To shut up compilers. */
cantseek = true;
@@ -3212,8 +3216,7 @@
/*
* Find the next data area. If there is just a hole to EOF,
- * FIOSEEKDATA should fail and then we drop down into the
- * inner loop and create the hole on the outvp file.
+ * FIOSEEKDATA should fail with ENXIO.
* (I do not know if any file system will report a hole to
* EOF via FIOSEEKHOLE, but I am pretty sure FIOSEEKDATA
* will fail for those file systems.)
@@ -3222,10 +3225,16 @@
* the code just falls through to the inner copy loop.
*/
error = EINVAL;
- if (holein > 0)
+ if (holein > 0) {
error = VOP_IOCTL(invp, FIOSEEKDATA, &startoff, 0,
incred, curthread);
- if (error == 0) {
+ if (error == ENXIO) {
+ startoff = endoff = inva.va_size;
+ eof = holetoeof = true;
+ error = 0;
+ }
+ }
+ if (error == 0 && !holetoeof) {
endoff = startoff;
error = VOP_IOCTL(invp, FIOSEEKHOLE, &endoff, 0,
incred, curthread);
@@ -3256,11 +3265,12 @@
}
if (error == 0 && *outoffp + xfer >
- va.va_size && xfer == len)
- /* Grow last block. */
+ va.va_size && (xfer == len || holetoeof)) {
+ /* Grow output file (hole at end). */
error = vn_write_outvp(outvp, dat,
*outoffp, xfer, blksize, true,
false, outcred);
+ }
if (error == 0) {
*inoffp += xfer;
*outoffp += xfer;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 22, 1:36 PM (10 h, 3 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30123506
Default Alt Text
D30076.diff (2 KB)
Attached To
Mode
D30076: make vn_generic_copy_file_range() run efficiently when the input file has a large hole to EOF
Attached
Detach File
Event Timeline
Log In to Comment