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