]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/commit
MFC of 246876, 246877, and 247387:
authormckusick <mckusick@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Sat, 30 Mar 2013 20:57:35 +0000 (20:57 +0000)
committermckusick <mckusick@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Sat, 30 Mar 2013 20:57:35 +0000 (20:57 +0000)
commit84918e3b634d4d0d21cb70e32d6f43f18e6797c2
treee6e352b170443e00768e03630e709c6a2371c0ce
parent0605cfbae37edce58fddd5f29c81d0047eb2244c
MFC of 246876, 246877, and 247387:
MFC reviewed by: kib

MFC 246876:

Add barrier write capability to the VFS buffer interface. A barrier
write is a disk write request that tells the disk that the buffer
being written must be committed to the media along with any writes
that preceeded it before any future blocks may be written to the drive.

Barrier writes are provided by adding the functions bbarrierwrite
(bwrite with barrier) and babarrierwrite (bawrite with barrier).

Following a bbarrierwrite the client knows that the requested buffer
is on the media. It does not ensure that buffers written before that
buffer are on the media. It only ensure that buffers written before
that buffer will get to the media before any buffers written after
that buffer. A flush command must be sent to the disk to ensure that
all earlier written buffers are on the media.

Reviewed by: kib
Tested by:   Peter Holm

MFC 246877:

The UFS2 filesystem allocates new blocks of inodes as they are needed.
When a cylinder group runs short of inodes, a new block for inodes is
allocated, zero'ed, and written to the disk. The zero'ed inodes must
be on the disk before the cylinder group can be updated to claim them.
If the cylinder group claiming the new inodes were written before the
zero'ed block of inodes, the system could crash with the filesystem in
an unrecoverable state.

Rather than adding a soft updates dependency to ensure that the new
inode block is written before it is claimed by the cylinder group
map, we just do a barrier write of the zero'ed inode block to ensure
that it will get written before the updated cylinder group map can
be written. This change should only slow down bulk loading of newly
created filesystems since that is the primary time that new inode
blocks need to be created.

Reported by: Robert Watson
Reviewed by: kib
Tested by:   Peter Holm

MFC 247387:

An inode block must not be blockingly read while cg block is owned.
The order is inode buffer lock -> snaplk -> cg buffer lock, reversing
the order causes deadlocks.

Inode block must not be written while cg block buffer is owned. The
FFS copy on write needs to allocate a block to copy the content of the
inode block, and the cylinder group selected for the allocation might
be the same as the owned cg block.  The reserved block detection code
in the ffs_copyonwrite() and ffs_bp_snapblk() is unable to detect the
situation, because the locked cg buffer is not exposed to it.

In order to maintain the dependency between initialized inode block
and the cg_initediblk pointer, look up the inode buffer in
non-blocking mode. If succeeded, brelse cg block, initialize the inode
block and write it.  After the write is finished, reread cg block and
update the cg_initediblk.

If inode block is already locked by another thread, let the another
thread initialize it.  If another thread raced with us after we
started writing inode block, the situation is detected by an update of
cg_initediblk.  Note that double-initialization of the inode block is
harmless, the block cannot be used until cg_initediblk is incremented.

Sponsored by:   The FreeBSD Foundation
In collaboration with:  pho
Reviewed by:    mckusick
X-MFC-note:     after r246877

git-svn-id: svn://svn.freebsd.org/base/stable/8@248936 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/geom/geom_vfs.c
sys/kern/vfs_bio.c
sys/kern/vfs_cluster.c
sys/sys/buf.h
sys/ufs/ffs/ffs_alloc.c