On Wed, Mar 07, 2012 at 11:20:57AM -0600, Eric Sandeen wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > 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@xxxxxxxxxx> 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 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs