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
This commit is contained in:
Konstantin Belousov 2020-11-30 17:03:26 +00:00
parent ec5fed758c
commit 21a45add50

View File

@ -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;