diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2021-02-18 14:51:50 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2021-02-24 07:54:50 +0000 |
commit | 49831462794690155ce8dbe02679e6d9390f3d7d (patch) | |
tree | 99b24a50f3fc9c4e62bd13d30022d6e5accbcf36 | |
parent | cc9958bf22f1426faf4be8bf492ce69587a9008f (diff) | |
download | src-49831462794690155ce8dbe02679e6d9390f3d7d.tar.gz src-49831462794690155ce8dbe02679e6d9390f3d7d.zip |
ffs: do not call softdep_prealloc() from UFS_BALLOC()
Do it in ffs_write(), where we can gracefuly handle relock and its
consequences. In particular, recheck the v_data to see if the vnode
reclamation ended, and return EBADF when we cannot proceed with the
write.
Reviewed by: mckusick
Reported by: pho
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
-rw-r--r-- | sys/ufs/ffs/ffs_balloc.c | 5 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 5 |
2 files changed, 5 insertions, 5 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index daa897dfe032..1b53a90a48c4 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -128,8 +128,6 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, return (EFBIG); gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0; - if (DOINGSOFTDEP(vp)) - softdep_prealloc(vp, MNT_WAIT); /* * If the next write will extend the file into a new block, * and the file is currently composed of a fragment @@ -621,9 +619,6 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, return (EFBIG); gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0; - if (DOINGSOFTDEP(vp)) - softdep_prealloc(vp, MNT_WAIT); - /* * Check for allocating external data. */ diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 686bfddcb0ea..db14d2099be9 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -834,6 +834,11 @@ ffs_write(ap) int blkoffset, error, flags, ioflag, size, xfersize; vp = ap->a_vp; + if (DOINGSUJ(vp)) + softdep_prealloc(vp, MNT_WAIT); + if (vp->v_data == NULL) + return (EBADF); + uio = ap->a_uio; ioflag = ap->a_ioflag; if (ap->a_ioflag & IO_EXT) |