aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-11-30 17:03:26 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-11-30 17:03:26 +0000
commit21a45add50f1b1eb7e52e6adb859ae6c9fe0be5a (patch)
tree50a7742c3385fd611fff225adbbb02b77581f526
parentec5fed758cbe1552c4716f2ac615d09a68905bca (diff)
downloadsrc-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.c29
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;