]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/xfs/xfs_buf_item.c
Merge remote-tracking branches 'regulator/topic/db8500', 'regulator/topic/gpio',...
[karo-tx-linux.git] / fs / xfs / xfs_buf_item.c
index a64f67ba25d3c99c748e1d4a8f84f7648e3dd651..2227b9b050bb30248d986b343dd33e42c7978529 100644 (file)
@@ -496,6 +496,14 @@ xfs_buf_item_unpin(
        }
 }
 
+/*
+ * Buffer IO error rate limiting. Limit it to no more than 10 messages per 30
+ * seconds so as to not spam logs too much on repeated detection of the same
+ * buffer being bad..
+ */
+
+DEFINE_RATELIMIT_STATE(xfs_buf_write_fail_rl_state, 30 * HZ, 10);
+
 STATIC uint
 xfs_buf_item_push(
        struct xfs_log_item     *lip,
@@ -524,6 +532,14 @@ xfs_buf_item_push(
 
        trace_xfs_buf_item_push(bip);
 
+       /* has a previous flush failed due to IO errors? */
+       if ((bp->b_flags & XBF_WRITE_FAIL) &&
+           ___ratelimit(&xfs_buf_write_fail_rl_state, "XFS:")) {
+               xfs_warn(bp->b_target->bt_mount,
+"Detected failing async write on buffer block 0x%llx. Retrying async write.\n",
+                        (long long)bp->b_bn);
+       }
+
        if (!xfs_buf_delwri_queue(bp, buffer_list))
                rval = XFS_ITEM_FLUSHING;
        xfs_buf_unlock(bp);
@@ -1096,8 +1112,9 @@ xfs_buf_iodone_callbacks(
 
                xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */
 
-               if (!XFS_BUF_ISSTALE(bp)) {
-                       bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE;
+               if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) {
+                       bp->b_flags |= XBF_WRITE | XBF_ASYNC |
+                                      XBF_DONE | XBF_WRITE_FAIL;
                        xfs_buf_iorequest(bp);
                } else {
                        xfs_buf_relse(bp);