]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.13/xfs-handle-dquot-buffer-readahead-in-log-recovery-correctly.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.13 / xfs-handle-dquot-buffer-readahead-in-log-recovery-correctly.patch
1 From 7d6a13f023567d573ac362502bb702eda716e654 Mon Sep 17 00:00:00 2001
2 From: Dave Chinner <dchinner@redhat.com>
3 Date: Tue, 12 Jan 2016 07:04:01 +1100
4 Subject: xfs: handle dquot buffer readahead in log recovery correctly
5
6 From: Dave Chinner <dchinner@redhat.com>
7
8 commit 7d6a13f023567d573ac362502bb702eda716e654 upstream.
9
10 When we do dquot readahead in log recovery, we do not use a verifier
11 as the underlying buffer may not have dquots in it. e.g. the
12 allocation operation hasn't yet been replayed. Hence we do not want
13 to fail recovery because we detect an operation to be replayed has
14 not been run yet. This problem was addressed for inodes in commit
15 d891400 ("xfs: inode buffers may not be valid during recovery
16 readahead") but the problem was not recognised to exist for dquots
17 and their buffers as the dquot readahead did not have a verifier.
18
19 The result of not using a verifier is that when the buffer is then
20 next read to replay a dquot modification, the dquot buffer verifier
21 will only be attached to the buffer if *readahead is not complete*.
22 Hence we can read the buffer, replay the dquot changes and then add
23 it to the delwri submission list without it having a verifier
24 attached to it. This then generates warnings in xfs_buf_ioapply(),
25 which catches and warns about this case.
26
27 Fix this and make it handle the same readahead verifier error cases
28 as for inode buffers by adding a new readahead verifier that has a
29 write operation as well as a read operation that marks the buffer as
30 not done if any corruption is detected. Also make sure we don't run
31 readahead if the dquot buffer has been marked as cancelled by
32 recovery.
33
34 This will result in readahead either succeeding and the buffer
35 having a valid write verifier, or readahead failing and the buffer
36 state requiring the subsequent read to resubmit the IO with the new
37 verifier. In either case, this will result in the buffer always
38 ending up with a valid write verifier on it.
39
40 Note: we also need to fix the inode buffer readahead error handling
41 to mark the buffer with EIO. Brian noticed the code I copied from
42 there wrong during review, so fix it at the same time. Add comments
43 linking the two functions that handle readahead verifier errors
44 together so we don't forget this behavioural link in future.
45
46 Signed-off-by: Dave Chinner <dchinner@redhat.com>
47 Reviewed-by: Brian Foster <bfoster@redhat.com>
48 Signed-off-by: Dave Chinner <david@fromorbit.com>
49 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
50
51 ---
52 fs/xfs/libxfs/xfs_dquot_buf.c | 36 ++++++++++++++++++++++++++++++------
53 fs/xfs/libxfs/xfs_inode_buf.c | 2 ++
54 fs/xfs/libxfs/xfs_quota_defs.h | 2 +-
55 fs/xfs/libxfs/xfs_shared.h | 1 +
56 fs/xfs/xfs_log_recover.c | 9 +++++++--
57 5 files changed, 41 insertions(+), 9 deletions(-)
58
59 --- a/fs/xfs/libxfs/xfs_dquot_buf.c
60 +++ b/fs/xfs/libxfs/xfs_dquot_buf.c
61 @@ -54,7 +54,7 @@ xfs_dqcheck(
62 xfs_dqid_t id,
63 uint type, /* used only when IO_dorepair is true */
64 uint flags,
65 - char *str)
66 + const char *str)
67 {
68 xfs_dqblk_t *d = (xfs_dqblk_t *)ddq;
69 int errs = 0;
70 @@ -207,7 +207,8 @@ xfs_dquot_buf_verify_crc(
71 STATIC bool
72 xfs_dquot_buf_verify(
73 struct xfs_mount *mp,
74 - struct xfs_buf *bp)
75 + struct xfs_buf *bp,
76 + int warn)
77 {
78 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
79 xfs_dqid_t id = 0;
80 @@ -240,8 +241,7 @@ xfs_dquot_buf_verify(
81 if (i == 0)
82 id = be32_to_cpu(ddq->d_id);
83
84 - error = xfs_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN,
85 - "xfs_dquot_buf_verify");
86 + error = xfs_dqcheck(mp, ddq, id + i, 0, warn, __func__);
87 if (error)
88 return false;
89 }
90 @@ -256,7 +256,7 @@ xfs_dquot_buf_read_verify(
91
92 if (!xfs_dquot_buf_verify_crc(mp, bp))
93 xfs_buf_ioerror(bp, -EFSBADCRC);
94 - else if (!xfs_dquot_buf_verify(mp, bp))
95 + else if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN))
96 xfs_buf_ioerror(bp, -EFSCORRUPTED);
97
98 if (bp->b_error)
99 @@ -264,6 +264,25 @@ xfs_dquot_buf_read_verify(
100 }
101
102 /*
103 + * readahead errors are silent and simply leave the buffer as !done so a real
104 + * read will then be run with the xfs_dquot_buf_ops verifier. See
105 + * xfs_inode_buf_verify() for why we use EIO and ~XBF_DONE here rather than
106 + * reporting the failure.
107 + */
108 +static void
109 +xfs_dquot_buf_readahead_verify(
110 + struct xfs_buf *bp)
111 +{
112 + struct xfs_mount *mp = bp->b_target->bt_mount;
113 +
114 + if (!xfs_dquot_buf_verify_crc(mp, bp) ||
115 + !xfs_dquot_buf_verify(mp, bp, 0)) {
116 + xfs_buf_ioerror(bp, -EIO);
117 + bp->b_flags &= ~XBF_DONE;
118 + }
119 +}
120 +
121 +/*
122 * we don't calculate the CRC here as that is done when the dquot is flushed to
123 * the buffer after the update is done. This ensures that the dquot in the
124 * buffer always has an up-to-date CRC value.
125 @@ -274,7 +293,7 @@ xfs_dquot_buf_write_verify(
126 {
127 struct xfs_mount *mp = bp->b_target->bt_mount;
128
129 - if (!xfs_dquot_buf_verify(mp, bp)) {
130 + if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN)) {
131 xfs_buf_ioerror(bp, -EFSCORRUPTED);
132 xfs_verifier_error(bp);
133 return;
134 @@ -287,3 +306,8 @@ const struct xfs_buf_ops xfs_dquot_buf_o
135 .verify_write = xfs_dquot_buf_write_verify,
136 };
137
138 +const struct xfs_buf_ops xfs_dquot_buf_ra_ops = {
139 + .name = "xfs_dquot_ra",
140 + .verify_read = xfs_dquot_buf_readahead_verify,
141 + .verify_write = xfs_dquot_buf_write_verify,
142 +};
143 --- a/fs/xfs/libxfs/xfs_inode_buf.c
144 +++ b/fs/xfs/libxfs/xfs_inode_buf.c
145 @@ -68,6 +68,8 @@ xfs_inobp_check(
146 * recovery and we don't get unnecssary panics on debug kernels. We use EIO here
147 * because all we want to do is say readahead failed; there is no-one to report
148 * the error to, so this will distinguish it from a non-ra verifier failure.
149 + * Changes to this readahead error behavour also need to be reflected in
150 + * xfs_dquot_buf_readahead_verify().
151 */
152 static void
153 xfs_inode_buf_verify(
154 --- a/fs/xfs/libxfs/xfs_quota_defs.h
155 +++ b/fs/xfs/libxfs/xfs_quota_defs.h
156 @@ -153,7 +153,7 @@ typedef __uint16_t xfs_qwarncnt_t;
157 #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
158
159 extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq,
160 - xfs_dqid_t id, uint type, uint flags, char *str);
161 + xfs_dqid_t id, uint type, uint flags, const char *str);
162 extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
163
164 #endif /* __XFS_QUOTA_H__ */
165 --- a/fs/xfs/libxfs/xfs_shared.h
166 +++ b/fs/xfs/libxfs/xfs_shared.h
167 @@ -49,6 +49,7 @@ extern const struct xfs_buf_ops xfs_inob
168 extern const struct xfs_buf_ops xfs_inode_buf_ops;
169 extern const struct xfs_buf_ops xfs_inode_buf_ra_ops;
170 extern const struct xfs_buf_ops xfs_dquot_buf_ops;
171 +extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops;
172 extern const struct xfs_buf_ops xfs_sb_buf_ops;
173 extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
174 extern const struct xfs_buf_ops xfs_symlink_buf_ops;
175 --- a/fs/xfs/xfs_log_recover.c
176 +++ b/fs/xfs/xfs_log_recover.c
177 @@ -3204,6 +3204,7 @@ xlog_recover_dquot_ra_pass2(
178 struct xfs_disk_dquot *recddq;
179 struct xfs_dq_logformat *dq_f;
180 uint type;
181 + int len;
182
183
184 if (mp->m_qflags == 0)
185 @@ -3224,8 +3225,12 @@ xlog_recover_dquot_ra_pass2(
186 ASSERT(dq_f);
187 ASSERT(dq_f->qlf_len == 1);
188
189 - xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno,
190 - XFS_FSB_TO_BB(mp, dq_f->qlf_len), NULL);
191 + len = XFS_FSB_TO_BB(mp, dq_f->qlf_len);
192 + if (xlog_peek_buffer_cancelled(log, dq_f->qlf_blkno, len, 0))
193 + return;
194 +
195 + xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno, len,
196 + &xfs_dquot_buf_ra_ops);
197 }
198
199 STATIC void