• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3  * Copyright (c) 2013 Red Hat, Inc.
4  * All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it would be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write the Free Software Foundation,
17  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 #include "xfs.h"
20 #include "xfs_fs.h"
21 #include "xfs_shared.h"
22 #include "xfs_format.h"
23 #include "xfs_log_format.h"
24 #include "xfs_trans_resv.h"
25 #include "xfs_mount.h"
26 #include "xfs_inode.h"
27 #include "xfs_quota.h"
28 #include "xfs_trans.h"
29 #include "xfs_qm.h"
30 #include "xfs_error.h"
31 #include "xfs_cksum.h"
32 #include "xfs_trace.h"
33 
34 int
xfs_calc_dquots_per_chunk(unsigned int nbblks)35 xfs_calc_dquots_per_chunk(
36 	unsigned int		nbblks)	/* basic block units */
37 {
38 	unsigned int	ndquots;
39 
40 	ASSERT(nbblks > 0);
41 	ndquots = BBTOB(nbblks);
42 	do_div(ndquots, sizeof(xfs_dqblk_t));
43 
44 	return ndquots;
45 }
46 
47 /*
48  * Do some primitive error checking on ondisk dquot data structures.
49  */
50 int
xfs_dqcheck(struct xfs_mount * mp,xfs_disk_dquot_t * ddq,xfs_dqid_t id,uint type,uint flags,const char * str)51 xfs_dqcheck(
52 	struct xfs_mount *mp,
53 	xfs_disk_dquot_t *ddq,
54 	xfs_dqid_t	 id,
55 	uint		 type,	  /* used only when IO_dorepair is true */
56 	uint		 flags,
57 	const char	 *str)
58 {
59 	xfs_dqblk_t	 *d = (xfs_dqblk_t *)ddq;
60 	int		errs = 0;
61 
62 	/*
63 	 * We can encounter an uninitialized dquot buffer for 2 reasons:
64 	 * 1. If we crash while deleting the quotainode(s), and those blks got
65 	 *    used for user data. This is because we take the path of regular
66 	 *    file deletion; however, the size field of quotainodes is never
67 	 *    updated, so all the tricks that we play in itruncate_finish
68 	 *    don't quite matter.
69 	 *
70 	 * 2. We don't play the quota buffers when there's a quotaoff logitem.
71 	 *    But the allocation will be replayed so we'll end up with an
72 	 *    uninitialized quota block.
73 	 *
74 	 * This is all fine; things are still consistent, and we haven't lost
75 	 * any quota information. Just don't complain about bad dquot blks.
76 	 */
77 	if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) {
78 		if (flags & XFS_QMOPT_DOWARN)
79 			xfs_alert(mp,
80 			"%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
81 			str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
82 		errs++;
83 	}
84 	if (ddq->d_version != XFS_DQUOT_VERSION) {
85 		if (flags & XFS_QMOPT_DOWARN)
86 			xfs_alert(mp,
87 			"%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
88 			str, id, ddq->d_version, XFS_DQUOT_VERSION);
89 		errs++;
90 	}
91 
92 	if (ddq->d_flags != XFS_DQ_USER &&
93 	    ddq->d_flags != XFS_DQ_PROJ &&
94 	    ddq->d_flags != XFS_DQ_GROUP) {
95 		if (flags & XFS_QMOPT_DOWARN)
96 			xfs_alert(mp,
97 			"%s : XFS dquot ID 0x%x, unknown flags 0x%x",
98 			str, id, ddq->d_flags);
99 		errs++;
100 	}
101 
102 	if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
103 		if (flags & XFS_QMOPT_DOWARN)
104 			xfs_alert(mp,
105 			"%s : ondisk-dquot 0x%p, ID mismatch: "
106 			"0x%x expected, found id 0x%x",
107 			str, ddq, id, be32_to_cpu(ddq->d_id));
108 		errs++;
109 	}
110 
111 	if (!errs && ddq->d_id) {
112 		if (ddq->d_blk_softlimit &&
113 		    be64_to_cpu(ddq->d_bcount) >
114 				be64_to_cpu(ddq->d_blk_softlimit)) {
115 			if (!ddq->d_btimer) {
116 				if (flags & XFS_QMOPT_DOWARN)
117 					xfs_alert(mp,
118 			"%s : Dquot ID 0x%x (0x%p) BLK TIMER NOT STARTED",
119 					str, (int)be32_to_cpu(ddq->d_id), ddq);
120 				errs++;
121 			}
122 		}
123 		if (ddq->d_ino_softlimit &&
124 		    be64_to_cpu(ddq->d_icount) >
125 				be64_to_cpu(ddq->d_ino_softlimit)) {
126 			if (!ddq->d_itimer) {
127 				if (flags & XFS_QMOPT_DOWARN)
128 					xfs_alert(mp,
129 			"%s : Dquot ID 0x%x (0x%p) INODE TIMER NOT STARTED",
130 					str, (int)be32_to_cpu(ddq->d_id), ddq);
131 				errs++;
132 			}
133 		}
134 		if (ddq->d_rtb_softlimit &&
135 		    be64_to_cpu(ddq->d_rtbcount) >
136 				be64_to_cpu(ddq->d_rtb_softlimit)) {
137 			if (!ddq->d_rtbtimer) {
138 				if (flags & XFS_QMOPT_DOWARN)
139 					xfs_alert(mp,
140 			"%s : Dquot ID 0x%x (0x%p) RTBLK TIMER NOT STARTED",
141 					str, (int)be32_to_cpu(ddq->d_id), ddq);
142 				errs++;
143 			}
144 		}
145 	}
146 
147 	if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
148 		return errs;
149 
150 	if (flags & XFS_QMOPT_DOWARN)
151 		xfs_notice(mp, "Re-initializing dquot ID 0x%x", id);
152 
153 	/*
154 	 * Typically, a repair is only requested by quotacheck.
155 	 */
156 	ASSERT(id != -1);
157 	ASSERT(flags & XFS_QMOPT_DQREPAIR);
158 	memset(d, 0, sizeof(xfs_dqblk_t));
159 
160 	d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
161 	d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
162 	d->dd_diskdq.d_flags = type;
163 	d->dd_diskdq.d_id = cpu_to_be32(id);
164 
165 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
166 		uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid);
167 		xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
168 				 XFS_DQUOT_CRC_OFF);
169 	}
170 
171 	return errs;
172 }
173 
174 STATIC bool
xfs_dquot_buf_verify_crc(struct xfs_mount * mp,struct xfs_buf * bp)175 xfs_dquot_buf_verify_crc(
176 	struct xfs_mount	*mp,
177 	struct xfs_buf		*bp)
178 {
179 	struct xfs_dqblk	*d = (struct xfs_dqblk *)bp->b_addr;
180 	int			ndquots;
181 	int			i;
182 
183 	if (!xfs_sb_version_hascrc(&mp->m_sb))
184 		return true;
185 
186 	/*
187 	 * if we are in log recovery, the quota subsystem has not been
188 	 * initialised so we have no quotainfo structure. In that case, we need
189 	 * to manually calculate the number of dquots in the buffer.
190 	 */
191 	if (mp->m_quotainfo)
192 		ndquots = mp->m_quotainfo->qi_dqperchunk;
193 	else
194 		ndquots = xfs_calc_dquots_per_chunk(bp->b_length);
195 
196 	for (i = 0; i < ndquots; i++, d++) {
197 		if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
198 				 XFS_DQUOT_CRC_OFF))
199 			return false;
200 		if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_meta_uuid))
201 			return false;
202 	}
203 	return true;
204 }
205 
206 STATIC bool
xfs_dquot_buf_verify(struct xfs_mount * mp,struct xfs_buf * bp,int warn)207 xfs_dquot_buf_verify(
208 	struct xfs_mount	*mp,
209 	struct xfs_buf		*bp,
210 	int			warn)
211 {
212 	struct xfs_dqblk	*d = (struct xfs_dqblk *)bp->b_addr;
213 	xfs_dqid_t		id = 0;
214 	int			ndquots;
215 	int			i;
216 
217 	/*
218 	 * if we are in log recovery, the quota subsystem has not been
219 	 * initialised so we have no quotainfo structure. In that case, we need
220 	 * to manually calculate the number of dquots in the buffer.
221 	 */
222 	if (mp->m_quotainfo)
223 		ndquots = mp->m_quotainfo->qi_dqperchunk;
224 	else
225 		ndquots = xfs_calc_dquots_per_chunk(bp->b_length);
226 
227 	/*
228 	 * On the first read of the buffer, verify that each dquot is valid.
229 	 * We don't know what the id of the dquot is supposed to be, just that
230 	 * they should be increasing monotonically within the buffer. If the
231 	 * first id is corrupt, then it will fail on the second dquot in the
232 	 * buffer so corruptions could point to the wrong dquot in this case.
233 	 */
234 	for (i = 0; i < ndquots; i++) {
235 		struct xfs_disk_dquot	*ddq;
236 		int			error;
237 
238 		ddq = &d[i].dd_diskdq;
239 
240 		if (i == 0)
241 			id = be32_to_cpu(ddq->d_id);
242 
243 		error = xfs_dqcheck(mp, ddq, id + i, 0, warn, __func__);
244 		if (error)
245 			return false;
246 	}
247 	return true;
248 }
249 
250 static void
xfs_dquot_buf_read_verify(struct xfs_buf * bp)251 xfs_dquot_buf_read_verify(
252 	struct xfs_buf	*bp)
253 {
254 	struct xfs_mount	*mp = bp->b_target->bt_mount;
255 
256 	if (!xfs_dquot_buf_verify_crc(mp, bp))
257 		xfs_buf_ioerror(bp, -EFSBADCRC);
258 	else if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN))
259 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
260 
261 	if (bp->b_error)
262 		xfs_verifier_error(bp);
263 }
264 
265 /*
266  * readahead errors are silent and simply leave the buffer as !done so a real
267  * read will then be run with the xfs_dquot_buf_ops verifier. See
268  * xfs_inode_buf_verify() for why we use EIO and ~XBF_DONE here rather than
269  * reporting the failure.
270  */
271 static void
xfs_dquot_buf_readahead_verify(struct xfs_buf * bp)272 xfs_dquot_buf_readahead_verify(
273 	struct xfs_buf	*bp)
274 {
275 	struct xfs_mount	*mp = bp->b_target->bt_mount;
276 
277 	if (!xfs_dquot_buf_verify_crc(mp, bp) ||
278 	    !xfs_dquot_buf_verify(mp, bp, 0)) {
279 		xfs_buf_ioerror(bp, -EIO);
280 		bp->b_flags &= ~XBF_DONE;
281 	}
282 }
283 
284 /*
285  * we don't calculate the CRC here as that is done when the dquot is flushed to
286  * the buffer after the update is done. This ensures that the dquot in the
287  * buffer always has an up-to-date CRC value.
288  */
289 static void
xfs_dquot_buf_write_verify(struct xfs_buf * bp)290 xfs_dquot_buf_write_verify(
291 	struct xfs_buf	*bp)
292 {
293 	struct xfs_mount	*mp = bp->b_target->bt_mount;
294 
295 	if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN)) {
296 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
297 		xfs_verifier_error(bp);
298 		return;
299 	}
300 }
301 
302 const struct xfs_buf_ops xfs_dquot_buf_ops = {
303 	.name = "xfs_dquot",
304 	.verify_read = xfs_dquot_buf_read_verify,
305 	.verify_write = xfs_dquot_buf_write_verify,
306 };
307 
308 const struct xfs_buf_ops xfs_dquot_buf_ra_ops = {
309 	.name = "xfs_dquot_ra",
310 	.verify_read = xfs_dquot_buf_readahead_verify,
311 	.verify_write = xfs_dquot_buf_write_verify,
312 };
313