aboutsummaryrefslogtreecommitdiff
path: root/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2007-01-23 10:01:19 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2007-01-23 10:01:19 +0000
commit2cc7d26f7f9d897fb38b9cf621a73b89a3dd8365 (patch)
treeb0e8fba9d4f75f20a608a5e6e9db64ce7633b0f4 /sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
parent1f294570c0b513e3c7f73e495d5105ede3a74dda (diff)
downloadsrc-2cc7d26f7f9d897fb38b9cf621a73b89a3dd8365.tar.gz
src-2cc7d26f7f9d897fb38b9cf621a73b89a3dd8365.zip
Cylinder group bitmaps and blocks containing inode for a snapshot
file are after snaplock, while other ffs device buffers are before snaplock in global lock order. By itself, this could cause deadlock when bdwrite() tries to flush dirty buffers on snapshotted ffs. If, during the flush, COW activity for snapshot needs to allocate block and ffs_alloccg() selects the cylinder group that is being written by bdwrite(), then kernel would panic due to recursive buffer lock acquision. Avoid dealing with buffers in bdwrite() that are from other side of snaplock divisor in the lock order then the buffer being written. Add new BOP, bop_bdwrite(), to do dirty buffer flushing for same vnode in the bdwrite(). Default implementation, bufbdflush(), refactors the code from bdwrite(). For ffs device buffers, specialized implementation is used. Reviewed by: tegge, jeff, Russell Cattelan (cattelan xfs org, xfs changes) Tested by: Peter Holm X-MFC after: 3 weeks (if ever: it changes ABI)
Notes
Notes: svn path=/head/; revision=166193
Diffstat (limited to 'sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c')
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
index cf4ae89c6328..da3650b3993b 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
@@ -497,9 +497,16 @@ xfs_geom_bufsync(struct bufobj *bo, int waitfor, struct thread *td)
return bufsync(bo,waitfor,td);
}
+static void
+xfs_geom_bufbdflush(struct bufobj *bo, struct buf *bp)
+{
+ bufbdflush(bo, bp);
+}
+
struct buf_ops xfs_bo_ops = {
.bop_name = "XFS",
.bop_write = xfs_geom_bufwrite,
.bop_strategy = xfs_geom_strategy,
.bop_sync = xfs_geom_bufsync,
+ .bop_bdflush = xfs_geom_bufbdflush,
};