diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2020-11-30 17:03:26 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2020-11-30 17:03:26 +0000 |
commit | 21a45add50f1b1eb7e52e6adb859ae6c9fe0be5a (patch) | |
tree | 50a7742c3385fd611fff225adbbb02b77581f526 | |
parent | ec5fed758cbe1552c4716f2ac615d09a68905bca (diff) | |
download | src-21a45add50f1b1eb7e52e6adb859ae6c9fe0be5a.tar.gz src-21a45add50f1b1eb7e52e6adb859ae6c9fe0be5a.zip |
ffs: do not read full direct blocks if they are going to be overwritten.
BA_CLRBUF specifies that existing context of the block will be
completely overwritten by caller, so there is no reason to spend io
fetching existing data. We do the same for indirect blocks.
Reported by: tmunro
Reviewed by: mckusick, tmunro
Tested by: pho, tmunro
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D27353
Notes
Notes:
svn path=/head/; revision=368191
-rw-r--r-- | sys/ufs/ffs/ffs_balloc.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index be0fadde312c..daa897dfe032 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -172,9 +172,17 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); nb = dp->di_db[lbn]; if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { - error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); - if (error) { - return (error); + if ((flags & BA_CLRBUF) != 0) { + error = bread(vp, lbn, fs->fs_bsize, NOCRED, + &bp); + if (error != 0) + return (error); + } else { + bp = getblk(vp, lbn, fs->fs_bsize, 0, 0, + gbflags); + if (bp == NULL) + return (EIO); + vfs_bio_clrbuf(bp); } bp->b_blkno = fsbtodb(fs, nb); *bpp = bp; @@ -768,10 +776,17 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); nb = dp->di_db[lbn]; if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { - error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED, - gbflags, &bp); - if (error) { - return (error); + if ((flags & BA_CLRBUF) != 0) { + error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED, + gbflags, &bp); + if (error != 0) + return (error); + } else { + bp = getblk(vp, lbn, fs->fs_bsize, 0, 0, + gbflags); + if (bp == NULL) + return (EIO); + vfs_bio_clrbuf(bp); } bp->b_blkno = fsbtodb(fs, nb); *bpp = bp; |