diff options
Diffstat (limited to 'fs/xfs/xfs_buf.c')
| -rw-r--r-- | fs/xfs/xfs_buf.c | 171 | 
1 files changed, 24 insertions, 147 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 548344e25128..ca0849043f54 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -4,24 +4,9 @@   * All Rights Reserved.   */  #include "xfs.h" -#include <linux/stddef.h> -#include <linux/errno.h> -#include <linux/gfp.h> -#include <linux/pagemap.h> -#include <linux/init.h> -#include <linux/vmalloc.h> -#include <linux/bio.h> -#include <linux/sysctl.h> -#include <linux/proc_fs.h> -#include <linux/workqueue.h> -#include <linux/percpu.h> -#include <linux/blkdev.h> -#include <linux/hash.h> -#include <linux/kthread.h> -#include <linux/migrate.h>  #include <linux/backing-dev.h> -#include <linux/freezer.h> +#include "xfs_shared.h"  #include "xfs_format.h"  #include "xfs_log_format.h"  #include "xfs_trans_resv.h" @@ -213,7 +198,7 @@ xfs_buf_free_maps(  	}  } -struct xfs_buf * +static struct xfs_buf *  _xfs_buf_alloc(  	struct xfs_buftarg	*target,  	struct xfs_buf_map	*map, @@ -243,6 +228,7 @@ _xfs_buf_alloc(  	sema_init(&bp->b_sema, 0); /* held, no waiters */  	spin_lock_init(&bp->b_lock);  	bp->b_target = target; +	bp->b_mount = target->bt_mount;  	bp->b_flags = flags;  	/* @@ -263,12 +249,11 @@ _xfs_buf_alloc(  		bp->b_maps[i].bm_len = map[i].bm_len;  		bp->b_length += map[i].bm_len;  	} -	bp->b_io_length = bp->b_length;  	atomic_set(&bp->b_pin_count, 0);  	init_waitqueue_head(&bp->b_waiters); -	XFS_STATS_INC(target->bt_mount, xb_create); +	XFS_STATS_INC(bp->b_mount, xb_create);  	trace_xfs_buf_init(bp, _RET_IP_);  	return bp; @@ -425,12 +410,12 @@ retry:  					current->comm, current->pid,  					__func__, gfp_mask); -			XFS_STATS_INC(bp->b_target->bt_mount, xb_page_retries); +			XFS_STATS_INC(bp->b_mount, xb_page_retries);  			congestion_wait(BLK_RW_ASYNC, HZ/50);  			goto retry;  		} -		XFS_STATS_INC(bp->b_target->bt_mount, xb_page_found); +		XFS_STATS_INC(bp->b_mount, xb_page_found);  		nbytes = min_t(size_t, size, PAGE_SIZE - offset);  		size -= nbytes; @@ -909,83 +894,6 @@ xfs_buf_read_uncached(  	return 0;  } -/* - * Return a buffer allocated as an empty buffer and associated to external - * memory via xfs_buf_associate_memory() back to it's empty state. - */ -void -xfs_buf_set_empty( -	struct xfs_buf		*bp, -	size_t			numblks) -{ -	if (bp->b_pages) -		_xfs_buf_free_pages(bp); - -	bp->b_pages = NULL; -	bp->b_page_count = 0; -	bp->b_addr = NULL; -	bp->b_length = numblks; -	bp->b_io_length = numblks; - -	ASSERT(bp->b_map_count == 1); -	bp->b_bn = XFS_BUF_DADDR_NULL; -	bp->b_maps[0].bm_bn = XFS_BUF_DADDR_NULL; -	bp->b_maps[0].bm_len = bp->b_length; -} - -static inline struct page * -mem_to_page( -	void			*addr) -{ -	if ((!is_vmalloc_addr(addr))) { -		return virt_to_page(addr); -	} else { -		return vmalloc_to_page(addr); -	} -} - -int -xfs_buf_associate_memory( -	xfs_buf_t		*bp, -	void			*mem, -	size_t			len) -{ -	int			rval; -	int			i = 0; -	unsigned long		pageaddr; -	unsigned long		offset; -	size_t			buflen; -	int			page_count; - -	pageaddr = (unsigned long)mem & PAGE_MASK; -	offset = (unsigned long)mem - pageaddr; -	buflen = PAGE_ALIGN(len + offset); -	page_count = buflen >> PAGE_SHIFT; - -	/* Free any previous set of page pointers */ -	if (bp->b_pages) -		_xfs_buf_free_pages(bp); - -	bp->b_pages = NULL; -	bp->b_addr = mem; - -	rval = _xfs_buf_get_pages(bp, page_count); -	if (rval) -		return rval; - -	bp->b_offset = offset; - -	for (i = 0; i < bp->b_page_count; i++) { -		bp->b_pages[i] = mem_to_page((void *)pageaddr); -		pageaddr += PAGE_SIZE; -	} - -	bp->b_io_length = BTOBB(len); -	bp->b_length = BTOBB(buflen); - -	return 0; -} -  xfs_buf_t *  xfs_buf_get_uncached(  	struct xfs_buftarg	*target, @@ -1180,7 +1088,7 @@ xfs_buf_lock(  	trace_xfs_buf_lock(bp, _RET_IP_);  	if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) -		xfs_log_force(bp->b_target->bt_mount, 0); +		xfs_log_force(bp->b_mount, 0);  	down(&bp->b_sema);  	trace_xfs_buf_lock_done(bp, _RET_IP_); @@ -1269,7 +1177,7 @@ xfs_buf_ioend_async(  	struct xfs_buf	*bp)  {  	INIT_WORK(&bp->b_ioend_work, xfs_buf_ioend_work); -	queue_work(bp->b_ioend_wq, &bp->b_ioend_work); +	queue_work(bp->b_mount->m_buf_workqueue, &bp->b_ioend_work);  }  void @@ -1288,7 +1196,7 @@ xfs_buf_ioerror_alert(  	struct xfs_buf		*bp,  	const char		*func)  { -	xfs_alert(bp->b_target->bt_mount, +	xfs_alert(bp->b_mount,  "metadata I/O error in \"%s\" at daddr 0x%llx len %d error %d",  			func, (uint64_t)XFS_BUF_ADDR(bp), bp->b_length,  			-bp->b_error); @@ -1307,10 +1215,8 @@ xfs_bwrite(  			 XBF_WRITE_FAIL | XBF_DONE);  	error = xfs_buf_submit(bp); -	if (error) { -		xfs_force_shutdown(bp->b_target->bt_mount, -				   SHUTDOWN_META_IO_ERROR); -	} +	if (error) +		xfs_force_shutdown(bp->b_mount, SHUTDOWN_META_IO_ERROR);  	return error;  } @@ -1436,21 +1342,8 @@ _xfs_buf_ioapply(  	 */  	bp->b_error = 0; -	/* -	 * Initialize the I/O completion workqueue if we haven't yet or the -	 * submitter has not opted to specify a custom one. -	 */ -	if (!bp->b_ioend_wq) -		bp->b_ioend_wq = bp->b_target->bt_mount->m_buf_workqueue; -  	if (bp->b_flags & XBF_WRITE) {  		op = REQ_OP_WRITE; -		if (bp->b_flags & XBF_SYNCIO) -			op_flags = REQ_SYNC; -		if (bp->b_flags & XBF_FUA) -			op_flags |= REQ_FUA; -		if (bp->b_flags & XBF_FLUSH) -			op_flags |= REQ_PREFLUSH;  		/*  		 * Run the write verifier callback function if it exists. If @@ -1460,12 +1353,12 @@ _xfs_buf_ioapply(  		if (bp->b_ops) {  			bp->b_ops->verify_write(bp);  			if (bp->b_error) { -				xfs_force_shutdown(bp->b_target->bt_mount, +				xfs_force_shutdown(bp->b_mount,  						   SHUTDOWN_CORRUPT_INCORE);  				return;  			}  		} else if (bp->b_bn != XFS_BUF_DADDR_NULL) { -			struct xfs_mount *mp = bp->b_target->bt_mount; +			struct xfs_mount *mp = bp->b_mount;  			/*  			 * non-crc filesystems don't attach verifiers during @@ -1497,7 +1390,7 @@ _xfs_buf_ioapply(  	 * subsequent call.  	 */  	offset = bp->b_offset; -	size = BBTOB(bp->b_io_length); +	size = BBTOB(bp->b_length);  	blk_start_plug(&plug);  	for (i = 0; i < bp->b_map_count; i++) {  		xfs_buf_ioapply_map(bp, i, &offset, &size, op, op_flags); @@ -1543,7 +1436,7 @@ __xfs_buf_submit(  	ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));  	/* on shutdown we stale and complete the buffer immediately */ -	if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { +	if (XFS_FORCED_SHUTDOWN(bp->b_mount)) {  		xfs_buf_ioerror(bp, -EIO);  		bp->b_flags &= ~XBF_DONE;  		xfs_buf_stale(bp); @@ -1613,16 +1506,11 @@ xfs_buf_offset(  	return page_address(page) + (offset & (PAGE_SIZE-1));  } -/* - *	Move data into or out of a buffer. - */  void -xfs_buf_iomove( -	xfs_buf_t		*bp,	/* buffer to process		*/ -	size_t			boff,	/* starting buffer offset	*/ -	size_t			bsize,	/* length to copy		*/ -	void			*data,	/* data address			*/ -	xfs_buf_rw_t		mode)	/* read/write/zero flag		*/ +xfs_buf_zero( +	struct xfs_buf		*bp, +	size_t			boff, +	size_t			bsize)  {  	size_t			bend; @@ -1635,23 +1523,13 @@ xfs_buf_iomove(  		page_offset = (boff + bp->b_offset) & ~PAGE_MASK;  		page = bp->b_pages[page_index];  		csize = min_t(size_t, PAGE_SIZE - page_offset, -				      BBTOB(bp->b_io_length) - boff); +				      BBTOB(bp->b_length) - boff);  		ASSERT((csize + page_offset) <= PAGE_SIZE); -		switch (mode) { -		case XBRW_ZERO: -			memset(page_address(page) + page_offset, 0, csize); -			break; -		case XBRW_READ: -			memcpy(data, page_address(page) + page_offset, csize); -			break; -		case XBRW_WRITE: -			memcpy(page_address(page) + page_offset, data, csize); -		} +		memset(page_address(page) + page_offset, 0, csize);  		boff += csize; -		data += csize;  	}  } @@ -2198,8 +2076,7 @@ void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref)  	 * This allows userspace to disrupt buffer caching for debug/testing  	 * purposes.  	 */ -	if (XFS_TEST_ERROR(false, bp->b_target->bt_mount, -			   XFS_ERRTAG_BUF_LRU_REF)) +	if (XFS_TEST_ERROR(false, bp->b_mount, XFS_ERRTAG_BUF_LRU_REF))  		lru_ref = 0;  	atomic_set(&bp->b_lru_ref, lru_ref); @@ -2215,7 +2092,7 @@ xfs_verify_magic(  	struct xfs_buf		*bp,  	__be32			dmagic)  { -	struct xfs_mount	*mp = bp->b_target->bt_mount; +	struct xfs_mount	*mp = bp->b_mount;  	int			idx;  	idx = xfs_sb_version_hascrc(&mp->m_sb); @@ -2233,7 +2110,7 @@ xfs_verify_magic16(  	struct xfs_buf		*bp,  	__be16			dmagic)  { -	struct xfs_mount	*mp = bp->b_target->bt_mount; +	struct xfs_mount	*mp = bp->b_mount;  	int			idx;  	idx = xfs_sb_version_hascrc(&mp->m_sb);  | 
