summaryrefslogtreecommitdiffstats
path: root/sys/sys/bufobj.h
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-01-23 10:01:19 +0000
committerkib <kib@FreeBSD.org>2007-01-23 10:01:19 +0000
commitfdd50404d125cf6f60a72b7d3483c1d35a62b6b0 (patch)
treeb0e8fba9d4f75f20a608a5e6e9db64ce7633b0f4 /sys/sys/bufobj.h
parent7ebb7b7367c8ec8782e3fd7dfa2fdcf410af02e4 (diff)
downloadFreeBSD-src-fdd50404d125cf6f60a72b7d3483c1d35a62b6b0.zip
FreeBSD-src-fdd50404d125cf6f60a72b7d3483c1d35a62b6b0.tar.gz
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)
Diffstat (limited to 'sys/sys/bufobj.h')
-rw-r--r--sys/sys/bufobj.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/sys/sys/bufobj.h b/sys/sys/bufobj.h
index ea568e4..6650702 100644
--- a/sys/sys/bufobj.h
+++ b/sys/sys/bufobj.h
@@ -70,17 +70,20 @@ struct bufv {
typedef void b_strategy_t(struct bufobj *, struct buf *);
typedef int b_write_t(struct buf *);
typedef int b_sync_t(struct bufobj *, int waitfor, struct thread *td);
+typedef void b_bdflush_t(struct bufobj *, struct buf *);
struct buf_ops {
char *bop_name;
b_write_t *bop_write;
b_strategy_t *bop_strategy;
b_sync_t *bop_sync;
+ b_bdflush_t *bop_bdflush;
};
#define BO_STRATEGY(bo, bp) ((bo)->bo_ops->bop_strategy((bo), (bp)))
#define BO_SYNC(bo, w, td) ((bo)->bo_ops->bop_sync((bo), (w), (td)))
#define BO_WRITE(bo, bp) ((bo)->bo_ops->bop_write((bp)))
+#define BO_BDFLUSH(bo, bp) ((bo)->bo_ops->bop_bdflush((bo), (bp)))
struct bufobj {
struct mtx *bo_mtx; /* Mutex which protects "i" things */
@@ -130,6 +133,7 @@ void bufobj_wrefl(struct bufobj *bo);
int bufobj_invalbuf(struct bufobj *bo, int flags, struct thread *td, int slpflag, int slptimeo);
int bufobj_wwait(struct bufobj *bo, int slpflag, int timeo);
int bufsync(struct bufobj *bo, int waitfor, struct thread *td);
+void bufbdflush(struct bufobj *bo, struct buf *bp);
#endif /* defined(_KERNEL) || defined(_KVM_VNODE) */
#endif /* _SYS_BUFOBJ_H_ */
OpenPOWER on IntegriCloud