diff options
Diffstat (limited to 'fs/xfs/xfs_super.c')
| -rw-r--r-- | fs/xfs/xfs_super.c | 103 | 
1 files changed, 45 insertions, 58 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e21459f9923a..e8f37bdc8354 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -331,13 +331,34 @@ xfs_set_inode_alloc(  	return xfs_is_inode32(mp) ? maxagi : agcount;  } -static bool -xfs_buftarg_is_dax( -	struct super_block	*sb, -	struct xfs_buftarg	*bt) +static int +xfs_setup_dax_always( +	struct xfs_mount	*mp)  { -	return dax_supported(bt->bt_daxdev, bt->bt_bdev, sb->s_blocksize, 0, -			bdev_nr_sectors(bt->bt_bdev)); +	if (!mp->m_ddev_targp->bt_daxdev && +	    (!mp->m_rtdev_targp || !mp->m_rtdev_targp->bt_daxdev)) { +		xfs_alert(mp, +			"DAX unsupported by block device. Turning off DAX."); +		goto disable_dax; +	} + +	if (mp->m_super->s_blocksize != PAGE_SIZE) { +		xfs_alert(mp, +			"DAX not supported for blocksize. Turning off DAX."); +		goto disable_dax; +	} + +	if (xfs_has_reflink(mp)) { +		xfs_alert(mp, "DAX and reflink cannot be used together!"); +		return -EINVAL; +	} + +	xfs_warn(mp, "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); +	return 0; + +disable_dax: +	xfs_mount_set_dax_mode(mp, XFS_DAX_NEVER); +	return 0;  }  STATIC int @@ -370,26 +391,19 @@ STATIC void  xfs_close_devices(  	struct xfs_mount	*mp)  { -	struct dax_device *dax_ddev = mp->m_ddev_targp->bt_daxdev; -  	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {  		struct block_device *logdev = mp->m_logdev_targp->bt_bdev; -		struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;  		xfs_free_buftarg(mp->m_logdev_targp);  		xfs_blkdev_put(logdev); -		fs_put_dax(dax_logdev);  	}  	if (mp->m_rtdev_targp) {  		struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; -		struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;  		xfs_free_buftarg(mp->m_rtdev_targp);  		xfs_blkdev_put(rtdev); -		fs_put_dax(dax_rtdev);  	}  	xfs_free_buftarg(mp->m_ddev_targp); -	fs_put_dax(dax_ddev);  }  /* @@ -407,8 +421,6 @@ xfs_open_devices(  	struct xfs_mount	*mp)  {  	struct block_device	*ddev = mp->m_super->s_bdev; -	struct dax_device	*dax_ddev = fs_dax_get_by_bdev(ddev); -	struct dax_device	*dax_logdev = NULL, *dax_rtdev = NULL;  	struct block_device	*logdev = NULL, *rtdev = NULL;  	int			error; @@ -418,8 +430,7 @@ xfs_open_devices(  	if (mp->m_logname) {  		error = xfs_blkdev_get(mp, mp->m_logname, &logdev);  		if (error) -			goto out; -		dax_logdev = fs_dax_get_by_bdev(logdev); +			return error;  	}  	if (mp->m_rtname) { @@ -433,25 +444,24 @@ xfs_open_devices(  			error = -EINVAL;  			goto out_close_rtdev;  		} -		dax_rtdev = fs_dax_get_by_bdev(rtdev);  	}  	/*  	 * Setup xfs_mount buffer target pointers  	 */  	error = -ENOMEM; -	mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev); +	mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);  	if (!mp->m_ddev_targp)  		goto out_close_rtdev;  	if (rtdev) { -		mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev); +		mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);  		if (!mp->m_rtdev_targp)  			goto out_free_ddev_targ;  	}  	if (logdev && logdev != ddev) { -		mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev); +		mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);  		if (!mp->m_logdev_targp)  			goto out_free_rtdev_targ;  	} else { @@ -467,14 +477,9 @@ xfs_open_devices(  	xfs_free_buftarg(mp->m_ddev_targp);   out_close_rtdev:  	xfs_blkdev_put(rtdev); -	fs_put_dax(dax_rtdev);   out_close_logdev: -	if (logdev && logdev != ddev) { +	if (logdev && logdev != ddev)  		xfs_blkdev_put(logdev); -		fs_put_dax(dax_logdev); -	} - out: -	fs_put_dax(dax_ddev);  	return error;  } @@ -1593,26 +1598,9 @@ xfs_fs_fill_super(  		sb->s_flags |= SB_I_VERSION;  	if (xfs_has_dax_always(mp)) { -		bool rtdev_is_dax = false, datadev_is_dax; - -		xfs_warn(mp, -		"DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); - -		datadev_is_dax = xfs_buftarg_is_dax(sb, mp->m_ddev_targp); -		if (mp->m_rtdev_targp) -			rtdev_is_dax = xfs_buftarg_is_dax(sb, -						mp->m_rtdev_targp); -		if (!rtdev_is_dax && !datadev_is_dax) { -			xfs_alert(mp, -			"DAX unsupported by block device. Turning off DAX."); -			xfs_mount_set_dax_mode(mp, XFS_DAX_NEVER); -		} -		if (xfs_has_reflink(mp)) { -			xfs_alert(mp, -		"DAX and reflink cannot be used together!"); -			error = -EINVAL; +		error = xfs_setup_dax_always(mp); +		if (error)  			goto out_filestream_unmount; -		}  	}  	if (xfs_has_discard(mp)) { @@ -1739,15 +1727,6 @@ xfs_remount_rw(  	 */  	xfs_restore_resvblks(mp);  	xfs_log_work_queue(mp); - -	/* Recover any CoW blocks that never got remapped. */ -	error = xfs_reflink_recover_cow(mp); -	if (error) { -		xfs_err(mp, -			"Error %d recovering leftover CoW allocations.", error); -		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); -		return error; -	}  	xfs_blockgc_start(mp);  	/* Create the per-AG metadata reservation pool .*/ @@ -1765,7 +1744,10 @@ static int  xfs_remount_ro(  	struct xfs_mount	*mp)  { -	int error; +	struct xfs_icwalk	icw = { +		.icw_flags	= XFS_ICWALK_FLAG_SYNC, +	}; +	int			error;  	/*  	 * Cancel background eofb scanning so it cannot race with the final @@ -1773,8 +1755,13 @@ xfs_remount_ro(  	 */  	xfs_blockgc_stop(mp); -	/* Get rid of any leftover CoW reservations... */ -	error = xfs_blockgc_free_space(mp, NULL); +	/* +	 * Clear out all remaining COW staging extents and speculative post-EOF +	 * preallocations so that we don't leave inodes requiring inactivation +	 * cleanups during reclaim on a read-only mount.  We must process every +	 * cached inode, so this requires a synchronous cache scan. +	 */ +	error = xfs_blockgc_free_space(mp, &icw);  	if (error) {  		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);  		return error;  |