aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dquot.c')
-rw-r--r--fs/xfs/xfs_dquot.c117
1 files changed, 3 insertions, 114 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 8b1d2c0a9054..f85a893c2398 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -293,118 +293,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
293 dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5; 293 dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
294} 294}
295 295
296STATIC bool
297xfs_dquot_buf_verify_crc(
298 struct xfs_mount *mp,
299 struct xfs_buf *bp)
300{
301 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
302 int ndquots;
303 int i;
304
305 if (!xfs_sb_version_hascrc(&mp->m_sb))
306 return true;
307
308 /*
309 * if we are in log recovery, the quota subsystem has not been
310 * initialised so we have no quotainfo structure. In that case, we need
311 * to manually calculate the number of dquots in the buffer.
312 */
313 if (mp->m_quotainfo)
314 ndquots = mp->m_quotainfo->qi_dqperchunk;
315 else
316 ndquots = xfs_qm_calc_dquots_per_chunk(mp,
317 XFS_BB_TO_FSB(mp, bp->b_length));
318
319 for (i = 0; i < ndquots; i++, d++) {
320 if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
321 XFS_DQUOT_CRC_OFF))
322 return false;
323 if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
324 return false;
325 }
326 return true;
327}
328
329STATIC bool
330xfs_dquot_buf_verify(
331 struct xfs_mount *mp,
332 struct xfs_buf *bp)
333{
334 struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
335 xfs_dqid_t id = 0;
336 int ndquots;
337 int i;
338
339 /*
340 * if we are in log recovery, the quota subsystem has not been
341 * initialised so we have no quotainfo structure. In that case, we need
342 * to manually calculate the number of dquots in the buffer.
343 */
344 if (mp->m_quotainfo)
345 ndquots = mp->m_quotainfo->qi_dqperchunk;
346 else
347 ndquots = xfs_qm_calc_dquots_per_chunk(mp, bp->b_length);
348
349 /*
350 * On the first read of the buffer, verify that each dquot is valid.
351 * We don't know what the id of the dquot is supposed to be, just that
352 * they should be increasing monotonically within the buffer. If the
353 * first id is corrupt, then it will fail on the second dquot in the
354 * buffer so corruptions could point to the wrong dquot in this case.
355 */
356 for (i = 0; i < ndquots; i++) {
357 struct xfs_disk_dquot *ddq;
358 int error;
359
360 ddq = &d[i].dd_diskdq;
361
362 if (i == 0)
363 id = be32_to_cpu(ddq->d_id);
364
365 error = xfs_qm_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN,
366 "xfs_dquot_buf_verify");
367 if (error)
368 return false;
369 }
370 return true;
371}
372
373static void
374xfs_dquot_buf_read_verify(
375 struct xfs_buf *bp)
376{
377 struct xfs_mount *mp = bp->b_target->bt_mount;
378
379 if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
380 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
381 xfs_buf_ioerror(bp, EFSCORRUPTED);
382 }
383}
384
385/*
386 * we don't calculate the CRC here as that is done when the dquot is flushed to
387 * the buffer after the update is done. This ensures that the dquot in the
388 * buffer always has an up-to-date CRC value.
389 */
390void
391xfs_dquot_buf_write_verify(
392 struct xfs_buf *bp)
393{
394 struct xfs_mount *mp = bp->b_target->bt_mount;
395
396 if (!xfs_dquot_buf_verify(mp, bp)) {
397 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
398 xfs_buf_ioerror(bp, EFSCORRUPTED);
399 return;
400 }
401}
402
403const struct xfs_buf_ops xfs_dquot_buf_ops = {
404 .verify_read = xfs_dquot_buf_read_verify,
405 .verify_write = xfs_dquot_buf_write_verify,
406};
407
408/* 296/*
409 * Allocate a block and fill it with dquots. 297 * Allocate a block and fill it with dquots.
410 * This is called when the bmapi finds a hole. 298 * This is called when the bmapi finds a hole.
@@ -515,6 +403,7 @@ xfs_qm_dqalloc(
515 403
516 return (error); 404 return (error);
517} 405}
406
518STATIC int 407STATIC int
519xfs_qm_dqrepair( 408xfs_qm_dqrepair(
520 struct xfs_mount *mp, 409 struct xfs_mount *mp,
@@ -548,7 +437,7 @@ xfs_qm_dqrepair(
548 /* Do the actual repair of dquots in this buffer */ 437 /* Do the actual repair of dquots in this buffer */
549 for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++) { 438 for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++) {
550 ddq = &d[i].dd_diskdq; 439 ddq = &d[i].dd_diskdq;
551 error = xfs_qm_dqcheck(mp, ddq, firstid + i, 440 error = xfs_dqcheck(mp, ddq, firstid + i,
552 dqp->dq_flags & XFS_DQ_ALLTYPES, 441 dqp->dq_flags & XFS_DQ_ALLTYPES,
553 XFS_QMOPT_DQREPAIR, "xfs_qm_dqrepair"); 442 XFS_QMOPT_DQREPAIR, "xfs_qm_dqrepair");
554 if (error) { 443 if (error) {
@@ -1134,7 +1023,7 @@ xfs_qm_dqflush(
1134 /* 1023 /*
1135 * A simple sanity check in case we got a corrupted dquot.. 1024 * A simple sanity check in case we got a corrupted dquot..
1136 */ 1025 */
1137 error = xfs_qm_dqcheck(mp, &dqp->q_core, be32_to_cpu(ddqp->d_id), 0, 1026 error = xfs_dqcheck(mp, &dqp->q_core, be32_to_cpu(ddqp->d_id), 0,
1138 XFS_QMOPT_DOWARN, "dqflush (incore copy)"); 1027 XFS_QMOPT_DOWARN, "dqflush (incore copy)");
1139 if (error) { 1028 if (error) {
1140 xfs_buf_relse(bp); 1029 xfs_buf_relse(bp);