diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 181 |
1 files changed, 143 insertions, 38 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index eb403b40e120..6afaaeb2950a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -201,6 +201,38 @@ xfs_uuid_unmount( | |||
201 | 201 | ||
202 | 202 | ||
203 | /* | 203 | /* |
204 | * Reference counting access wrappers to the perag structures. | ||
205 | */ | ||
206 | struct xfs_perag * | ||
207 | xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno) | ||
208 | { | ||
209 | struct xfs_perag *pag; | ||
210 | int ref = 0; | ||
211 | |||
212 | spin_lock(&mp->m_perag_lock); | ||
213 | pag = radix_tree_lookup(&mp->m_perag_tree, agno); | ||
214 | if (pag) { | ||
215 | ASSERT(atomic_read(&pag->pag_ref) >= 0); | ||
216 | /* catch leaks in the positive direction during testing */ | ||
217 | ASSERT(atomic_read(&pag->pag_ref) < 1000); | ||
218 | ref = atomic_inc_return(&pag->pag_ref); | ||
219 | } | ||
220 | spin_unlock(&mp->m_perag_lock); | ||
221 | trace_xfs_perag_get(mp, agno, ref, _RET_IP_); | ||
222 | return pag; | ||
223 | } | ||
224 | |||
225 | void | ||
226 | xfs_perag_put(struct xfs_perag *pag) | ||
227 | { | ||
228 | int ref; | ||
229 | |||
230 | ASSERT(atomic_read(&pag->pag_ref) > 0); | ||
231 | ref = atomic_dec_return(&pag->pag_ref); | ||
232 | trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); | ||
233 | } | ||
234 | |||
235 | /* | ||
204 | * Free up the resources associated with a mount structure. Assume that | 236 | * Free up the resources associated with a mount structure. Assume that |
205 | * the structure was initially zeroed, so we can tell which fields got | 237 | * the structure was initially zeroed, so we can tell which fields got |
206 | * initialized. | 238 | * initialized. |
@@ -209,13 +241,16 @@ STATIC void | |||
209 | xfs_free_perag( | 241 | xfs_free_perag( |
210 | xfs_mount_t *mp) | 242 | xfs_mount_t *mp) |
211 | { | 243 | { |
212 | if (mp->m_perag) { | 244 | xfs_agnumber_t agno; |
213 | int agno; | 245 | struct xfs_perag *pag; |
214 | 246 | ||
215 | for (agno = 0; agno < mp->m_maxagi; agno++) | 247 | for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { |
216 | if (mp->m_perag[agno].pagb_list) | 248 | spin_lock(&mp->m_perag_lock); |
217 | kmem_free(mp->m_perag[agno].pagb_list); | 249 | pag = radix_tree_delete(&mp->m_perag_tree, agno); |
218 | kmem_free(mp->m_perag); | 250 | ASSERT(pag); |
251 | ASSERT(atomic_read(&pag->pag_ref) == 0); | ||
252 | spin_unlock(&mp->m_perag_lock); | ||
253 | kmem_free(pag); | ||
219 | } | 254 | } |
220 | } | 255 | } |
221 | 256 | ||
@@ -389,22 +424,57 @@ xfs_initialize_perag_icache( | |||
389 | } | 424 | } |
390 | } | 425 | } |
391 | 426 | ||
392 | xfs_agnumber_t | 427 | int |
393 | xfs_initialize_perag( | 428 | xfs_initialize_perag( |
394 | xfs_mount_t *mp, | 429 | xfs_mount_t *mp, |
395 | xfs_agnumber_t agcount) | 430 | xfs_agnumber_t agcount, |
431 | xfs_agnumber_t *maxagi) | ||
396 | { | 432 | { |
397 | xfs_agnumber_t index, max_metadata; | 433 | xfs_agnumber_t index, max_metadata; |
434 | xfs_agnumber_t first_initialised = 0; | ||
398 | xfs_perag_t *pag; | 435 | xfs_perag_t *pag; |
399 | xfs_agino_t agino; | 436 | xfs_agino_t agino; |
400 | xfs_ino_t ino; | 437 | xfs_ino_t ino; |
401 | xfs_sb_t *sbp = &mp->m_sb; | 438 | xfs_sb_t *sbp = &mp->m_sb; |
402 | xfs_ino_t max_inum = XFS_MAXINUMBER_32; | 439 | xfs_ino_t max_inum = XFS_MAXINUMBER_32; |
440 | int error = -ENOMEM; | ||
403 | 441 | ||
404 | /* Check to see if the filesystem can overflow 32 bit inodes */ | 442 | /* Check to see if the filesystem can overflow 32 bit inodes */ |
405 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); | 443 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); |
406 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); | 444 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); |
407 | 445 | ||
446 | /* | ||
447 | * Walk the current per-ag tree so we don't try to initialise AGs | ||
448 | * that already exist (growfs case). Allocate and insert all the | ||
449 | * AGs we don't find ready for initialisation. | ||
450 | */ | ||
451 | for (index = 0; index < agcount; index++) { | ||
452 | pag = xfs_perag_get(mp, index); | ||
453 | if (pag) { | ||
454 | xfs_perag_put(pag); | ||
455 | continue; | ||
456 | } | ||
457 | if (!first_initialised) | ||
458 | first_initialised = index; | ||
459 | pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); | ||
460 | if (!pag) | ||
461 | goto out_unwind; | ||
462 | if (radix_tree_preload(GFP_NOFS)) | ||
463 | goto out_unwind; | ||
464 | spin_lock(&mp->m_perag_lock); | ||
465 | if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { | ||
466 | BUG(); | ||
467 | spin_unlock(&mp->m_perag_lock); | ||
468 | radix_tree_preload_end(); | ||
469 | error = -EEXIST; | ||
470 | goto out_unwind; | ||
471 | } | ||
472 | pag->pag_agno = index; | ||
473 | pag->pag_mount = mp; | ||
474 | spin_unlock(&mp->m_perag_lock); | ||
475 | radix_tree_preload_end(); | ||
476 | } | ||
477 | |||
408 | /* Clear the mount flag if no inode can overflow 32 bits | 478 | /* Clear the mount flag if no inode can overflow 32 bits |
409 | * on this filesystem, or if specifically requested.. | 479 | * on this filesystem, or if specifically requested.. |
410 | */ | 480 | */ |
@@ -438,21 +508,33 @@ xfs_initialize_perag( | |||
438 | } | 508 | } |
439 | 509 | ||
440 | /* This ag is preferred for inodes */ | 510 | /* This ag is preferred for inodes */ |
441 | pag = &mp->m_perag[index]; | 511 | pag = xfs_perag_get(mp, index); |
442 | pag->pagi_inodeok = 1; | 512 | pag->pagi_inodeok = 1; |
443 | if (index < max_metadata) | 513 | if (index < max_metadata) |
444 | pag->pagf_metadata = 1; | 514 | pag->pagf_metadata = 1; |
445 | xfs_initialize_perag_icache(pag); | 515 | xfs_initialize_perag_icache(pag); |
516 | xfs_perag_put(pag); | ||
446 | } | 517 | } |
447 | } else { | 518 | } else { |
448 | /* Setup default behavior for smaller filesystems */ | 519 | /* Setup default behavior for smaller filesystems */ |
449 | for (index = 0; index < agcount; index++) { | 520 | for (index = 0; index < agcount; index++) { |
450 | pag = &mp->m_perag[index]; | 521 | pag = xfs_perag_get(mp, index); |
451 | pag->pagi_inodeok = 1; | 522 | pag->pagi_inodeok = 1; |
452 | xfs_initialize_perag_icache(pag); | 523 | xfs_initialize_perag_icache(pag); |
524 | xfs_perag_put(pag); | ||
453 | } | 525 | } |
454 | } | 526 | } |
455 | return index; | 527 | if (maxagi) |
528 | *maxagi = index; | ||
529 | return 0; | ||
530 | |||
531 | out_unwind: | ||
532 | kmem_free(pag); | ||
533 | for (; index > first_initialised; index--) { | ||
534 | pag = radix_tree_delete(&mp->m_perag_tree, index); | ||
535 | kmem_free(pag); | ||
536 | } | ||
537 | return error; | ||
456 | } | 538 | } |
457 | 539 | ||
458 | void | 540 | void |
@@ -583,7 +665,7 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
583 | * access to the superblock. | 665 | * access to the superblock. |
584 | */ | 666 | */ |
585 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); | 667 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); |
586 | extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED; | 668 | extra_flags = XBF_LOCK | XBF_FS_MANAGED | XBF_MAPPED; |
587 | 669 | ||
588 | bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR, BTOBB(sector_size), | 670 | bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR, BTOBB(sector_size), |
589 | extra_flags); | 671 | extra_flags); |
@@ -731,12 +813,13 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
731 | error = xfs_ialloc_pagi_init(mp, NULL, index); | 813 | error = xfs_ialloc_pagi_init(mp, NULL, index); |
732 | if (error) | 814 | if (error) |
733 | return error; | 815 | return error; |
734 | pag = &mp->m_perag[index]; | 816 | pag = xfs_perag_get(mp, index); |
735 | ifree += pag->pagi_freecount; | 817 | ifree += pag->pagi_freecount; |
736 | ialloc += pag->pagi_count; | 818 | ialloc += pag->pagi_count; |
737 | bfree += pag->pagf_freeblks; | 819 | bfree += pag->pagf_freeblks; |
738 | bfreelst += pag->pagf_flcount; | 820 | bfreelst += pag->pagf_flcount; |
739 | btree += pag->pagf_btreeblks; | 821 | btree += pag->pagf_btreeblks; |
822 | xfs_perag_put(pag); | ||
740 | } | 823 | } |
741 | /* | 824 | /* |
742 | * Overwrite incore superblock counters with just-read data | 825 | * Overwrite incore superblock counters with just-read data |
@@ -1008,6 +1091,22 @@ xfs_mount_reset_sbqflags( | |||
1008 | return xfs_trans_commit(tp, 0); | 1091 | return xfs_trans_commit(tp, 0); |
1009 | } | 1092 | } |
1010 | 1093 | ||
1094 | __uint64_t | ||
1095 | xfs_default_resblks(xfs_mount_t *mp) | ||
1096 | { | ||
1097 | __uint64_t resblks; | ||
1098 | |||
1099 | /* | ||
1100 | * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | ||
1101 | * This may drive us straight to ENOSPC on mount, but that implies | ||
1102 | * we were already there on the last unmount. Warn if this occurs. | ||
1103 | */ | ||
1104 | resblks = mp->m_sb.sb_dblocks; | ||
1105 | do_div(resblks, 20); | ||
1106 | resblks = min_t(__uint64_t, resblks, 1024); | ||
1107 | return resblks; | ||
1108 | } | ||
1109 | |||
1011 | /* | 1110 | /* |
1012 | * This function does the following on an initial mount of a file system: | 1111 | * This function does the following on an initial mount of a file system: |
1013 | * - reads the superblock from disk and init the mount struct | 1112 | * - reads the superblock from disk and init the mount struct |
@@ -1152,13 +1251,13 @@ xfs_mountfs( | |||
1152 | /* | 1251 | /* |
1153 | * Allocate and initialize the per-ag data. | 1252 | * Allocate and initialize the per-ag data. |
1154 | */ | 1253 | */ |
1155 | init_rwsem(&mp->m_peraglock); | 1254 | spin_lock_init(&mp->m_perag_lock); |
1156 | mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), | 1255 | INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS); |
1157 | KM_MAYFAIL); | 1256 | error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); |
1158 | if (!mp->m_perag) | 1257 | if (error) { |
1258 | cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); | ||
1159 | goto out_remove_uuid; | 1259 | goto out_remove_uuid; |
1160 | 1260 | } | |
1161 | mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); | ||
1162 | 1261 | ||
1163 | if (!sbp->sb_logblocks) { | 1262 | if (!sbp->sb_logblocks) { |
1164 | cmn_err(CE_WARN, "XFS: no log defined"); | 1263 | cmn_err(CE_WARN, "XFS: no log defined"); |
@@ -1318,18 +1417,14 @@ xfs_mountfs( | |||
1318 | * when at ENOSPC. This is needed for operations like create with | 1417 | * when at ENOSPC. This is needed for operations like create with |
1319 | * attr, unwritten extent conversion at ENOSPC, etc. Data allocations | 1418 | * attr, unwritten extent conversion at ENOSPC, etc. Data allocations |
1320 | * are not allowed to use this reserved space. | 1419 | * are not allowed to use this reserved space. |
1321 | * | ||
1322 | * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | ||
1323 | * This may drive us straight to ENOSPC on mount, but that implies | ||
1324 | * we were already there on the last unmount. Warn if this occurs. | ||
1325 | */ | 1420 | */ |
1326 | resblks = mp->m_sb.sb_dblocks; | 1421 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { |
1327 | do_div(resblks, 20); | 1422 | resblks = xfs_default_resblks(mp); |
1328 | resblks = min_t(__uint64_t, resblks, 1024); | 1423 | error = xfs_reserve_blocks(mp, &resblks, NULL); |
1329 | error = xfs_reserve_blocks(mp, &resblks, NULL); | 1424 | if (error) |
1330 | if (error) | 1425 | cmn_err(CE_WARN, "XFS: Unable to allocate reserve " |
1331 | cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. " | 1426 | "blocks. Continuing without a reserve pool."); |
1332 | "Continuing without a reserve pool."); | 1427 | } |
1333 | 1428 | ||
1334 | return 0; | 1429 | return 0; |
1335 | 1430 | ||
@@ -1372,8 +1467,19 @@ xfs_unmountfs( | |||
1372 | * push out the iclog we will never get that unlocked. hence we | 1467 | * push out the iclog we will never get that unlocked. hence we |
1373 | * need to force the log first. | 1468 | * need to force the log first. |
1374 | */ | 1469 | */ |
1375 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | 1470 | xfs_log_force(mp, XFS_LOG_SYNC); |
1376 | xfs_reclaim_inodes(mp, XFS_IFLUSH_ASYNC); | 1471 | |
1472 | /* | ||
1473 | * Do a delwri reclaim pass first so that as many dirty inodes are | ||
1474 | * queued up for IO as possible. Then flush the buffers before making | ||
1475 | * a synchronous path to catch all the remaining inodes are reclaimed. | ||
1476 | * This makes the reclaim process as quick as possible by avoiding | ||
1477 | * synchronous writeout and blocking on inodes already in the delwri | ||
1478 | * state as much as possible. | ||
1479 | */ | ||
1480 | xfs_reclaim_inodes(mp, 0); | ||
1481 | XFS_bflush(mp->m_ddev_targp); | ||
1482 | xfs_reclaim_inodes(mp, SYNC_WAIT); | ||
1377 | 1483 | ||
1378 | xfs_qm_unmount(mp); | 1484 | xfs_qm_unmount(mp); |
1379 | 1485 | ||
@@ -1382,7 +1488,7 @@ xfs_unmountfs( | |||
1382 | * that nothing is pinned. This is important because bflush() | 1488 | * that nothing is pinned. This is important because bflush() |
1383 | * will skip pinned buffers. | 1489 | * will skip pinned buffers. |
1384 | */ | 1490 | */ |
1385 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | 1491 | xfs_log_force(mp, XFS_LOG_SYNC); |
1386 | 1492 | ||
1387 | xfs_binval(mp->m_ddev_targp); | 1493 | xfs_binval(mp->m_ddev_targp); |
1388 | if (mp->m_rtdev_targp) { | 1494 | if (mp->m_rtdev_targp) { |
@@ -1548,15 +1654,14 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1548 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); | 1654 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); |
1549 | 1655 | ||
1550 | /* find modified range */ | 1656 | /* find modified range */ |
1657 | f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); | ||
1658 | ASSERT((1LL << f) & XFS_SB_MOD_BITS); | ||
1659 | last = xfs_sb_info[f + 1].offset - 1; | ||
1551 | 1660 | ||
1552 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); | 1661 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); |
1553 | ASSERT((1LL << f) & XFS_SB_MOD_BITS); | 1662 | ASSERT((1LL << f) & XFS_SB_MOD_BITS); |
1554 | first = xfs_sb_info[f].offset; | 1663 | first = xfs_sb_info[f].offset; |
1555 | 1664 | ||
1556 | f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); | ||
1557 | ASSERT((1LL << f) & XFS_SB_MOD_BITS); | ||
1558 | last = xfs_sb_info[f + 1].offset - 1; | ||
1559 | |||
1560 | xfs_trans_log_buf(tp, bp, first, last); | 1665 | xfs_trans_log_buf(tp, bp, first, last); |
1561 | } | 1666 | } |
1562 | 1667 | ||
@@ -1887,7 +1992,7 @@ xfs_getsb( | |||
1887 | 1992 | ||
1888 | ASSERT(mp->m_sb_bp != NULL); | 1993 | ASSERT(mp->m_sb_bp != NULL); |
1889 | bp = mp->m_sb_bp; | 1994 | bp = mp->m_sb_bp; |
1890 | if (flags & XFS_BUF_TRYLOCK) { | 1995 | if (flags & XBF_TRYLOCK) { |
1891 | if (!XFS_BUF_CPSEMA(bp)) { | 1996 | if (!XFS_BUF_CPSEMA(bp)) { |
1892 | return NULL; | 1997 | return NULL; |
1893 | } | 1998 | } |