xfs: fix access to upper inodes without inode64

If a filesystem is mounted without the inode64 mount option we
should still be able to access inodes not fitting into 32 bits, just
not created new ones. For this to work we need to make sure the
inode cache radix tree is initialized for all allocation groups, not
just those we plan to allocate inodes from. This patch makes sure
we initialize the inode cache radix tree for all allocation groups,
and also cleans xfs_initialize_perag up a bit to separate the
inode32 logical from the general perag structure setup.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>

authored by Christoph Hellwig and committed by Alex Elder fb3b504a 9b98b6f3

+23 -48
-9
fs/xfs/linux-2.6/xfs_sync.c
··· 164 struct xfs_perag *pag; 165 166 pag = xfs_perag_get(mp, ag); 167 - if (!pag->pag_ici_init) { 168 - xfs_perag_put(pag); 169 - continue; 170 - } 171 error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, 172 exclusive, &nr); 173 xfs_perag_put(pag); ··· 863 down_read(&xfs_mount_list_lock); 864 list_for_each_entry(mp, &xfs_mount_list, m_mplist) { 865 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { 866 - 867 pag = xfs_perag_get(mp, ag); 868 - if (!pag->pag_ici_init) { 869 - xfs_perag_put(pag); 870 - continue; 871 - } 872 reclaimable += pag->pag_ici_reclaimable; 873 xfs_perag_put(pag); 874 }
··· 164 struct xfs_perag *pag; 165 166 pag = xfs_perag_get(mp, ag); 167 error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, 168 exclusive, &nr); 169 xfs_perag_put(pag); ··· 867 down_read(&xfs_mount_list_lock); 868 list_for_each_entry(mp, &xfs_mount_list, m_mplist) { 869 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { 870 pag = xfs_perag_get(mp, ag); 871 reclaimable += pag->pag_ici_reclaimable; 872 xfs_perag_put(pag); 873 }
-1
fs/xfs/xfs_ag.h
··· 227 228 atomic_t pagf_fstrms; /* # of filestreams active in this AG */ 229 230 - int pag_ici_init; /* incore inode cache initialised */ 231 rwlock_t pag_ici_lock; /* incore inode lock */ 232 struct radix_tree_root pag_ici_root; /* incore inode cache root */ 233 int pag_ici_reclaimable; /* reclaimable inodes */
··· 227 228 atomic_t pagf_fstrms; /* # of filestreams active in this AG */ 229 230 rwlock_t pag_ici_lock; /* incore inode lock */ 231 struct radix_tree_root pag_ici_root; /* incore inode cache root */ 232 int pag_ici_reclaimable; /* reclaimable inodes */
-3
fs/xfs/xfs_iget.c
··· 382 383 /* get the perag structure and ensure that it's inode capable */ 384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); 385 - if (!pag->pagi_inodeok) 386 - return EINVAL; 387 - ASSERT(pag->pag_ici_init); 388 agino = XFS_INO_TO_AGINO(mp, ino); 389 390 again:
··· 382 383 /* get the perag structure and ensure that it's inode capable */ 384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); 385 agino = XFS_INO_TO_AGINO(mp, ino); 386 387 again:
-2
fs/xfs/xfs_inode.c
··· 2649 int i; 2650 2651 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2652 - ASSERT(pag->pagi_inodeok); 2653 - ASSERT(pag->pag_ici_init); 2654 2655 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2656 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
··· 2649 int i; 2650 2651 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2652 2653 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2654 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
+23 -33
fs/xfs/xfs_mount.c
··· 413 return 0; 414 } 415 416 - STATIC void 417 - xfs_initialize_perag_icache( 418 - xfs_perag_t *pag) 419 - { 420 - if (!pag->pag_ici_init) { 421 - rwlock_init(&pag->pag_ici_lock); 422 - INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); 423 - pag->pag_ici_init = 1; 424 - } 425 - } 426 - 427 int 428 xfs_initialize_perag( 429 xfs_mount_t *mp, ··· 425 xfs_agino_t agino; 426 xfs_ino_t ino; 427 xfs_sb_t *sbp = &mp->m_sb; 428 - xfs_ino_t max_inum = XFS_MAXINUMBER_32; 429 int error = -ENOMEM; 430 - 431 - /* Check to see if the filesystem can overflow 32 bit inodes */ 432 - agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); 433 - ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); 434 435 /* 436 * Walk the current per-ag tree so we don't try to initialise AGs ··· 440 } 441 if (!first_initialised) 442 first_initialised = index; 443 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); 444 if (!pag) 445 goto out_unwind; 446 if (radix_tree_preload(GFP_NOFS)) 447 goto out_unwind; 448 spin_lock(&mp->m_perag_lock); 449 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { 450 BUG(); ··· 460 error = -EEXIST; 461 goto out_unwind; 462 } 463 - pag->pag_agno = index; 464 - pag->pag_mount = mp; 465 spin_unlock(&mp->m_perag_lock); 466 radix_tree_preload_end(); 467 } 468 469 - /* Clear the mount flag if no inode can overflow 32 bits 470 - * on this filesystem, or if specifically requested.. 471 */ 472 - if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { 473 - mp->m_flags |= XFS_MOUNT_32BITINODES; 474 - } else { 475 - mp->m_flags &= ~XFS_MOUNT_32BITINODES; 476 - } 477 478 - /* If we can overflow then setup the ag headers accordingly */ 479 if (mp->m_flags & XFS_MOUNT_32BITINODES) { 480 - /* Calculate how much should be reserved for inodes to 481 - * meet the max inode percentage. 482 */ 483 if (mp->m_maxicount) { 484 __uint64_t icount; ··· 492 } else { 493 max_metadata = agcount; 494 } 495 for (index = 0; index < agcount; index++) { 496 ino = XFS_AGINO_TO_INO(mp, index, agino); 497 - if (ino > max_inum) { 498 index++; 499 break; 500 } 501 502 - /* This ag is preferred for inodes */ 503 pag = xfs_perag_get(mp, index); 504 pag->pagi_inodeok = 1; 505 if (index < max_metadata) 506 pag->pagf_metadata = 1; 507 - xfs_initialize_perag_icache(pag); 508 xfs_perag_put(pag); 509 } 510 } else { 511 - /* Setup default behavior for smaller filesystems */ 512 for (index = 0; index < agcount; index++) { 513 pag = xfs_perag_get(mp, index); 514 pag->pagi_inodeok = 1; 515 - xfs_initialize_perag_icache(pag); 516 xfs_perag_put(pag); 517 } 518 } 519 if (maxagi) 520 *maxagi = index; 521 return 0;
··· 413 return 0; 414 } 415 416 int 417 xfs_initialize_perag( 418 xfs_mount_t *mp, ··· 436 xfs_agino_t agino; 437 xfs_ino_t ino; 438 xfs_sb_t *sbp = &mp->m_sb; 439 int error = -ENOMEM; 440 441 /* 442 * Walk the current per-ag tree so we don't try to initialise AGs ··· 456 } 457 if (!first_initialised) 458 first_initialised = index; 459 + 460 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); 461 if (!pag) 462 goto out_unwind; 463 + pag->pag_agno = index; 464 + pag->pag_mount = mp; 465 + rwlock_init(&pag->pag_ici_lock); 466 + INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); 467 + 468 if (radix_tree_preload(GFP_NOFS)) 469 goto out_unwind; 470 + 471 spin_lock(&mp->m_perag_lock); 472 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { 473 BUG(); ··· 469 error = -EEXIST; 470 goto out_unwind; 471 } 472 spin_unlock(&mp->m_perag_lock); 473 radix_tree_preload_end(); 474 } 475 476 + /* 477 + * If we mount with the inode64 option, or no inode overflows 478 + * the legacy 32-bit address space clear the inode32 option. 479 */ 480 + agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); 481 + ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); 482 483 + if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32) 484 + mp->m_flags |= XFS_MOUNT_32BITINODES; 485 + else 486 + mp->m_flags &= ~XFS_MOUNT_32BITINODES; 487 + 488 if (mp->m_flags & XFS_MOUNT_32BITINODES) { 489 + /* 490 + * Calculate how much should be reserved for inodes to meet 491 + * the max inode percentage. 492 */ 493 if (mp->m_maxicount) { 494 __uint64_t icount; ··· 500 } else { 501 max_metadata = agcount; 502 } 503 + 504 for (index = 0; index < agcount; index++) { 505 ino = XFS_AGINO_TO_INO(mp, index, agino); 506 + if (ino > XFS_MAXINUMBER_32) { 507 index++; 508 break; 509 } 510 511 pag = xfs_perag_get(mp, index); 512 pag->pagi_inodeok = 1; 513 if (index < max_metadata) 514 pag->pagf_metadata = 1; 515 xfs_perag_put(pag); 516 } 517 } else { 518 for (index = 0; index < agcount; index++) { 519 pag = xfs_perag_get(mp, index); 520 pag->pagi_inodeok = 1; 521 xfs_perag_put(pag); 522 } 523 } 524 + 525 if (maxagi) 526 *maxagi = index; 527 return 0;