diff options
Diffstat (limited to 'fs/xfs')
| -rw-r--r-- | fs/xfs/Kconfig | 1 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_remote.c | 7 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_btree.c | 6 | ||||
| -rw-r--r-- | fs/xfs/xfs_aops.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_zone_alloc.c | 45 | ||||
| -rw-r--r-- | fs/xfs/xfs_zone_space_resv.c | 6 | 
6 files changed, 25 insertions, 43 deletions
| diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index ae0ca6858496..065953475cf5 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -105,6 +105,7 @@ config XFS_POSIX_ACL  config XFS_RT  	bool "XFS Realtime subvolume support"  	depends on XFS_FS +	default BLK_DEV_ZONED  	help  	  If you say Y here you will be able to mount and use XFS filesystems  	  which contain a realtime subvolume.  The realtime subvolume is a diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 4c44ce1c8a64..bff3dc226f81 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -435,6 +435,13 @@ xfs_attr_rmtval_get(  					0, &bp, &xfs_attr3_rmt_buf_ops);  			if (xfs_metadata_is_sick(error))  				xfs_dirattr_mark_sick(args->dp, XFS_ATTR_FORK); +			/* +			 * ENODATA from disk implies a disk medium failure; +			 * ENODATA for xattrs means attribute not found, so +			 * disambiguate that here. +			 */ +			if (error == -ENODATA) +				error = -EIO;  			if (error)  				return error; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 17d9e6154f19..723a0643b838 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2833,6 +2833,12 @@ xfs_da_read_buf(  			&bp, ops);  	if (xfs_metadata_is_sick(error))  		xfs_dirattr_mark_sick(dp, whichfork); +	/* +	 * ENODATA from disk implies a disk medium failure; ENODATA for +	 * xattrs means attribute not found, so disambiguate that here. +	 */ +	if (error == -ENODATA && whichfork == XFS_ATTR_FORK) +		error = -EIO;  	if (error)  		goto out_free; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 1ee4f835ac3c..a26f79815533 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -760,6 +760,9 @@ xfs_vm_swap_activate(  {  	struct xfs_inode		*ip = XFS_I(file_inode(swap_file)); +	if (xfs_is_zoned_inode(ip)) +		return -EINVAL; +  	/*  	 * Swap file activation can race against concurrent shared extent  	 * removal in files that have been cloned.  If this happens, diff --git a/fs/xfs/xfs_zone_alloc.c b/fs/xfs/xfs_zone_alloc.c index f8bd6d741755..f28214c28ab5 100644 --- a/fs/xfs/xfs_zone_alloc.c +++ b/fs/xfs/xfs_zone_alloc.c @@ -374,44 +374,6 @@ xfs_zone_free_blocks(  	return 0;  } -/* - * Check if the zone containing the data just before the offset we are - * writing to is still open and has space. - */ -static struct xfs_open_zone * -xfs_last_used_zone( -	struct iomap_ioend	*ioend) -{ -	struct xfs_inode	*ip = XFS_I(ioend->io_inode); -	struct xfs_mount	*mp = ip->i_mount; -	xfs_fileoff_t		offset_fsb = XFS_B_TO_FSB(mp, ioend->io_offset); -	struct xfs_rtgroup	*rtg = NULL; -	struct xfs_open_zone	*oz = NULL; -	struct xfs_iext_cursor	icur; -	struct xfs_bmbt_irec	got; - -	xfs_ilock(ip, XFS_ILOCK_SHARED); -	if (!xfs_iext_lookup_extent_before(ip, &ip->i_df, &offset_fsb, -				&icur, &got)) { -		xfs_iunlock(ip, XFS_ILOCK_SHARED); -		return NULL; -	} -	xfs_iunlock(ip, XFS_ILOCK_SHARED); - -	rtg = xfs_rtgroup_grab(mp, xfs_rtb_to_rgno(mp, got.br_startblock)); -	if (!rtg) -		return NULL; - -	xfs_ilock(rtg_rmap(rtg), XFS_ILOCK_SHARED); -	oz = READ_ONCE(rtg->rtg_open_zone); -	if (oz && (oz->oz_is_gc || !atomic_inc_not_zero(&oz->oz_ref))) -		oz = NULL; -	xfs_iunlock(rtg_rmap(rtg), XFS_ILOCK_SHARED); - -	xfs_rtgroup_rele(rtg); -	return oz; -} -  static struct xfs_group *  xfs_find_free_zone(  	struct xfs_mount	*mp, @@ -918,12 +880,9 @@ xfs_zone_alloc_and_submit(  		goto out_error;  	/* -	 * If we don't have a cached zone in this write context, see if the -	 * last extent before the one we are writing to points to an active -	 * zone.  If so, just continue writing to it. +	 * If we don't have a locally cached zone in this write context, see if +	 * the inode is still associated with a zone and use that if so.  	 */ -	if (!*oz && ioend->io_offset) -		*oz = xfs_last_used_zone(ioend);  	if (!*oz)  		*oz = xfs_cached_zone(mp, ip); diff --git a/fs/xfs/xfs_zone_space_resv.c b/fs/xfs/xfs_zone_space_resv.c index 1313c55b8cbe..9cd38716fd25 100644 --- a/fs/xfs/xfs_zone_space_resv.c +++ b/fs/xfs/xfs_zone_space_resv.c @@ -10,6 +10,7 @@  #include "xfs_mount.h"  #include "xfs_inode.h"  #include "xfs_rtbitmap.h" +#include "xfs_icache.h"  #include "xfs_zone_alloc.h"  #include "xfs_zone_priv.h"  #include "xfs_zones.h" @@ -230,6 +231,11 @@ xfs_zoned_space_reserve(  	error = xfs_dec_freecounter(mp, XC_FREE_RTEXTENTS, count_fsb,  			flags & XFS_ZR_RESERVED); +	if (error == -ENOSPC && !(flags & XFS_ZR_NOWAIT)) { +		xfs_inodegc_flush(mp); +		error = xfs_dec_freecounter(mp, XC_FREE_RTEXTENTS, count_fsb, +				flags & XFS_ZR_RESERVED); +	}  	if (error == -ENOSPC && (flags & XFS_ZR_GREEDY) && count_fsb > 1)  		error = xfs_zoned_reserve_extents_greedy(mp, &count_fsb, flags);  	if (error) | 
