diff --git a/include/xfs_mount.h b/include/xfs_mount.h index dc2206de..f3c03833 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -207,6 +207,7 @@ __XFS_UNSUPP_FEAT(wsync) __XFS_UNSUPP_FEAT(noattr2) __XFS_UNSUPP_FEAT(ikeep) __XFS_UNSUPP_FEAT(swalloc) +__XFS_UNSUPP_FEAT(small_inums) __XFS_UNSUPP_FEAT(readonly) /* Operational mount state flags */ diff --git a/libxfs/init.c b/libxfs/init.c index 94f70429..5a3bf169 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -425,14 +425,13 @@ libxfs_init(libxfs_init_t *a) */ static int rtmount_init( - xfs_mount_t *mp, /* file system mount structure */ - int flags) + xfs_mount_t *mp) /* file system mount structure */ { struct xfs_buf *bp; /* buffer for last block of subvolume */ xfs_daddr_t d; /* address of last block of subvolume */ int error; - if (!xfs_has_realtime(mp)) + if (mp->m_sb.sb_rblocks == 0) return 0; if (xfs_has_reflink(mp)) { @@ -490,13 +489,21 @@ rtmount_init( /* * Set parameters for inode allocation heuristics, taking into account - * filesystem size. + * filesystem size and inode32/inode64 mount options; i.e. specifically + * whether or not XFS_MOUNT_SMALL_INUMS is set. + * + * Inode allocation patterns are altered only if inode32 is requested + * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large. + * If altered, XFS_MOUNT_32BITINODES is set as well. * * An agcount independent of that in the mount structure is provided * because in the growfs case, mp->m_sb.sb_agcount is not yet updated * to the potentially higher ag count. * * Returns the maximum AG index which may contain inodes. + * + * NOTE: userspace has no concept of "inode32" and so xfs_has_small_inums + * is always false, and much of this code is a no-op. */ xfs_agnumber_t xfs_set_inode_alloc( @@ -526,11 +533,19 @@ xfs_set_inode_alloc( max_metadata = agcount; } - /* Get the last possible inode in an AG. */ - agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1); + /* Get the last possible inode in the filesystem */ + agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1); + ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); - /* There is no inode32 mount option in userspace, so clear it. */ - xfs_clear_inode32(mp); + /* + * If user asked for no more than 32-bit inodes, and the fs is + * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter + * the allocator to accommodate the request. + */ + if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32) + xfs_set_inode32(mp); + else + xfs_clear_inode32(mp); for (index = 0; index < agcount; index++) { struct xfs_perag *pag; @@ -815,7 +830,7 @@ libxfs_mount( } /* Initialize realtime fields in the mount structure */ - if (rtmount_init(mp, flags)) { + if (rtmount_init(mp)) { fprintf(stderr, _("%s: realtime device init failed\n"), progname); return NULL; diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 2a9e8c98..6c5ce3ea 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -214,7 +214,7 @@ libxfs_bcompare(struct cache_node *node, cache_key_t key) "%lx: Badness in key lookup (length)\n" "bp=(bno 0x%llx, len %u bytes) key=(bno 0x%llx, len %u bytes)\n", pthread_self(), - (unsigned long long)xfs_buf_daddr(bp), + xfs_buf_daddr(bp), BBTOB(bp->b_length), (unsigned long long)bkey->blkno, BBTOB(bkey->bblen)); @@ -833,14 +833,15 @@ libxfs_bwrite( fprintf(stderr, _("%s: write verifier failed on %s bno 0x%llx/0x%x\n"), __func__, bp->b_ops->name, - (long long)xfs_buf_daddr(bp), bp->b_length); + xfs_buf_daddr(bp), bp->b_length); return bp->b_error; } } if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) { bp->b_error = __write_buf(fd, bp->b_addr, BBTOB(bp->b_length), - LIBXFS_BBTOOFF64(xfs_buf_daddr(bp)), bp->b_flags); + LIBXFS_BBTOOFF64(xfs_buf_daddr(bp)), + bp->b_flags); } else { int i; void *buf = bp->b_addr; @@ -861,7 +862,7 @@ libxfs_bwrite( fprintf(stderr, _("%s: write failed on %s bno 0x%llx/0x%x, err=%d\n"), __func__, bp->b_ops ? bp->b_ops->name : "(unknown)", - (long long)xfs_buf_daddr(bp), bp->b_length, -bp->b_error); + xfs_buf_daddr(bp), bp->b_length, -bp->b_error); } else { bp->b_flags |= LIBXFS_B_UPTODATE; bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_UNCHECKED);