xfs: add buffer pre-write callback
authorDave Chinner <dchinner@redhat.com>
Mon, 12 Nov 2012 11:54:19 +0000 (22:54 +1100)
committerBen Myers <bpm@sgi.com>
Fri, 16 Nov 2012 03:35:00 +0000 (21:35 -0600)
Add a callback to the buffer write path to enable verification of
the buffer and CRC calculation prior to issuing the write to the
underlying storage.

If the callback function detects some kind of failure or error
condition, it must mark the buffer with an error so that the caller
can take appropriate action. In the case of xfs_buf_ioapply(), a
corrupt metadta buffer willt rigger a shutdown of the filesystem,
because something is clearly wrong and we can't allow corrupt
metadata to be written to disk.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Phil White <pwhite@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h

index fbc965fc075ab212940994e9a1c875496e108fa4..bd1a948ee39c015958d4a46db4990398b183c642 100644 (file)
@@ -569,7 +569,9 @@ found:
         */
        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_);
@@ -1323,6 +1325,20 @@ _xfs_buf_ioapply(
        /* 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 -
index 677b1dc822f448bfaff554b850429a84b95c57c5..51bc16a1cd9c7082456c8c2538531e86408ec6dd 100644 (file)
@@ -155,6 +155,9 @@ typedef struct xfs_buf {
        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