From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 3/9] repair: ensure prefetched buffers have CRCs validated
Date: Tue, 15 Apr 2014 18:24:55 +1000 [thread overview]
Message-ID: <1397550301-31883-4-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1397550301-31883-1-git-send-email-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
Prefetch currently does not do CRC validation when the IO completes
due to the optimisation it performs and the fact that it does not
know what the type of metadata into the buffer is supposed to be.
Hence, mark all prefetched buffers as "suspect" so that when the
end user tries to read it with a supplied validation function the
validation is run even though the buffer was already in the cache.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 1 +
libxfs/rdwr.c | 36 +++++++++++++++++++++++++++++++-----
repair/prefetch.c | 3 +++
3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index 6bc6c94..6b1e276 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -333,6 +333,7 @@ enum xfs_buf_flags_t { /* b_flags bits */
LIBXFS_B_STALE = 0x0004, /* buffer marked as invalid */
LIBXFS_B_UPTODATE = 0x0008, /* buffer is sync'd to disk */
LIBXFS_B_DISCONTIG = 0x0010, /* discontiguous buffer */
+ LIBXFS_B_UNCHECKED = 0x0020, /* needs verification */
};
#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 7208a2f..a8f06aa 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -718,12 +718,25 @@ libxfs_readbuf(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, int flags,
bp = libxfs_getbuf(btp, blkno, len);
if (!bp)
return NULL;
- if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
+
+ /*
+ * if the buffer was prefetched, it is likely that it was not
+ * validated. Hence if we are supplied an ops function and the
+ * buffer is marked as unchecked, we need to validate it now.
+ */
+ if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) {
+ if (ops && (bp->b_flags & LIBXFS_B_UNCHECKED)) {
+ bp->b_error = 0;
+ bp->b_ops = ops;
+ bp->b_ops->verify_read(bp);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
+ }
return bp;
+ }
/*
- * only set the ops on a cache miss (i.e. first physical read) as the
- * verifier may change the ops to match the typ eof buffer it contains.
+ * Set the ops on a cache miss (i.e. first physical read) as the
+ * verifier may change the ops to match the type of buffer it contains.
* A cache hit might reset the verifier to the original type if we set
* it again, but it won't get called again and set to match the buffer
* contents. *cough* xfs_da_node_buf_ops *cough*.
@@ -733,8 +746,10 @@ libxfs_readbuf(struct xfs_buftarg *btp, xfs_daddr_t blkno, int len, int flags,
error = libxfs_readbufr(btp, blkno, bp, len, flags);
if (error)
bp->b_error = error;
- else if (bp->b_ops)
+ else if (bp->b_ops) {
bp->b_ops->verify_read(bp);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
+ }
return bp;
}
@@ -786,6 +801,14 @@ libxfs_readbuf_map(struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps,
return NULL;
bp->b_error = 0;
+ if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) {
+ if (ops && (bp->b_flags & LIBXFS_B_UNCHECKED)) {
+ bp->b_ops = ops;
+ bp->b_ops->verify_read(bp);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
+ }
+ return bp;
+ }
bp->b_ops = ops;
if ((bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY)))
return bp;
@@ -793,8 +816,10 @@ libxfs_readbuf_map(struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps,
error = libxfs_readbufr_map(btp, bp, flags);
if (!error) {
bp->b_flags |= LIBXFS_B_UPTODATE;
- if (bp->b_ops)
+ if (bp->b_ops) {
bp->b_ops->verify_read(bp);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
+ }
}
#ifdef IO_DEBUG
printf("%lx: %s: read %lu bytes, error %d, blkno=%llu(%llu), %p\n",
@@ -889,6 +914,7 @@ libxfs_writebufr(xfs_buf_t *bp)
if (!error) {
bp->b_flags |= LIBXFS_B_UPTODATE;
bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_EXIT);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
}
return error;
}
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 6d6d344..d794ba3 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -389,6 +389,7 @@ pf_read_inode_dirs(
bp->b_ops = &xfs_inode_buf_ops;
bp->b_ops->verify_read(bp);
+ bp->b_flags &= ~LIBXFS_B_UNCHECKED;
if (bp->b_error)
return;
@@ -460,6 +461,7 @@ pf_read_discontig(
pthread_mutex_unlock(&args->lock);
libxfs_readbufr_map(mp->m_ddev_targp, bp, 0);
+ bp->b_flags |= LIBXFS_B_UNCHECKED;
libxfs_putbuf(bp);
pthread_mutex_lock(&args->lock);
}
@@ -583,6 +585,7 @@ pf_batch_read(
break;
memcpy(XFS_BUF_PTR(bplist[i]), pbuf, size);
bplist[i]->b_flags |= LIBXFS_B_UPTODATE;
+ bplist[i]->b_flags |= LIBXFS_B_UNCHECKED;
len -= size;
if (B_IS_INODE(XFS_BUF_PRIORITY(bplist[i])))
pf_read_inode_dirs(args, bplist[i]);
--
1.9.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2014-04-15 8:25 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-15 8:24 [PATCH 0/9] xfs_db, xfs_repair: improve CRC error detection Dave Chinner
2014-04-15 8:24 ` [PATCH 1/9] db: don't claim unchecked CRCs are correct Dave Chinner
2014-04-21 7:00 ` Christoph Hellwig
2014-04-21 23:13 ` Dave Chinner
2014-04-15 8:24 ` [PATCH 2/9] db: verify buffer on type change Dave Chinner
2014-04-21 7:02 ` Christoph Hellwig
2014-04-21 23:14 ` Dave Chinner
2014-04-15 8:24 ` Dave Chinner [this message]
2014-04-15 19:40 ` [PATCH 3/9] repair: ensure prefetched buffers have CRCs validated Brian Foster
2014-04-15 21:46 ` Dave Chinner
2014-04-15 22:06 ` Brian Foster
2014-04-16 0:41 ` Dave Chinner
2014-04-15 8:24 ` [PATCH 4/9] repair: detect and correct CRC errors in directory blocks Dave Chinner
2014-04-21 7:08 ` Christoph Hellwig
2014-04-15 8:24 ` [PATCH 5/9] repair: detect CRC errors in AG headers Dave Chinner
2014-04-15 19:40 ` Brian Foster
2014-04-15 21:52 ` Dave Chinner
2014-04-21 7:11 ` Christoph Hellwig
2014-04-21 23:35 ` Dave Chinner
2014-04-22 6:47 ` Christoph Hellwig
2014-04-22 9:10 ` Dave Chinner
2014-04-22 9:41 ` Christoph Hellwig
2014-04-15 8:24 ` [PATCH 6/9] repair: report AG btree verifier errors Dave Chinner
2014-04-15 19:40 ` Brian Foster
2014-04-15 21:53 ` Dave Chinner
2014-04-15 8:24 ` [PATCH 7/9] repair: remove more dirv1 leftovers Dave Chinner
2014-04-16 13:23 ` Brian Foster
2014-04-21 7:14 ` Christoph Hellwig
2014-04-21 7:13 ` Christoph Hellwig
2014-04-15 8:25 ` [PATCH 8/9] repair: handle remote sylmlink CRC errors Dave Chinner
2014-04-16 13:23 ` Brian Foster
2014-04-15 8:25 ` [PATCH 9/9] repair: detect and handle attribute tree " Dave Chinner
2014-04-16 13:25 ` Brian Foster
2014-04-21 23:27 ` Dave Chinner
-- strict thread matches above, loose matches on Subject: below --
2014-04-24 5:01 [PATCH 0/9 V2] xfs_db, xfs_repair: improve CRC error detection Dave Chinner
2014-04-24 5:01 ` [PATCH 3/9] repair: ensure prefetched buffers have CRCs validated Dave Chinner
2014-04-25 5:47 ` Christoph Hellwig
2014-04-28 21:04 [PATCH 0/9 v3] xfs_db, xfs_repair: improve CRC error detection Dave Chinner
2014-04-28 21:04 ` [PATCH 3/9] repair: ensure prefetched buffers have CRCs validated Dave Chinner
2014-04-29 14:05 ` Brian Foster
2014-04-29 18:15 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1397550301-31883-4-git-send-email-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).