Re: [PATCH] default to 64 bit inodes & add feature flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux