diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
| -rw-r--r-- | fs/xfs/xfs_log.c | 126 | 
1 files changed, 75 insertions, 51 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 6db1fef38bf..d90d4a38860 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -18,9 +18,7 @@  #include "xfs.h"  #include "xfs_fs.h"  #include "xfs_types.h" -#include "xfs_bit.h"  #include "xfs_log.h" -#include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" @@ -35,19 +33,26 @@  #include "xfs_trans_priv.h"  #include "xfs_dinode.h"  #include "xfs_inode.h" -#include "xfs_rw.h"  #include "xfs_trace.h"  kmem_zone_t	*xfs_log_ticket_zone;  /* Local miscellaneous function prototypes */ -STATIC int	 xlog_commit_record(struct log *log, struct xlog_ticket *ticket, -				    xlog_in_core_t **, xfs_lsn_t *); +STATIC int +xlog_commit_record( +	struct xlog		*log, +	struct xlog_ticket	*ticket, +	struct xlog_in_core	**iclog, +	xfs_lsn_t		*commitlsnp); +  STATIC xlog_t *  xlog_alloc_log(xfs_mount_t	*mp,  				xfs_buftarg_t	*log_target,  				xfs_daddr_t	blk_offset,  				int		num_bblks); -STATIC int	 xlog_space_left(struct log *log, atomic64_t *head); +STATIC int +xlog_space_left( +	struct xlog		*log, +	atomic64_t		*head);  STATIC int	 xlog_sync(xlog_t *log, xlog_in_core_t *iclog);  STATIC void	 xlog_dealloc_log(xlog_t *log); @@ -67,8 +72,10 @@ STATIC void xlog_state_switch_iclogs(xlog_t		*log,  				     int		eventual_size);  STATIC void xlog_state_want_sync(xlog_t	*log, xlog_in_core_t *iclog); -STATIC void xlog_grant_push_ail(struct log	*log, -				int		need_bytes); +STATIC void +xlog_grant_push_ail( +	struct xlog	*log, +	int		need_bytes);  STATIC void xlog_regrant_reserve_log_space(xlog_t	 *log,  					   xlog_ticket_t *ticket);  STATIC void xlog_ungrant_log_space(xlog_t	 *log, @@ -76,7 +83,9 @@ STATIC void xlog_ungrant_log_space(xlog_t	 *log,  #if defined(DEBUG)  STATIC void	xlog_verify_dest_ptr(xlog_t *log, char *ptr); -STATIC void	xlog_verify_grant_tail(struct log *log); +STATIC void +xlog_verify_grant_tail( +	struct xlog	*log);  STATIC void	xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,  				  int count, boolean_t syncing);  STATIC void	xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, @@ -92,9 +101,9 @@ STATIC int	xlog_iclogs_empty(xlog_t *log);  static void  xlog_grant_sub_space( -	struct log	*log, -	atomic64_t	*head, -	int		bytes) +	struct xlog		*log, +	atomic64_t		*head, +	int			bytes)  {  	int64_t	head_val = atomic64_read(head);  	int64_t new, old; @@ -118,9 +127,9 @@ xlog_grant_sub_space(  static void  xlog_grant_add_space( -	struct log	*log, -	atomic64_t	*head, -	int		bytes) +	struct xlog		*log, +	atomic64_t		*head, +	int			bytes)  {  	int64_t	head_val = atomic64_read(head);  	int64_t new, old; @@ -168,7 +177,7 @@ xlog_grant_head_wake_all(  static inline int  xlog_ticket_reservation( -	struct log		*log, +	struct xlog		*log,  	struct xlog_grant_head	*head,  	struct xlog_ticket	*tic)  { @@ -185,7 +194,7 @@ xlog_ticket_reservation(  STATIC bool  xlog_grant_head_wake( -	struct log		*log, +	struct xlog		*log,  	struct xlog_grant_head	*head,  	int			*free_bytes)  { @@ -207,7 +216,7 @@ xlog_grant_head_wake(  STATIC int  xlog_grant_head_wait( -	struct log		*log, +	struct xlog		*log,  	struct xlog_grant_head	*head,  	struct xlog_ticket	*tic,  	int			need_bytes) @@ -259,7 +268,7 @@ shutdown:   */  STATIC int  xlog_grant_head_check( -	struct log		*log, +	struct xlog		*log,  	struct xlog_grant_head	*head,  	struct xlog_ticket	*tic,  	int			*need_bytes) @@ -326,7 +335,7 @@ xfs_log_regrant(  	struct xfs_mount	*mp,  	struct xlog_ticket	*tic)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	int			need_bytes;  	int			error = 0; @@ -392,7 +401,7 @@ xfs_log_reserve(  	bool			permanent,  	uint		 	t_type)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	struct xlog_ticket	*tic;  	int			need_bytes;  	int			error = 0; @@ -468,7 +477,7 @@ xfs_log_done(  	struct xlog_in_core	**iclog,  	uint			flags)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	xfs_lsn_t		lsn = 0;  	if (XLOG_FORCED_SHUTDOWN(log) || @@ -813,6 +822,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)  void  xfs_log_unmount(xfs_mount_t *mp)  { +	cancel_delayed_work_sync(&mp->m_sync_work);  	xfs_trans_ail_destroy(mp);  	xlog_dealloc_log(mp->m_log);  } @@ -841,7 +851,7 @@ void  xfs_log_space_wake(  	struct xfs_mount	*mp)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	int			free_bytes;  	if (XLOG_FORCED_SHUTDOWN(log)) @@ -916,27 +926,42 @@ xfs_log_need_covered(xfs_mount_t *mp)   * We may be holding the log iclog lock upon entering this routine.   */  xfs_lsn_t -xlog_assign_tail_lsn( +xlog_assign_tail_lsn_locked(  	struct xfs_mount	*mp)  { +	struct xlog		*log = mp->m_log; +	struct xfs_log_item	*lip;  	xfs_lsn_t		tail_lsn; -	struct log		*log = mp->m_log; + +	assert_spin_locked(&mp->m_ail->xa_lock);  	/*  	 * To make sure we always have a valid LSN for the log tail we keep  	 * track of the last LSN which was committed in log->l_last_sync_lsn, -	 * and use that when the AIL was empty and xfs_ail_min_lsn returns 0. -	 * -	 * If the AIL has been emptied we also need to wake any process -	 * waiting for this condition. +	 * and use that when the AIL was empty.  	 */ -	tail_lsn = xfs_ail_min_lsn(mp->m_ail); -	if (!tail_lsn) +	lip = xfs_ail_min(mp->m_ail); +	if (lip) +		tail_lsn = lip->li_lsn; +	else  		tail_lsn = atomic64_read(&log->l_last_sync_lsn);  	atomic64_set(&log->l_tail_lsn, tail_lsn);  	return tail_lsn;  } +xfs_lsn_t +xlog_assign_tail_lsn( +	struct xfs_mount	*mp) +{ +	xfs_lsn_t		tail_lsn; + +	spin_lock(&mp->m_ail->xa_lock); +	tail_lsn = xlog_assign_tail_lsn_locked(mp); +	spin_unlock(&mp->m_ail->xa_lock); + +	return tail_lsn; +} +  /*   * Return the space in the log between the tail and the head.  The head   * is passed in the cycle/bytes formal parms.  In the special case where @@ -953,7 +978,7 @@ xlog_assign_tail_lsn(   */  STATIC int  xlog_space_left( -	struct log	*log, +	struct xlog	*log,  	atomic64_t	*head)  {  	int		free_bytes; @@ -1172,7 +1197,7 @@ xlog_alloc_log(xfs_mount_t	*mp,  	xlog_get_iclog_buffer_size(mp, log);  	error = ENOMEM; -	bp = xfs_buf_alloc(mp->m_logdev_targp, 0, log->l_iclog_size, 0); +	bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0);  	if (!bp)  		goto out_free_log;  	bp->b_iodone = xlog_iodone; @@ -1182,9 +1207,6 @@ xlog_alloc_log(xfs_mount_t	*mp,  	spin_lock_init(&log->l_icloglock);  	init_waitqueue_head(&log->l_flush_wait); -	/* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ -	ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); -  	iclogp = &log->l_iclog;  	/*  	 * The amount of memory to allocate for the iclog structure is @@ -1204,7 +1226,7 @@ xlog_alloc_log(xfs_mount_t	*mp,  		prev_iclog = iclog;  		bp = xfs_buf_get_uncached(mp->m_logdev_targp, -						log->l_iclog_size, 0); +						BTOBB(log->l_iclog_size), 0);  		if (!bp)  			goto out_free_iclog; @@ -1224,7 +1246,7 @@ xlog_alloc_log(xfs_mount_t	*mp,  		head->h_fmt = cpu_to_be32(XLOG_FMT);  		memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); -		iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize; +		iclog->ic_size = BBTOB(bp->b_length) - log->l_iclog_hsize;  		iclog->ic_state = XLOG_STATE_ACTIVE;  		iclog->ic_log = log;  		atomic_set(&iclog->ic_refcnt, 0); @@ -1268,7 +1290,7 @@ out:   */  STATIC int  xlog_commit_record( -	struct log		*log, +	struct xlog		*log,  	struct xlog_ticket	*ticket,  	struct xlog_in_core	**iclog,  	xfs_lsn_t		*commitlsnp) @@ -1302,7 +1324,7 @@ xlog_commit_record(   */  STATIC void  xlog_grant_push_ail( -	struct log	*log, +	struct xlog	*log,  	int		need_bytes)  {  	xfs_lsn_t	threshold_lsn = 0; @@ -1475,7 +1497,7 @@ xlog_sync(xlog_t		*log,  	} else {  		iclog->ic_bwritecnt = 1;  	} -	XFS_BUF_SET_COUNT(bp, count); +	bp->b_io_length = BTOBB(count);  	bp->b_fspriv = iclog;  	XFS_BUF_ZEROFLAGS(bp);  	XFS_BUF_ASYNC(bp); @@ -1573,7 +1595,7 @@ xlog_dealloc_log(xlog_t *log)  	 * always need to ensure that the extra buffer does not point to memory  	 * owned by another log buffer before we free it.  	 */ -	xfs_buf_set_empty(log->l_xbuf, log->l_iclog_size); +	xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size));  	xfs_buf_free(log->l_xbuf);  	iclog = log->l_iclog; @@ -1781,7 +1803,7 @@ xlog_write_start_rec(  static xlog_op_header_t *  xlog_write_setup_ophdr( -	struct log		*log, +	struct xlog		*log,  	struct xlog_op_header	*ophdr,  	struct xlog_ticket	*ticket,  	uint			flags) @@ -1864,7 +1886,7 @@ xlog_write_setup_copy(  static int  xlog_write_copy_finish( -	struct log		*log, +	struct xlog		*log,  	struct xlog_in_core	*iclog,  	uint			flags,  	int			*record_cnt, @@ -1949,7 +1971,7 @@ xlog_write_copy_finish(   */  int  xlog_write( -	struct log		*log, +	struct xlog		*log,  	struct xfs_log_vec	*log_vector,  	struct xlog_ticket	*ticket,  	xfs_lsn_t		*start_lsn, @@ -2812,7 +2834,7 @@ _xfs_log_force(  	uint			flags,  	int			*log_flushed)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	struct xlog_in_core	*iclog;  	xfs_lsn_t		lsn; @@ -2932,6 +2954,7 @@ xfs_log_force(  {  	int	error; +	trace_xfs_log_force(mp, 0);  	error = _xfs_log_force(mp, flags, NULL);  	if (error)  		xfs_warn(mp, "%s: error %d returned.", __func__, error); @@ -2959,7 +2982,7 @@ _xfs_log_force_lsn(  	uint			flags,  	int			*log_flushed)  { -	struct log		*log = mp->m_log; +	struct xlog		*log = mp->m_log;  	struct xlog_in_core	*iclog;  	int			already_slept = 0; @@ -3080,6 +3103,7 @@ xfs_log_force_lsn(  {  	int	error; +	trace_xfs_log_force(mp, lsn);  	error = _xfs_log_force_lsn(mp, lsn, flags, NULL);  	if (error)  		xfs_warn(mp, "%s: error %d returned.", __func__, error); @@ -3136,12 +3160,12 @@ xfs_log_ticket_get(   */  xlog_ticket_t *  xlog_ticket_alloc( -	struct log	*log, +	struct xlog	*log,  	int		unit_bytes,  	int		cnt,  	char		client,  	bool		permanent, -	int		alloc_flags) +	xfs_km_flags_t	alloc_flags)  {  	struct xlog_ticket *tic;  	uint		num_headers; @@ -3267,7 +3291,7 @@ xlog_ticket_alloc(   */  void  xlog_verify_dest_ptr( -	struct log	*log, +	struct xlog	*log,  	char		*ptr)  {  	int i; @@ -3296,7 +3320,7 @@ xlog_verify_dest_ptr(   */  STATIC void  xlog_verify_grant_tail( -	struct log	*log) +	struct xlog	*log)  {  	int		tail_cycle, tail_blocks;  	int		cycle, space;  | 
