diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
| -rw-r--r-- | fs/xfs/xfs_log.c | 69 | 
1 files changed, 42 insertions, 27 deletions
| diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 292308dede6d..ca4fd5bd8522 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -34,6 +34,7 @@  #include "xfs_trace.h"  #include "xfs_fsops.h"  #include "xfs_cksum.h" +#include "xfs_sysfs.h"  kmem_zone_t	*xfs_log_ticket_zone; @@ -283,7 +284,7 @@ xlog_grant_head_wait(  	return 0;  shutdown:  	list_del_init(&tic->t_queue); -	return XFS_ERROR(EIO); +	return -EIO;  }  /* @@ -377,7 +378,7 @@ xfs_log_regrant(  	int			error = 0;  	if (XLOG_FORCED_SHUTDOWN(log)) -		return XFS_ERROR(EIO); +		return -EIO;  	XFS_STATS_INC(xs_try_logspace); @@ -446,7 +447,7 @@ xfs_log_reserve(  	ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);  	if (XLOG_FORCED_SHUTDOWN(log)) -		return XFS_ERROR(EIO); +		return -EIO;  	XFS_STATS_INC(xs_try_logspace); @@ -454,7 +455,7 @@ xfs_log_reserve(  	tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent,  				KM_SLEEP | KM_MAYFAIL);  	if (!tic) -		return XFS_ERROR(ENOMEM); +		return -ENOMEM;  	tic->t_trans_type = t_type;  	*ticp = tic; @@ -590,7 +591,7 @@ xfs_log_release_iclog(  {  	if (xlog_state_release_iclog(mp->m_log, iclog)) {  		xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); -		return EIO; +		return -EIO;  	}  	return 0; @@ -628,7 +629,7 @@ xfs_log_mount(  	mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);  	if (IS_ERR(mp->m_log)) { -		error = -PTR_ERR(mp->m_log); +		error = PTR_ERR(mp->m_log);  		goto out;  	} @@ -652,18 +653,18 @@ xfs_log_mount(  		xfs_warn(mp,  		"Log size %d blocks too small, minimum size is %d blocks",  			 mp->m_sb.sb_logblocks, min_logfsbs); -		error = EINVAL; +		error = -EINVAL;  	} else if (mp->m_sb.sb_logblocks > XFS_MAX_LOG_BLOCKS) {  		xfs_warn(mp,  		"Log size %d blocks too large, maximum size is %lld blocks",  			 mp->m_sb.sb_logblocks, XFS_MAX_LOG_BLOCKS); -		error = EINVAL; +		error = -EINVAL;  	} else if (XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks) > XFS_MAX_LOG_BYTES) {  		xfs_warn(mp,  		"log size %lld bytes too large, maximum size is %lld bytes",  			 XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks),  			 XFS_MAX_LOG_BYTES); -		error = EINVAL; +		error = -EINVAL;  	}  	if (error) {  		if (xfs_sb_version_hascrc(&mp->m_sb)) { @@ -707,6 +708,11 @@ xfs_log_mount(  		}  	} +	error = xfs_sysfs_init(&mp->m_log->l_kobj, &xfs_log_ktype, &mp->m_kobj, +			       "log"); +	if (error) +		goto out_destroy_ail; +  	/* Normal transactions can now occur */  	mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; @@ -947,6 +953,9 @@ xfs_log_unmount(  	xfs_log_quiesce(mp);  	xfs_trans_ail_destroy(mp); + +	xfs_sysfs_del(&mp->m_log->l_kobj); +  	xlog_dealloc_log(mp->m_log);  } @@ -1313,7 +1322,7 @@ xlog_alloc_log(  	xlog_in_core_t		*iclog, *prev_iclog=NULL;  	xfs_buf_t		*bp;  	int			i; -	int			error = ENOMEM; +	int			error = -ENOMEM;  	uint			log2_size = 0;  	log = kmem_zalloc(sizeof(struct xlog), KM_MAYFAIL); @@ -1340,7 +1349,7 @@ xlog_alloc_log(  	xlog_grant_head_init(&log->l_reserve_head);  	xlog_grant_head_init(&log->l_write_head); -	error = EFSCORRUPTED; +	error = -EFSCORRUPTED;  	if (xfs_sb_version_hassector(&mp->m_sb)) {  	        log2_size = mp->m_sb.sb_logsectlog;  		if (log2_size < BBSHIFT) { @@ -1369,8 +1378,14 @@ xlog_alloc_log(  	xlog_get_iclog_buffer_size(mp, log); -	error = ENOMEM; -	bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0); +	/* +	 * Use a NULL block for the extra log buffer used during splits so that +	 * it will trigger errors if we ever try to do IO on it without first +	 * having set it up properly. +	 */ +	error = -ENOMEM; +	bp = xfs_buf_alloc(mp->m_logdev_targp, XFS_BUF_DADDR_NULL, +			   BTOBB(log->l_iclog_size), 0);  	if (!bp)  		goto out_free_log; @@ -1463,7 +1478,7 @@ out_free_iclog:  out_free_log:  	kmem_free(log);  out: -	return ERR_PTR(-error); +	return ERR_PTR(error);  }	/* xlog_alloc_log */ @@ -1661,7 +1676,7 @@ xlog_bdstrat(  	xfs_buf_lock(bp);  	if (iclog->ic_state & XLOG_STATE_IOERROR) { -		xfs_buf_ioerror(bp, EIO); +		xfs_buf_ioerror(bp, -EIO);  		xfs_buf_stale(bp);  		xfs_buf_ioend(bp, 0);  		/* @@ -2360,7 +2375,7 @@ xlog_write(  			ophdr = xlog_write_setup_ophdr(log, ptr, ticket, flags);  			if (!ophdr) -				return XFS_ERROR(EIO); +				return -EIO;  			xlog_write_adv_cnt(&ptr, &len, &log_offset,  					   sizeof(struct xlog_op_header)); @@ -2859,7 +2874,7 @@ restart:  	spin_lock(&log->l_icloglock);  	if (XLOG_FORCED_SHUTDOWN(log)) {  		spin_unlock(&log->l_icloglock); -		return XFS_ERROR(EIO); +		return -EIO;  	}  	iclog = log->l_iclog; @@ -3047,7 +3062,7 @@ xlog_state_release_iclog(  	int		sync = 0;	/* do we sync? */  	if (iclog->ic_state & XLOG_STATE_IOERROR) -		return XFS_ERROR(EIO); +		return -EIO;  	ASSERT(atomic_read(&iclog->ic_refcnt) > 0);  	if (!atomic_dec_and_lock(&iclog->ic_refcnt, &log->l_icloglock)) @@ -3055,7 +3070,7 @@ xlog_state_release_iclog(  	if (iclog->ic_state & XLOG_STATE_IOERROR) {  		spin_unlock(&log->l_icloglock); -		return XFS_ERROR(EIO); +		return -EIO;  	}  	ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE ||  	       iclog->ic_state == XLOG_STATE_WANT_SYNC); @@ -3172,7 +3187,7 @@ _xfs_log_force(  	iclog = log->l_iclog;  	if (iclog->ic_state & XLOG_STATE_IOERROR) {  		spin_unlock(&log->l_icloglock); -		return XFS_ERROR(EIO); +		return -EIO;  	}  	/* If the head iclog is not active nor dirty, we just attach @@ -3210,7 +3225,7 @@ _xfs_log_force(  				spin_unlock(&log->l_icloglock);  				if (xlog_state_release_iclog(log, iclog)) -					return XFS_ERROR(EIO); +					return -EIO;  				if (log_flushed)  					*log_flushed = 1; @@ -3246,7 +3261,7 @@ maybe_sleep:  		 */  		if (iclog->ic_state & XLOG_STATE_IOERROR) {  			spin_unlock(&log->l_icloglock); -			return XFS_ERROR(EIO); +			return -EIO;  		}  		XFS_STATS_INC(xs_log_force_sleep);  		xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); @@ -3256,7 +3271,7 @@ maybe_sleep:  		 * and the memory read should be atomic.  		 */  		if (iclog->ic_state & XLOG_STATE_IOERROR) -			return XFS_ERROR(EIO); +			return -EIO;  		if (log_flushed)  			*log_flushed = 1;  	} else { @@ -3324,7 +3339,7 @@ try_again:  	iclog = log->l_iclog;  	if (iclog->ic_state & XLOG_STATE_IOERROR) {  		spin_unlock(&log->l_icloglock); -		return XFS_ERROR(EIO); +		return -EIO;  	}  	do { @@ -3375,7 +3390,7 @@ try_again:  			xlog_state_switch_iclogs(log, iclog, 0);  			spin_unlock(&log->l_icloglock);  			if (xlog_state_release_iclog(log, iclog)) -				return XFS_ERROR(EIO); +				return -EIO;  			if (log_flushed)  				*log_flushed = 1;  			spin_lock(&log->l_icloglock); @@ -3390,7 +3405,7 @@ try_again:  			 */  			if (iclog->ic_state & XLOG_STATE_IOERROR) {  				spin_unlock(&log->l_icloglock); -				return XFS_ERROR(EIO); +				return -EIO;  			}  			XFS_STATS_INC(xs_log_force_sleep);  			xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); @@ -3400,7 +3415,7 @@ try_again:  			 * and the memory read should be atomic.  			 */  			if (iclog->ic_state & XLOG_STATE_IOERROR) -				return XFS_ERROR(EIO); +				return -EIO;  			if (log_flushed)  				*log_flushed = 1; | 
