diff options
| author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
| commit | befddb21c845f8fb49e637997891ef97c6a869dc (patch) | |
| tree | 0e7629123184f2dd50291ad6d477b894175f0f26 /fs/xfs/xfs_fsops.c | |
| parent | e716efde75267eab919cdb2bef5b2cb77f305326 (diff) | |
| parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) | |
Merge tag 'v3.8-rc4' into irq/core
Merge Linux 3.8-rc4 before pulling in new commits - we were on an old v3.7 base.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_fsops.c')
| -rw-r--r-- | fs/xfs/xfs_fsops.c | 158 |
1 files changed, 111 insertions, 47 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index c25b094efbf7..94eaeedc5498 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
| @@ -97,7 +97,9 @@ xfs_fs_geometry( | |||
| 97 | (xfs_sb_version_haslazysbcount(&mp->m_sb) ? | 97 | (xfs_sb_version_haslazysbcount(&mp->m_sb) ? |
| 98 | XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) | | 98 | XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) | |
| 99 | (xfs_sb_version_hasattr2(&mp->m_sb) ? | 99 | (xfs_sb_version_hasattr2(&mp->m_sb) ? |
| 100 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); | 100 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) | |
| 101 | (xfs_sb_version_hasprojid32bit(&mp->m_sb) ? | ||
| 102 | XFS_FSOP_GEOM_FLAGS_PROJID32 : 0); | ||
| 101 | geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? | 103 | geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? |
| 102 | mp->m_sb.sb_logsectsize : BBSIZE; | 104 | mp->m_sb.sb_logsectsize : BBSIZE; |
| 103 | geo->rtsectsize = mp->m_sb.sb_blocksize; | 105 | geo->rtsectsize = mp->m_sb.sb_blocksize; |
| @@ -112,18 +114,40 @@ xfs_fs_geometry( | |||
| 112 | return 0; | 114 | return 0; |
| 113 | } | 115 | } |
| 114 | 116 | ||
| 117 | static struct xfs_buf * | ||
| 118 | xfs_growfs_get_hdr_buf( | ||
| 119 | struct xfs_mount *mp, | ||
| 120 | xfs_daddr_t blkno, | ||
| 121 | size_t numblks, | ||
| 122 | int flags, | ||
| 123 | const struct xfs_buf_ops *ops) | ||
| 124 | { | ||
| 125 | struct xfs_buf *bp; | ||
| 126 | |||
| 127 | bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); | ||
| 128 | if (!bp) | ||
| 129 | return NULL; | ||
| 130 | |||
| 131 | xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); | ||
| 132 | bp->b_bn = blkno; | ||
| 133 | bp->b_maps[0].bm_bn = blkno; | ||
| 134 | bp->b_ops = ops; | ||
| 135 | |||
| 136 | return bp; | ||
| 137 | } | ||
| 138 | |||
| 115 | static int | 139 | static int |
| 116 | xfs_growfs_data_private( | 140 | xfs_growfs_data_private( |
| 117 | xfs_mount_t *mp, /* mount point for filesystem */ | 141 | xfs_mount_t *mp, /* mount point for filesystem */ |
| 118 | xfs_growfs_data_t *in) /* growfs data input struct */ | 142 | xfs_growfs_data_t *in) /* growfs data input struct */ |
| 119 | { | 143 | { |
| 120 | xfs_agf_t *agf; | 144 | xfs_agf_t *agf; |
| 145 | struct xfs_agfl *agfl; | ||
| 121 | xfs_agi_t *agi; | 146 | xfs_agi_t *agi; |
| 122 | xfs_agnumber_t agno; | 147 | xfs_agnumber_t agno; |
| 123 | xfs_extlen_t agsize; | 148 | xfs_extlen_t agsize; |
| 124 | xfs_extlen_t tmpsize; | 149 | xfs_extlen_t tmpsize; |
| 125 | xfs_alloc_rec_t *arec; | 150 | xfs_alloc_rec_t *arec; |
| 126 | struct xfs_btree_block *block; | ||
| 127 | xfs_buf_t *bp; | 151 | xfs_buf_t *bp; |
| 128 | int bucket; | 152 | int bucket; |
| 129 | int dpct; | 153 | int dpct; |
| @@ -146,9 +170,14 @@ xfs_growfs_data_private( | |||
| 146 | dpct = pct - mp->m_sb.sb_imax_pct; | 170 | dpct = pct - mp->m_sb.sb_imax_pct; |
| 147 | bp = xfs_buf_read_uncached(mp->m_ddev_targp, | 171 | bp = xfs_buf_read_uncached(mp->m_ddev_targp, |
| 148 | XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), | 172 | XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), |
| 149 | XFS_FSS_TO_BB(mp, 1), 0); | 173 | XFS_FSS_TO_BB(mp, 1), 0, NULL); |
| 150 | if (!bp) | 174 | if (!bp) |
| 151 | return EIO; | 175 | return EIO; |
| 176 | if (bp->b_error) { | ||
| 177 | int error = bp->b_error; | ||
| 178 | xfs_buf_relse(bp); | ||
| 179 | return error; | ||
| 180 | } | ||
| 152 | xfs_buf_relse(bp); | 181 | xfs_buf_relse(bp); |
| 153 | 182 | ||
| 154 | new = nb; /* use new as a temporary here */ | 183 | new = nb; /* use new as a temporary here */ |
| @@ -186,17 +215,18 @@ xfs_growfs_data_private( | |||
| 186 | nfree = 0; | 215 | nfree = 0; |
| 187 | for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) { | 216 | for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) { |
| 188 | /* | 217 | /* |
| 189 | * AG freelist header block | 218 | * AG freespace header block |
| 190 | */ | 219 | */ |
| 191 | bp = xfs_buf_get(mp->m_ddev_targp, | 220 | bp = xfs_growfs_get_hdr_buf(mp, |
| 192 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), | 221 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), |
| 193 | XFS_FSS_TO_BB(mp, 1), 0); | 222 | XFS_FSS_TO_BB(mp, 1), 0, |
| 223 | &xfs_agf_buf_ops); | ||
| 194 | if (!bp) { | 224 | if (!bp) { |
| 195 | error = ENOMEM; | 225 | error = ENOMEM; |
| 196 | goto error0; | 226 | goto error0; |
| 197 | } | 227 | } |
| 228 | |||
| 198 | agf = XFS_BUF_TO_AGF(bp); | 229 | agf = XFS_BUF_TO_AGF(bp); |
| 199 | memset(agf, 0, mp->m_sb.sb_sectsize); | ||
| 200 | agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); | 230 | agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); |
| 201 | agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); | 231 | agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); |
| 202 | agf->agf_seqno = cpu_to_be32(agno); | 232 | agf->agf_seqno = cpu_to_be32(agno); |
| @@ -223,17 +253,39 @@ xfs_growfs_data_private( | |||
| 223 | goto error0; | 253 | goto error0; |
| 224 | 254 | ||
| 225 | /* | 255 | /* |
| 256 | * AG freelist header block | ||
| 257 | */ | ||
| 258 | bp = xfs_growfs_get_hdr_buf(mp, | ||
| 259 | XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), | ||
| 260 | XFS_FSS_TO_BB(mp, 1), 0, | ||
| 261 | &xfs_agfl_buf_ops); | ||
| 262 | if (!bp) { | ||
| 263 | error = ENOMEM; | ||
| 264 | goto error0; | ||
| 265 | } | ||
| 266 | |||
| 267 | agfl = XFS_BUF_TO_AGFL(bp); | ||
| 268 | for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) | ||
| 269 | agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); | ||
| 270 | |||
| 271 | error = xfs_bwrite(bp); | ||
| 272 | xfs_buf_relse(bp); | ||
| 273 | if (error) | ||
| 274 | goto error0; | ||
| 275 | |||
| 276 | /* | ||
| 226 | * AG inode header block | 277 | * AG inode header block |
| 227 | */ | 278 | */ |
| 228 | bp = xfs_buf_get(mp->m_ddev_targp, | 279 | bp = xfs_growfs_get_hdr_buf(mp, |
| 229 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | 280 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), |
| 230 | XFS_FSS_TO_BB(mp, 1), 0); | 281 | XFS_FSS_TO_BB(mp, 1), 0, |
| 282 | &xfs_agi_buf_ops); | ||
| 231 | if (!bp) { | 283 | if (!bp) { |
| 232 | error = ENOMEM; | 284 | error = ENOMEM; |
| 233 | goto error0; | 285 | goto error0; |
| 234 | } | 286 | } |
| 287 | |||
| 235 | agi = XFS_BUF_TO_AGI(bp); | 288 | agi = XFS_BUF_TO_AGI(bp); |
| 236 | memset(agi, 0, mp->m_sb.sb_sectsize); | ||
| 237 | agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); | 289 | agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); |
| 238 | agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); | 290 | agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); |
| 239 | agi->agi_seqno = cpu_to_be32(agno); | 291 | agi->agi_seqno = cpu_to_be32(agno); |
| @@ -254,24 +306,22 @@ xfs_growfs_data_private( | |||
| 254 | /* | 306 | /* |
| 255 | * BNO btree root block | 307 | * BNO btree root block |
| 256 | */ | 308 | */ |
| 257 | bp = xfs_buf_get(mp->m_ddev_targp, | 309 | bp = xfs_growfs_get_hdr_buf(mp, |
| 258 | XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), | 310 | XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), |
| 259 | BTOBB(mp->m_sb.sb_blocksize), 0); | 311 | BTOBB(mp->m_sb.sb_blocksize), 0, |
| 312 | &xfs_allocbt_buf_ops); | ||
| 313 | |||
| 260 | if (!bp) { | 314 | if (!bp) { |
| 261 | error = ENOMEM; | 315 | error = ENOMEM; |
| 262 | goto error0; | 316 | goto error0; |
| 263 | } | 317 | } |
| 264 | block = XFS_BUF_TO_BLOCK(bp); | 318 | |
| 265 | memset(block, 0, mp->m_sb.sb_blocksize); | 319 | xfs_btree_init_block(mp, bp, XFS_ABTB_MAGIC, 0, 1, 0); |
| 266 | block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); | 320 | arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); |
| 267 | block->bb_level = 0; | ||
| 268 | block->bb_numrecs = cpu_to_be16(1); | ||
| 269 | block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); | ||
| 270 | block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); | ||
| 271 | arec = XFS_ALLOC_REC_ADDR(mp, block, 1); | ||
| 272 | arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); | 321 | arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); |
| 273 | arec->ar_blockcount = cpu_to_be32( | 322 | arec->ar_blockcount = cpu_to_be32( |
| 274 | agsize - be32_to_cpu(arec->ar_startblock)); | 323 | agsize - be32_to_cpu(arec->ar_startblock)); |
| 324 | |||
| 275 | error = xfs_bwrite(bp); | 325 | error = xfs_bwrite(bp); |
| 276 | xfs_buf_relse(bp); | 326 | xfs_buf_relse(bp); |
| 277 | if (error) | 327 | if (error) |
| @@ -280,25 +330,22 @@ xfs_growfs_data_private( | |||
| 280 | /* | 330 | /* |
| 281 | * CNT btree root block | 331 | * CNT btree root block |
| 282 | */ | 332 | */ |
| 283 | bp = xfs_buf_get(mp->m_ddev_targp, | 333 | bp = xfs_growfs_get_hdr_buf(mp, |
| 284 | XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), | 334 | XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), |
| 285 | BTOBB(mp->m_sb.sb_blocksize), 0); | 335 | BTOBB(mp->m_sb.sb_blocksize), 0, |
| 336 | &xfs_allocbt_buf_ops); | ||
| 286 | if (!bp) { | 337 | if (!bp) { |
| 287 | error = ENOMEM; | 338 | error = ENOMEM; |
| 288 | goto error0; | 339 | goto error0; |
| 289 | } | 340 | } |
| 290 | block = XFS_BUF_TO_BLOCK(bp); | 341 | |
| 291 | memset(block, 0, mp->m_sb.sb_blocksize); | 342 | xfs_btree_init_block(mp, bp, XFS_ABTC_MAGIC, 0, 1, 0); |
| 292 | block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); | 343 | arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); |
| 293 | block->bb_level = 0; | ||
| 294 | block->bb_numrecs = cpu_to_be16(1); | ||
| 295 | block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); | ||
| 296 | block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); | ||
| 297 | arec = XFS_ALLOC_REC_ADDR(mp, block, 1); | ||
| 298 | arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); | 344 | arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); |
| 299 | arec->ar_blockcount = cpu_to_be32( | 345 | arec->ar_blockcount = cpu_to_be32( |
| 300 | agsize - be32_to_cpu(arec->ar_startblock)); | 346 | agsize - be32_to_cpu(arec->ar_startblock)); |
| 301 | nfree += be32_to_cpu(arec->ar_blockcount); | 347 | nfree += be32_to_cpu(arec->ar_blockcount); |
| 348 | |||
| 302 | error = xfs_bwrite(bp); | 349 | error = xfs_bwrite(bp); |
| 303 | xfs_buf_relse(bp); | 350 | xfs_buf_relse(bp); |
| 304 | if (error) | 351 | if (error) |
| @@ -307,20 +354,17 @@ xfs_growfs_data_private( | |||
| 307 | /* | 354 | /* |
| 308 | * INO btree root block | 355 | * INO btree root block |
| 309 | */ | 356 | */ |
| 310 | bp = xfs_buf_get(mp->m_ddev_targp, | 357 | bp = xfs_growfs_get_hdr_buf(mp, |
| 311 | XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), | 358 | XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), |
| 312 | BTOBB(mp->m_sb.sb_blocksize), 0); | 359 | BTOBB(mp->m_sb.sb_blocksize), 0, |
| 360 | &xfs_inobt_buf_ops); | ||
| 313 | if (!bp) { | 361 | if (!bp) { |
| 314 | error = ENOMEM; | 362 | error = ENOMEM; |
| 315 | goto error0; | 363 | goto error0; |
| 316 | } | 364 | } |
| 317 | block = XFS_BUF_TO_BLOCK(bp); | 365 | |
| 318 | memset(block, 0, mp->m_sb.sb_blocksize); | 366 | xfs_btree_init_block(mp, bp, XFS_IBT_MAGIC, 0, 0, 0); |
| 319 | block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); | 367 | |
| 320 | block->bb_level = 0; | ||
| 321 | block->bb_numrecs = 0; | ||
| 322 | block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); | ||
| 323 | block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); | ||
| 324 | error = xfs_bwrite(bp); | 368 | error = xfs_bwrite(bp); |
| 325 | xfs_buf_relse(bp); | 369 | xfs_buf_relse(bp); |
| 326 | if (error) | 370 | if (error) |
| @@ -399,9 +443,28 @@ xfs_growfs_data_private( | |||
| 399 | 443 | ||
| 400 | /* update secondary superblocks. */ | 444 | /* update secondary superblocks. */ |
| 401 | for (agno = 1; agno < nagcount; agno++) { | 445 | for (agno = 1; agno < nagcount; agno++) { |
| 402 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, | 446 | error = 0; |
| 447 | /* | ||
| 448 | * new secondary superblocks need to be zeroed, not read from | ||
| 449 | * disk as the contents of the new area we are growing into is | ||
| 450 | * completely unknown. | ||
| 451 | */ | ||
| 452 | if (agno < oagcount) { | ||
| 453 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, | ||
| 454 | XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), | ||
| 455 | XFS_FSS_TO_BB(mp, 1), 0, &bp, | ||
| 456 | &xfs_sb_buf_ops); | ||
| 457 | } else { | ||
| 458 | bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, | ||
| 403 | XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), | 459 | XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), |
| 404 | XFS_FSS_TO_BB(mp, 1), 0, &bp); | 460 | XFS_FSS_TO_BB(mp, 1), 0); |
| 461 | if (bp) { | ||
| 462 | bp->b_ops = &xfs_sb_buf_ops; | ||
| 463 | xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); | ||
| 464 | } else | ||
| 465 | error = ENOMEM; | ||
| 466 | } | ||
| 467 | |||
| 405 | if (error) { | 468 | if (error) { |
| 406 | xfs_warn(mp, | 469 | xfs_warn(mp, |
| 407 | "error %d reading secondary superblock for ag %d", | 470 | "error %d reading secondary superblock for ag %d", |
| @@ -409,6 +472,7 @@ xfs_growfs_data_private( | |||
| 409 | break; | 472 | break; |
| 410 | } | 473 | } |
| 411 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); | 474 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); |
| 475 | |||
| 412 | /* | 476 | /* |
| 413 | * If we get an error writing out the alternate superblocks, | 477 | * If we get an error writing out the alternate superblocks, |
| 414 | * just issue a warning and continue. The real work is | 478 | * just issue a warning and continue. The real work is |
| @@ -423,7 +487,7 @@ xfs_growfs_data_private( | |||
| 423 | break; /* no point in continuing */ | 487 | break; /* no point in continuing */ |
| 424 | } | 488 | } |
| 425 | } | 489 | } |
| 426 | return 0; | 490 | return error; |
| 427 | 491 | ||
| 428 | error0: | 492 | error0: |
| 429 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | 493 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); |
