diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_inode_fork.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_inode_fork.c | 19 | 
1 files changed, 17 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 6b21760184d9..5a2e7ddfa76d 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -140,7 +140,8 @@ xfs_iformat_extents(  				xfs_inode_verifier_error(ip, -EFSCORRUPTED,  						"xfs_iformat_extents(2)",  						dp, sizeof(*dp), fa); -				return -EFSCORRUPTED; +				return xfs_bmap_complain_bad_rec(ip, whichfork, +						fa, &new);  			}  			xfs_iext_insert(ip, &icur, &new, state); @@ -226,10 +227,15 @@ xfs_iformat_data_fork(  	/*  	 * Initialize the extent count early, as the per-format routines may -	 * depend on it. +	 * depend on it.  Use release semantics to set needextents /after/ we +	 * set the format. This ensures that we can use acquire semantics on +	 * needextents in xfs_need_iread_extents() and be guaranteed to see a +	 * valid format value after that load.  	 */  	ip->i_df.if_format = dip->di_format;  	ip->i_df.if_nextents = xfs_dfork_data_extents(dip); +	smp_store_release(&ip->i_df.if_needextents, +			   ip->i_df.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);  	switch (inode->i_mode & S_IFMT) {  	case S_IFIFO: @@ -282,8 +288,17 @@ xfs_ifork_init_attr(  	enum xfs_dinode_fmt	format,  	xfs_extnum_t		nextents)  { +	/* +	 * Initialize the extent count early, as the per-format routines may +	 * depend on it.  Use release semantics to set needextents /after/ we +	 * set the format. This ensures that we can use acquire semantics on +	 * needextents in xfs_need_iread_extents() and be guaranteed to see a +	 * valid format value after that load. +	 */  	ip->i_af.if_format = format;  	ip->i_af.if_nextents = nextents; +	smp_store_release(&ip->i_af.if_needextents, +			   ip->i_af.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);  }  void  |