aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-10-09 20:31:42 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-10-09 20:31:42 +0000
commitdeb1339f3f8c9325fffc551e622bf835a08dcd8c (patch)
treebfb17aeb31a2bb886d59a5a081b776951dabe885
parent7e8bd70cff019c5aa0bf1a69e3e1fa00985c358d (diff)
downloadsrc-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.c18
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);