diff --git a/bsd/sys/buf_internal.h b/bsd/sys/buf_internal.h index 5319f03e9..29e63ee06 100644 --- a/bsd/sys/buf_internal.h +++ b/bsd/sys/buf_internal.h @@ -126,6 +126,7 @@ struct buf { TAILQ_ENTRY(buf) b_act; /* Device driver queue when active */ void * b_drvdata; /* Device driver private use */ void * b_fsprivate; /* filesystem private use */ + void (*b_fsprivate_done)(void *); /* callback for fs to cleanup its data. */ void * b_transaction; /* journal private use */ int b_dirtyoff; /* Offset in buffer of dirty region. */ int b_dirtyend; /* Offset of end of dirty region. */ diff --git a/bsd/vfs/vfs_bio.c b/bsd/vfs/vfs_bio.c index 1c1318840..8c21b1d21 100644 --- a/bsd/vfs/vfs_bio.c +++ b/bsd/vfs/vfs_bio.c @@ -1113,10 +1113,14 @@ buf_fsprivate(buf_t bp) return bp->b_fsprivate; } +// if NULL callback is passed, it's ignored void -buf_setfsprivate(buf_t bp, void *fsprivate) +buf_setfsprivate(buf_t bp, void *fsprivate, (*release_callback)(void *)) { bp->b_fsprivate = fsprivate; + if (release_callback != NULL){ + bp->b_fsprivate_done = release_callback; + } } kauth_cred_t @@ -3921,6 +3925,10 @@ bcleanbuf(buf_t bp, boolean_t discard) bp->b_bufsize = 0; bp->b_datap = (uintptr_t)NULL; bp->b_upl = (void *)NULL; + /* call fs callback to release private data */ + if (bp->b_fsprivate_done != NULL){ + (void)b_fsprivate_done(bp->b_fsprivate); + } bp->b_fsprivate = (void *)NULL; /* * preserve the state of whether this buffer @@ -4493,6 +4501,7 @@ alloc_io_buf(vnode_t vp, int priv) bp->b_bufsize = 0; bp->b_upl = NULL; bp->b_fsprivate = (void *)NULL; + bp->b_fsprivate_done = NULL; bp->b_vp = vp; bzero(&bp->b_attr, sizeof(struct bufattr)); diff --git a/tools/lldbmacros/memory.py b/tools/lldbmacros/memory.py index 58d2f4f04..d2b7ad36e 100755 --- a/tools/lldbmacros/memory.py +++ b/tools/lldbmacros/memory.py @@ -4151,7 +4151,7 @@ def _GetBufSummary(buf): buf.b_flags, buf.b_lflags, buf.b_error, buf.b_bufsize, buf.b_bcount, buf.b_resid, buf.b_dev, buf.b_datap, buf.b_lblkno, buf.b_blkno, buf.b_iodone, buf.b_vp, buf.b_rcred, buf.b_wcred, buf.b_upl, buf.b_real_bp, buf.b_act, buf.b_drvdata, - buf.b_fsprivate, buf.b_transaction, buf.b_dirtyoff, buf.b_dirtyend, buf.b_validoff, + buf.b_fsprivate, buf.b_fsprivate_done, buf.b_transaction, buf.b_dirtyoff, buf.b_dirtyend, buf.b_validoff, buf.b_validend, buf.b_redundancy_flags, buf.b_proc, buf.b_attr] # Join an (already decent) string representation of each field