aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode_buf.c36
-rw-r--r--fs/xfs/xfs_inode_buf.h1
-rw-r--r--fs/xfs/xfs_log_recover.c2
3 files changed, 35 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode_buf.c b/fs/xfs/xfs_inode_buf.c
index 38fe509827dd..e011d597f12f 100644
--- a/fs/xfs/xfs_inode_buf.c
+++ b/fs/xfs/xfs_inode_buf.c
@@ -61,9 +61,22 @@ xfs_inobp_check(
61} 61}
62#endif 62#endif
63 63
64/*
65 * If we are doing readahead on an inode buffer, we might be in log recovery
66 * reading an inode allocation buffer that hasn't yet been replayed, and hence
67 * has not had the inode cores stamped into it. Hence for readahead, the buffer
68 * may be potentially invalid.
69 *
70 * If the readahead buffer is invalid, we don't want to mark it with an error,
71 * but we do want to clear the DONE status of the buffer so that a followup read
72 * will re-read it from disk. This will ensure that we don't get an unnecessary
73 * warnings during log recovery and we don't get unnecssary panics on debug
74 * kernels.
75 */
64static void 76static void
65xfs_inode_buf_verify( 77xfs_inode_buf_verify(
66 struct xfs_buf *bp) 78 struct xfs_buf *bp,
79 bool readahead)
67{ 80{
68 struct xfs_mount *mp = bp->b_target->bt_mount; 81 struct xfs_mount *mp = bp->b_target->bt_mount;
69 int i; 82 int i;
@@ -84,6 +97,11 @@ xfs_inode_buf_verify(
84 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, 97 if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
85 XFS_ERRTAG_ITOBP_INOTOBP, 98 XFS_ERRTAG_ITOBP_INOTOBP,
86 XFS_RANDOM_ITOBP_INOTOBP))) { 99 XFS_RANDOM_ITOBP_INOTOBP))) {
100 if (readahead) {
101 bp->b_flags &= ~XBF_DONE;
102 return;
103 }
104
87 xfs_buf_ioerror(bp, EFSCORRUPTED); 105 xfs_buf_ioerror(bp, EFSCORRUPTED);
88 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH, 106 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
89 mp, dip); 107 mp, dip);
@@ -104,14 +122,21 @@ static void
104xfs_inode_buf_read_verify( 122xfs_inode_buf_read_verify(
105 struct xfs_buf *bp) 123 struct xfs_buf *bp)
106{ 124{
107 xfs_inode_buf_verify(bp); 125 xfs_inode_buf_verify(bp, false);
126}
127
128static void
129xfs_inode_buf_readahead_verify(
130 struct xfs_buf *bp)
131{
132 xfs_inode_buf_verify(bp, true);
108} 133}
109 134
110static void 135static void
111xfs_inode_buf_write_verify( 136xfs_inode_buf_write_verify(
112 struct xfs_buf *bp) 137 struct xfs_buf *bp)
113{ 138{
114 xfs_inode_buf_verify(bp); 139 xfs_inode_buf_verify(bp, false);
115} 140}
116 141
117const struct xfs_buf_ops xfs_inode_buf_ops = { 142const struct xfs_buf_ops xfs_inode_buf_ops = {
@@ -119,6 +144,11 @@ const struct xfs_buf_ops xfs_inode_buf_ops = {
119 .verify_write = xfs_inode_buf_write_verify, 144 .verify_write = xfs_inode_buf_write_verify,
120}; 145};
121 146
147const struct xfs_buf_ops xfs_inode_buf_ra_ops = {
148 .verify_read = xfs_inode_buf_readahead_verify,
149 .verify_write = xfs_inode_buf_write_verify,
150};
151
122 152
123/* 153/*
124 * This routine is called to map an inode to the buffer containing the on-disk 154 * This routine is called to map an inode to the buffer containing the on-disk
diff --git a/fs/xfs/xfs_inode_buf.h b/fs/xfs/xfs_inode_buf.h
index aae9fc465fe0..599e6c0ca2a9 100644
--- a/fs/xfs/xfs_inode_buf.h
+++ b/fs/xfs/xfs_inode_buf.h
@@ -48,5 +48,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
48#endif /* DEBUG */ 48#endif /* DEBUG */
49 49
50extern const struct xfs_buf_ops xfs_inode_buf_ops; 50extern const struct xfs_buf_ops xfs_inode_buf_ops;
51extern const struct xfs_buf_ops xfs_inode_buf_ra_ops;
51 52
52#endif /* __XFS_INODE_BUF_H__ */ 53#endif /* __XFS_INODE_BUF_H__ */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index dc100fed1973..7c0c1fdc728b 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3309,7 +3309,7 @@ xlog_recover_inode_ra_pass2(
3309 return; 3309 return;
3310 3310
3311 xfs_buf_readahead(mp->m_ddev_targp, ilfp->ilf_blkno, 3311 xfs_buf_readahead(mp->m_ddev_targp, ilfp->ilf_blkno,
3312 ilfp->ilf_len, &xfs_inode_buf_ops); 3312 ilfp->ilf_len, &xfs_inode_buf_ra_ops);
3313} 3313}
3314 3314
3315STATIC void 3315STATIC void