[PATCH] default to 64 bit inodes & add feature flag
Josef 'Jeff' Sipek
jeffpc at josefsipek.net
Wed Mar 7 11:33:13 CST 2012
On Wed, Mar 07, 2012 at 11:20:57AM -0600, Eric Sandeen wrote:
> From: Dave Chinner <dchinner at redhat.com>
>
> Default to allowing 64-bit inodes on the filesystem.
>
> Add a feature bit to the the superblock to record whether 64 bit inodes have
> been allocated on the filesystem or not. This allows us to reject mounting the
> filesytem with inode32 if 64 bit inodes are present.
>
> Once a 64 bitinode is allocated, the inode64 superblock feature bit will be set.
> Once the superblock feature bit is set, the filesystem will default to 64 bit
> inodes regardless of whether inode64 is specified as a mount option.
>
> To ensure only 32 bit inodes are created, the inode32 mount option must be
> used. If there are already 64 bit inodes as flagged by the superblock feature
> bit, then the inode32 mount will be refused.
>
> Signed-off-by: Dave Chinner <dchinner at redhat.com>
Love it! Just last night, I ended up with a filesystem (x86_64, ~36TB, RAID
60) that started giving me ENOSPC for no reason (~1% disk utilization).
Eric pointed out that I forgot to use inode64. (For whatever reason, I
thought that a 64-bit system would implicitly use 64-bit inodes. We'll
*never* mount this fs on a 32-bit system, so I don't care about the
"incompatibility".)
I'm liking the feature-bit approach.
Jeff.
> diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
> index dad1a31..c80790e 100644
> --- a/fs/xfs/xfs_ialloc.c
> +++ b/fs/xfs/xfs_ialloc.c
> @@ -1011,6 +1011,19 @@ alloc_inode:
> xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
> xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
> xfs_perag_put(pag);
> +
> + /* set the inode64 feature bit if necessary */
> + if (ino > XFS_MAXINUMBER_32 &&
> + !xfs_sb_version_hasinode64(&mp->m_sb)) {
> + spin_lock(&mp->m_sb_lock);
> + if (!xfs_sb_version_hasinode64(&mp->m_sb)) {
> + xfs_sb_version_addinode64(&mp->m_sb);
> + spin_unlock(&mp->m_sb_lock);
> + xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
> + } else
> + spin_unlock(&mp->m_sb_lock);
> + }
> +
> *inop = ino;
> return 0;
> error1:
> diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
> index cb6ae71..5e28c99 100644
> --- a/fs/xfs/xfs_sb.h
> +++ b/fs/xfs/xfs_sb.h
> @@ -80,6 +80,7 @@ struct xfs_mount;
> #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
> #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
> #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */
> +#define XFS_SB_VERSION2_INODE64 0x00000020 /* 64 bit inodes */
> #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */
>
> #define XFS_SB_VERSION2_OKREALFBITS \
> @@ -503,6 +504,18 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp)
> (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT);
> }
>
> +static inline int xfs_sb_version_hasinode64(xfs_sb_t *sbp)
> +{
> + return xfs_sb_version_hasmorebits(sbp) &&
> + (sbp->sb_features2 & XFS_SB_VERSION2_INODE64);
> +}
> +
> +static inline void xfs_sb_version_addinode64(xfs_sb_t *sbp)
> +{
> + sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
> + sbp->sb_features2 |= XFS_SB_VERSION2_INODE64;
> +}
> +
> /*
> * end of superblock version macros
> */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index ee5b695..376a12d 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -88,6 +88,7 @@ mempool_t *xfs_ioend_pool;
> #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
> * unwritten extent conversion */
> #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
> +#define MNTOPT_32BITINODE "inode32" /* inodes allowed in first 32 bits */
> #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
> #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
> #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
> @@ -198,7 +199,8 @@ xfs_parseargs(
> */
> mp->m_flags |= XFS_MOUNT_BARRIER;
> mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> - mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> + if (!xfs_sb_version_hasinode64(&mp->m_sb))
> + mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
>
> /*
> * These can be overridden by the mount option parsing.
> @@ -295,6 +297,15 @@ xfs_parseargs(
> return EINVAL;
> }
> dswidth = simple_strtoul(value, &eov, 10);
> + } else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
> + if (xfs_sb_version_hasinode64(&mp->m_sb)) {
> + xfs_warn(mp,
> + "XFS: 64 bit inodes present. "
> + "%s option not allowed on this system",
> + this_char);
> + return EINVAL;
> + }
> + mp->m_flags |= ~XFS_MOUNT_SMALL_INUMS;
> } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
> mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> #if !XFS_BIG_INUMS
> @@ -494,6 +505,7 @@ xfs_showargs(
> { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
> { XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
> { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD },
> + { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE },
> { 0, NULL }
> };
> static struct proc_xfs_info xfs_info_unset[] = {
>
--
I have always wished for my computer to be as easy to use as my telephone;
my wish has come true because I can no longer figure out how to use my
telephone.
- Bjarne Stroustrup
More information about the xfs
mailing list