aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-10-08 23:50:52 -0400
committerBen Myers <bpm@sgi.com>2012-11-08 12:08:57 -0500
commiteaef854335ce09956e930fe4a193327417edc6c9 (patch)
treeb3ad6c5011d31cb72e770259a2a22889b962b2fc /fs
parent1f3c785c3adb7d2b109ec7c8f10081d1294b03d3 (diff)
xfs: growfs: don't read garbage for new secondary superblocks
When updating new secondary superblocks in a growfs operation, the superblock buffer is read from the newly grown region of the underlying device. This is not guaranteed to be zero, so violates the underlying assumption that the unused parts of superblocks are zero filled. Get a new buffer for these secondary superblocks to ensure that the unused regions are zero filled correctly. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_fsops.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index c25b094efbf7..4beaede43277 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -399,9 +399,26 @@ xfs_growfs_data_private(
399 399
400 /* update secondary superblocks. */ 400 /* update secondary superblocks. */
401 for (agno = 1; agno < nagcount; agno++) { 401 for (agno = 1; agno < nagcount; agno++) {
402 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, 402 error = 0;
403 /*
404 * new secondary superblocks need to be zeroed, not read from
405 * disk as the contents of the new area we are growing into is
406 * completely unknown.
407 */
408 if (agno < oagcount) {
409 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
403 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), 410 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
404 XFS_FSS_TO_BB(mp, 1), 0, &bp); 411 XFS_FSS_TO_BB(mp, 1), 0, &bp);
412 } else {
413 bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
414 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
415 XFS_FSS_TO_BB(mp, 1), 0);
416 if (bp)
417 xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
418 else
419 error = ENOMEM;
420 }
421
405 if (error) { 422 if (error) {
406 xfs_warn(mp, 423 xfs_warn(mp,
407 "error %d reading secondary superblock for ag %d", 424 "error %d reading secondary superblock for ag %d",
@@ -423,7 +440,7 @@ xfs_growfs_data_private(
423 break; /* no point in continuing */ 440 break; /* no point in continuing */
424 } 441 }
425 } 442 }
426 return 0; 443 return error;
427 444
428 error0: 445 error0:
429 xfs_trans_cancel(tp, XFS_TRANS_ABORT); 446 xfs_trans_cancel(tp, XFS_TRANS_ABORT);