aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_fsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_fsops.c')
-rw-r--r--fs/xfs/xfs_fsops.c141
1 files changed, 94 insertions, 47 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 4beaede43277..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
117static struct xfs_buf *
118xfs_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
115static int 139static int
116xfs_growfs_data_private( 140xfs_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)
@@ -408,14 +452,16 @@ xfs_growfs_data_private(
408 if (agno < oagcount) { 452 if (agno < oagcount) {
409 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, 453 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
410 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), 454 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
411 XFS_FSS_TO_BB(mp, 1), 0, &bp); 455 XFS_FSS_TO_BB(mp, 1), 0, &bp,
456 &xfs_sb_buf_ops);
412 } else { 457 } else {
413 bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, 458 bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
414 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), 459 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
415 XFS_FSS_TO_BB(mp, 1), 0); 460 XFS_FSS_TO_BB(mp, 1), 0);
416 if (bp) 461 if (bp) {
462 bp->b_ops = &xfs_sb_buf_ops;
417 xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); 463 xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
418 else 464 } else
419 error = ENOMEM; 465 error = ENOMEM;
420 } 466 }
421 467
@@ -426,6 +472,7 @@ xfs_growfs_data_private(
426 break; 472 break;
427 } 473 }
428 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
429 /* 476 /*
430 * If we get an error writing out the alternate superblocks, 477 * If we get an error writing out the alternate superblocks,
431 * just issue a warning and continue. The real work is 478 * just issue a warning and continue. The real work is