*/
        if (bp->b_flags & XBF_STALE) {
                ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
+               ASSERT(bp->b_iodone == NULL);
                bp->b_flags &= _XBF_KMEM | _XBF_PAGES;
+               bp->b_pre_io = NULL;
        }
 
        trace_xfs_buf_find(bp, flags, _RET_IP_);
        /* we only use the buffer cache for meta-data */
        rw |= REQ_META;
 
+       /*
+        * run the pre-io callback function if it exists. If this function
+        * fails it will mark the buffer with an error and the IO should
+        * not be dispatched.
+        */
+       if (bp->b_pre_io) {
+               bp->b_pre_io(bp);
+               if (bp->b_error) {
+                       xfs_force_shutdown(bp->b_target->bt_mount,
+                                          SHUTDOWN_CORRUPT_INCORE);
+                       return;
+               }
+       }
+
        /*
         * Walk all the vectors issuing IO on them. Set up the initial offset
         * into the buffer and the desired IO size before we start -
 
        unsigned int            b_offset;       /* page offset in first page */
        unsigned short          b_error;        /* error code on I/O */
 
+       void                    (*b_pre_io)(struct xfs_buf *);
+                                               /* pre-io callback function */
+
 #ifdef XFS_BUF_LOCK_TRACKING
        int                     b_last_holder;
 #endif