diff options
Diffstat (limited to 'fs/xfs/xfs_dquot.c')
-rw-r--r-- | fs/xfs/xfs_dquot.c | 117 |
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 | ||
296 | STATIC bool | ||
297 | xfs_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 | |||
329 | STATIC bool | ||
330 | xfs_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 | |||
373 | static void | ||
374 | xfs_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 | */ | ||
390 | void | ||
391 | xfs_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 | |||
403 | const 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 | |||
518 | STATIC int | 407 | STATIC int |
519 | xfs_qm_dqrepair( | 408 | xfs_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); |