svn commit: r253050 - head/sys/fs/ext2fs
Bruce Evans
brde at optusnet.com.au
Tue Jul 9 05:39:37 UTC 2013
On Tue, 9 Jul 2013, Pedro F. Giffuni wrote:
> Author: pfg
> Date: Tue Jul 9 01:31:04 2013
> New Revision: 253050
> URL: http://svnweb.freebsd.org/changeset/base/253050
>
> Log:
> Enhancement when writing an entire block of a file.
>
> Merge from UFS r231313:
>
> This change first attempts the uiomove() to the newly allocated
> (and dirty) buffer and only zeros it if the uiomove() fails. The
> effect is to eliminate the gratuitous zeroing of the buffer in
> the usual case where the uiomove() successfully fills it.
>
> MFC after: 3 days
>
> Modified:
> head/sys/fs/ext2fs/ext2_vnops.c
>
> Modified: head/sys/fs/ext2fs/ext2_vnops.c
> ==============================================================================
> --- head/sys/fs/ext2fs/ext2_vnops.c Tue Jul 9 01:05:28 2013 (r253049)
> +++ head/sys/fs/ext2fs/ext2_vnops.c Tue Jul 9 01:31:04 2013 (r253050)
> @@ -1812,15 +1812,6 @@ ext2_write(struct vop_write_args *ap)
> if (error != 0)
> break;
>
> - /*
> - * If the buffer is not valid and we did not clear garbage
> - * out above, we have to do so here even though the write
> - * covers the entire buffer in order to avoid a mmap()/write
> - * race where another process may see the garbage prior to
> - * the uiomove() for a write replacing it.
> - */
> - if ((bp->b_flags & B_CACHE) == 0 && fs->e2fs_bsize <= xfersize)
> - vfs_bio_clrbuf(bp);
> if ((ioflag & (IO_SYNC|IO_INVAL)) == (IO_SYNC|IO_INVAL))
> bp->b_flags |= B_NOCACHE;
> if (uio->uio_offset + xfersize > ip->i_size)
> @@ -1831,6 +1822,26 @@ ext2_write(struct vop_write_args *ap)
>
> error =
> uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
> + /*
> + * If the buffer is not already filled and we encounter an
> + * error while trying to fill it, we have to clear out any
> + * garbage data from the pages instantiated for the buffer.
> + * If we do not, a failed uiomove() during a write can leave
> + * the prior contents of the pages exposed to a userland mmap.
> + *
> + * Note that we need only clear buffers with a transfer size
> + * equal to the block size because buffers with a shorter
> + * transfer size were cleared above by the call to ext2_balloc()
> + * with the BA_CLRBUF flag set.
> + *
> + * If the source region for uiomove identically mmaps the
> + * buffer, uiomove() performed the NOP copy, and the buffer
> + * content remains valid because the page fault handler
> + * validated the pages.
> + */
> + if (error != 0 && (bp->b_flags & B_CACHE) == 0 &&
> + fs->e2fs_bsize == xfersize)
> + vfs_bio_clrbuf(bp);
> if (ioflag & (IO_VMIO|IO_DIRECT)) {
> bp->b_flags |= B_RELBUF;
> }
>
More information about the svn-src-head
mailing list