diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2020-10-09 20:31:42 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2020-10-09 20:31:42 +0000 |
commit | deb1339f3f8c9325fffc551e622bf835a08dcd8c (patch) | |
tree | bfb17aeb31a2bb886d59a5a081b776951dabe885 | |
parent | 7e8bd70cff019c5aa0bf1a69e3e1fa00985c358d (diff) | |
download | src-deb1339f3f8c9325fffc551e622bf835a08dcd8c.tar.gz src-deb1339f3f8c9325fffc551e622bf835a08dcd8c.zip |
vfs: fix a panic when truncating comming from copy_file_range
Truncating requires an exclusive lock, but it was not taken if the
filesystem indicates support for shared writes. This only concerns
ZFS.
In particular fixes cp of files which have trailing holes.
Reported by: bdrewery
Notes
Notes:
svn path=/head/; revision=366587
-rw-r--r-- | sys/kern/vfs_vnops.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index fc71f536200d..5c07afcc02e7 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -2975,18 +2975,22 @@ vn_write_outvp(struct vnode *outvp, char *dat, off_t outoff, off_t xfer, bwillwrite(); mp = NULL; error = vn_start_write(outvp, &mp, V_WAIT); - if (error == 0) { + if (error != 0) + break; + if (growfile) { + error = vn_lock(outvp, LK_EXCLUSIVE); + if (error == 0) { + error = vn_truncate_locked(outvp, outoff + xfer, + false, cred); + VOP_UNLOCK(outvp); + } + } else { if (MNT_SHARED_WRITES(mp)) lckf = LK_SHARED; else lckf = LK_EXCLUSIVE; error = vn_lock(outvp, lckf); - } - if (error == 0) { - if (growfile) - error = vn_truncate_locked(outvp, outoff + xfer, - false, cred); - else { + if (error == 0) { error = vn_rdwr(UIO_WRITE, outvp, dat, xfer2, outoff, UIO_SYSSPACE, IO_NODELOCKED, curthread->td_ucred, cred, NULL, curthread); |