diff options
Diffstat (limited to 'fs/xfs')
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.h | 2 | ||||
| -rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 4 | ||||
| -rw-r--r-- | fs/xfs/quota/xfs_qm.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr.c | 12 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 363 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap.h | 22 | ||||
| -rw-r--r-- | fs/xfs/xfs_da_btree.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 74 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.h | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.c | 11 | ||||
| -rw-r--r-- | fs/xfs/xfs_iocore.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 24 | ||||
| -rw-r--r-- | fs/xfs/xfs_mount.h | 23 | ||||
| -rw-r--r-- | fs/xfs/xfs_rtalloc.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 34 | 
19 files changed, 437 insertions, 166 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 67efe330898..67b5e1c20de 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -458,7 +458,7 @@ xfs_zero_last_block(  	last_fsb = XFS_B_TO_FSBT(mp, isize);  	nimaps = 1;  	error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, -			  &nimaps, NULL); +			  &nimaps, NULL, NULL);  	if (error) {  		return error;  	} @@ -556,7 +556,7 @@ xfs_zero_eof(  		nimaps = 1;  		zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;  		error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, -				  0, NULL, 0, &imap, &nimaps, NULL); +				  0, NULL, 0, &imap, &nimaps, NULL, NULL);  		if (error) {  			ASSERT(ismrlocked(io->io_lock, MR_UPDATE));  			ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index 8f453995235..dc49050688c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h @@ -49,7 +49,7 @@ struct xfs_iomap;  #define	XFS_CTRUNC4		14  #define	XFS_CTRUNC5		15  #define	XFS_CTRUNC6		16 -#define	XFS_BUNMAPI		17 +#define	XFS_BUNMAP		17  #define	XFS_INVAL_CACHED	18  #define	XFS_DIORD_ENTER		19  #define	XFS_DIOWR_ENTER		20 diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 772ac48329e..26ee5df4f83 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -444,7 +444,7 @@ xfs_qm_dqalloc(  			      XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,  			      &firstblock,  			      XFS_QM_DQALLOC_SPACE_RES(mp), -			      &map, &nmaps, &flist))) { +			      &map, &nmaps, &flist, NULL))) {  		goto error0;  	}  	ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); @@ -559,7 +559,7 @@ xfs_qm_dqtobp(  		error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,  				  XFS_DQUOT_CLUSTER_SIZE_FSB,  				  XFS_BMAPI_METADATA, -				  NULL, 0, &map, &nmaps, NULL); +				  NULL, 0, &map, &nmaps, NULL, NULL);  		xfs_iunlock(quotip, XFS_ILOCK_SHARED);  		if (error) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 7fb5eca9bd5..492840b2a35 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1603,7 +1603,7 @@ xfs_qm_dqiterate(  				  maxlblkcnt - lblkno,  				  XFS_BMAPI_METADATA,  				  NULL, -				  0, map, &nmaps, NULL); +				  0, map, &nmaps, NULL, NULL);  		xfs_iunlock(qip, XFS_ILOCK_SHARED);  		if (error)  			break; diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index b6e1e02bbb2..3ef41e75d08 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -1910,7 +1910,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)  		error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,  				  args->rmtblkcnt,  				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -				  NULL, 0, map, &nmap, NULL); +				  NULL, 0, map, &nmap, NULL, NULL);  		if (error)  			return(error);  		ASSERT(nmap >= 1); @@ -1988,7 +1988,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)  				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |  							XFS_BMAPI_WRITE,  				  args->firstblock, args->total, &map, &nmap, -				  args->flist); +				  args->flist, NULL);  		if (!error) {  			error = xfs_bmap_finish(&args->trans, args->flist,  						*args->firstblock, &committed); @@ -2039,7 +2039,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)  		error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,  				  args->rmtblkcnt,  				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -				  args->firstblock, 0, &map, &nmap, NULL); +				  args->firstblock, 0, &map, &nmap, +				  NULL, NULL);  		if (error) {  			return(error);  		} @@ -2104,7 +2105,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)  					args->rmtblkcnt,  					XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,  					args->firstblock, 0, &map, &nmap, -					args->flist); +					args->flist, NULL);  		if (error) {  			return(error);  		} @@ -2142,7 +2143,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)  		XFS_BMAP_INIT(args->flist, args->firstblock);  		error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,  				    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -				    1, args->firstblock, args->flist, &done); +				    1, args->firstblock, args->flist, +				    NULL, &done);  		if (!error) {  			error = xfs_bmap_finish(&args->trans, args->flist,  						*args->firstblock, &committed); diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 9462be86aa1..5c44343d4a3 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -2990,7 +2990,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,  		nmap = 1;  		error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,  					XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -					NULL, 0, &map, &nmap, NULL); +					NULL, 0, &map, &nmap, NULL, NULL);  		if (error) {  			return(error);  		} diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 26939d364bc..890ad352817 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -101,6 +101,7 @@ xfs_bmap_add_extent(  	xfs_fsblock_t		*first,	/* pointer to firstblock variable */  	xfs_bmap_free_t		*flist,	/* list of extents to be freed */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork, /* data or attr fork */  	int			rsvd);	/* OK to allocate reserved blocks */ @@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(  	xfs_fsblock_t		*first,	/* pointer to firstblock variable */  	xfs_bmap_free_t		*flist,	/* list of extents to be freed */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			rsvd);	/* OK to allocate reserved blocks */  /* @@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp,/* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			rsvd);	/* OK to allocate reserved blocks */  /* @@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork); /* data or attr fork */  /* @@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(  	xfs_extnum_t		idx,	/* extent number to update/insert */  	xfs_btree_cur_t		**curp,	/* if *curp is null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */ -	int			*logflagsp); /* inode logging flags */ +	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta); /* Change made to incore extents */  /*   * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. @@ -203,6 +208,7 @@ xfs_bmap_del_extent(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp,/* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork, /* data or attr fork */  	int			rsvd);	 /* OK to allocate reserved blocks */ @@ -530,6 +536,7 @@ xfs_bmap_add_extent(  	xfs_fsblock_t		*first,	/* pointer to firstblock variable */  	xfs_bmap_free_t		*flist,	/* list of extents to be freed */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork, /* data or attr fork */  	int			rsvd)	/* OK to use reserved data blocks */  { @@ -567,6 +574,15 @@ xfs_bmap_add_extent(  			logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);  		} else  			logflags = 0; +		/* DELTA: single new extent */ +		if (delta) { +			if (delta->xed_startoff > new->br_startoff) +				delta->xed_startoff = new->br_startoff; +			if (delta->xed_blockcount < +					new->br_startoff + new->br_blockcount) +				delta->xed_blockcount = new->br_startoff + +						new->br_blockcount; +		}  	}  	/*  	 * Any kind of new delayed allocation goes here. @@ -576,7 +592,7 @@ xfs_bmap_add_extent(  			ASSERT((cur->bc_private.b.flags &  				XFS_BTCUR_BPRV_WASDEL) == 0);  		if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, -				&logflags, rsvd))) +				&logflags, delta, rsvd)))  			goto done;  	}  	/* @@ -587,7 +603,7 @@ xfs_bmap_add_extent(  			ASSERT((cur->bc_private.b.flags &  				XFS_BTCUR_BPRV_WASDEL) == 0);  		if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, -				&logflags, whichfork))) +				&logflags, delta, whichfork)))  			goto done;  	} else {  		xfs_bmbt_irec_t	prev;	/* old extent at offset idx */ @@ -612,17 +628,17 @@ xfs_bmap_add_extent(  						XFS_BTCUR_BPRV_WASDEL);  				if ((error = xfs_bmap_add_extent_delay_real(ip,  					idx, &cur, new, &da_new, first, flist, -					&logflags, rsvd))) +					&logflags, delta, rsvd)))  					goto done;  			} else if (new->br_state == XFS_EXT_NORM) {  				ASSERT(new->br_state == XFS_EXT_NORM);  				if ((error = xfs_bmap_add_extent_unwritten_real( -					ip, idx, &cur, new, &logflags))) +					ip, idx, &cur, new, &logflags, delta)))  					goto done;  			} else {  				ASSERT(new->br_state == XFS_EXT_UNWRITTEN);  				if ((error = xfs_bmap_add_extent_unwritten_real( -					ip, idx, &cur, new, &logflags))) +					ip, idx, &cur, new, &logflags, delta)))  					goto done;  			}  			ASSERT(*curp == cur || *curp == NULL); @@ -635,7 +651,7 @@ xfs_bmap_add_extent(  				ASSERT((cur->bc_private.b.flags &  					XFS_BTCUR_BPRV_WASDEL) == 0);  			if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, -					new, &logflags, whichfork))) +					new, &logflags, delta, whichfork)))  				goto done;  		}  	} @@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(  	xfs_fsblock_t		*first,	/* pointer to firstblock variable */  	xfs_bmap_free_t		*flist,	/* list of extents to be freed */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			rsvd)	/* OK to use reserved data block allocation */  {  	xfs_btree_cur_t		*cur;	/* btree cursor */ @@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(  					/* left is 0, right is 1, prev is 2 */  	int			rval=0;	/* return value (logging flags) */  	int			state = 0;/* state bits, accessed thru macros */ -	xfs_filblks_t		temp;	/* value for dnew calculations */ -	xfs_filblks_t		temp2;	/* value for dnew calculations */ +	xfs_filblks_t		temp=0;	/* value for dnew calculations */ +	xfs_filblks_t		temp2=0;/* value for dnew calculations */  	int			tmp_rval;	/* partial logging flags */  	enum {				/* bit number definitions for state */  		LEFT_CONTIG,	RIGHT_CONTIG, @@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(  				goto done;  		}  		*dnew = 0; +		/* DELTA: Three in-core extents are replaced by one. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): @@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(  				goto done;  		}  		*dnew = 0; +		/* DELTA: Two in-core extents are replaced by one. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): @@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(  				goto done;  		}  		*dnew = 0; +		/* DELTA: Two in-core extents are replaced by one. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK2(LEFT_FILLING, RIGHT_FILLING): @@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(  			ASSERT(i == 1);  		}  		*dnew = 0; +		/* DELTA: The in-core extent described by new changed type. */ +		temp = new->br_startoff; +		temp2 = new->br_blockcount;  		break;  	case MASK2(LEFT_FILLING, LEFT_CONTIG): @@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(  		xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,  			XFS_DATA_FORK);  		*dnew = temp; +		/* DELTA: The boundary between two in-core extents moved. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount;  		break;  	case MASK(LEFT_FILLING): @@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(  		xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,  			XFS_DATA_FORK);  		*dnew = temp; +		/* DELTA: One in-core extent is split in two. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case MASK2(RIGHT_FILLING, RIGHT_CONTIG): @@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(  		xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,  			XFS_DATA_FORK);  		*dnew = temp; +		/* DELTA: The boundary between two in-core extents moved. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK(RIGHT_FILLING): @@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(  		xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));  		xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);  		*dnew = temp; +		/* DELTA: One in-core extent is split in two. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case 0: @@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(  		xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,  			XFS_DATA_FORK);  		*dnew = temp + temp2; +		/* DELTA: One in-core extent is split in three. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): @@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(  		ASSERT(0);  	}  	*curp = cur; +	if (delta) { +		temp2 += temp; +		if (delta->xed_startoff > temp) +			delta->xed_startoff = temp; +		if (delta->xed_blockcount < temp2) +			delta->xed_blockcount = temp2; +	}  done:  	*logflagsp = rval;  	return error; @@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(  	xfs_extnum_t		idx,	/* extent number to update/insert */  	xfs_btree_cur_t		**curp,	/* if *curp is null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */ -	int			*logflagsp) /* inode logging flags */ +	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta) /* Change made to incore extents */  {  	xfs_btree_cur_t		*cur;	/* btree cursor */  	xfs_bmbt_rec_t		*ep;	/* extent entry for idx */ @@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(  					/* left is 0, right is 1, prev is 2 */  	int			rval=0;	/* return value (logging flags) */  	int			state = 0;/* state bits, accessed thru macros */ +	xfs_filblks_t		temp=0; +	xfs_filblks_t		temp2=0;  	enum {				/* bit number definitions for state */  		LEFT_CONTIG,	RIGHT_CONTIG,  		LEFT_FILLING,	RIGHT_FILLING, @@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(  				RIGHT.br_blockcount, LEFT.br_state)))  				goto done;  		} +		/* DELTA: Three in-core extents are replaced by one. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): @@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(  				LEFT.br_state)))  				goto done;  		} +		/* DELTA: Two in-core extents are replaced by one. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): @@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(  				newext)))  				goto done;  		} +		/* DELTA: Two in-core extents are replaced by one. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK2(LEFT_FILLING, RIGHT_FILLING): @@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(  				newext)))  				goto done;  		} +		/* DELTA: The in-core extent described by new changed type. */ +		temp = new->br_startoff; +		temp2 = new->br_blockcount;  		break;  	case MASK2(LEFT_FILLING, LEFT_CONTIG): @@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(  				LEFT.br_state))  				goto done;  		} +		/* DELTA: The boundary between two in-core extents moved. */ +		temp = LEFT.br_startoff; +		temp2 = LEFT.br_blockcount + +			PREV.br_blockcount;  		break;  	case MASK(LEFT_FILLING): @@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(  				goto done;  			ASSERT(i == 1);  		} +		/* DELTA: One in-core extent is split in two. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case MASK2(RIGHT_FILLING, RIGHT_CONTIG): @@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(  				newext)))  				goto done;  		} +		/* DELTA: The boundary between two in-core extents moved. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount + +			RIGHT.br_blockcount;  		break;  	case MASK(RIGHT_FILLING): @@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(  				goto done;  			ASSERT(i == 1);  		} +		/* DELTA: One in-core extent is split in two. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case 0: @@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(  				goto done;  			ASSERT(i == 1);  		} +		/* DELTA: One in-core extent is split in three. */ +		temp = PREV.br_startoff; +		temp2 = PREV.br_blockcount;  		break;  	case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): @@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(  		ASSERT(0);  	}  	*curp = cur; +	if (delta) { +		temp2 += temp; +		if (delta->xed_startoff > temp) +			delta->xed_startoff = temp; +		if (delta->xed_blockcount < temp2) +			delta->xed_blockcount = temp2; +	}  done:  	*logflagsp = rval;  	return error; @@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			rsvd)		/* OK to allocate reserved blocks */  {  	xfs_bmbt_rec_t		*ep;	/* extent record for idx */ @@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(  	xfs_filblks_t		oldlen=0;	/* old indirect size */  	xfs_bmbt_irec_t		right;	/* right neighbor extent entry */  	int			state;  /* state bits, accessed thru macros */ -	xfs_filblks_t		temp;	/* temp for indirect calculations */ +	xfs_filblks_t		temp=0;	/* temp for indirect calculations */ +	xfs_filblks_t		temp2=0;  	enum {				/* bit number definitions for state */  		LEFT_CONTIG,	RIGHT_CONTIG,  		LEFT_DELAY,	RIGHT_DELAY, @@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(  			XFS_DATA_FORK);  		xfs_iext_remove(ifp, idx, 1);  		ip->i_df.if_lastex = idx - 1; +		/* DELTA: Two in-core extents were replaced by one. */ +		temp2 = temp; +		temp = left.br_startoff;  		break;  	case MASK(LEFT_CONTIG): @@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(  		xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,  			XFS_DATA_FORK);  		ip->i_df.if_lastex = idx - 1; +		/* DELTA: One in-core extent grew into a hole. */ +		temp2 = temp; +		temp = left.br_startoff;  		break;  	case MASK(RIGHT_CONTIG): @@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(  			NULLSTARTBLOCK((int)newlen), temp, right.br_state);  		xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);  		ip->i_df.if_lastex = idx; +		/* DELTA: One in-core extent grew into a hole. */ +		temp2 = temp; +		temp = new->br_startoff;  		break;  	case 0: @@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(  			XFS_DATA_FORK);  		xfs_iext_insert(ifp, idx, 1, new);  		ip->i_df.if_lastex = idx; +		/* DELTA: A new in-core extent was added in a hole. */ +		temp2 = new->br_blockcount; +		temp = new->br_startoff;  		break;  	}  	if (oldlen != newlen) { @@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(  		 * Nothing to do for disk quota accounting here.  		 */  	} +	if (delta) { +		temp2 += temp; +		if (delta->xed_startoff > temp) +			delta->xed_startoff = temp; +		if (delta->xed_blockcount < temp2) +			delta->xed_blockcount = temp2; +	}  	*logflagsp = 0;  	return 0;  #undef	MASK @@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork) /* data or attr fork */  {  	xfs_bmbt_rec_t		*ep;	/* pointer to extent entry ins. point */ @@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(  	xfs_ifork_t		*ifp;	/* inode fork pointer */  	xfs_bmbt_irec_t		left;	/* left neighbor extent entry */  	xfs_bmbt_irec_t		right;	/* right neighbor extent entry */ +	int			rval=0;	/* return value (logging flags) */  	int			state;	/* state bits, accessed thru macros */ +	xfs_filblks_t		temp=0; +	xfs_filblks_t		temp2=0;  	enum {				/* bit number definitions for state */  		LEFT_CONTIG,	RIGHT_CONTIG,  		LEFT_DELAY,	RIGHT_DELAY, @@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(  		 left.br_blockcount + new->br_blockcount +  		     right.br_blockcount <= MAXEXTLEN)); +	error = 0;  	/*  	 * Select which case we're in here, and implement it.  	 */ @@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(  		XFS_IFORK_NEXT_SET(ip, whichfork,  			XFS_IFORK_NEXTENTS(ip, whichfork) - 1);  		if (cur == NULL) { -			*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); -			return 0; +			rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); +		} else { +			rval = XFS_ILOG_CORE; +			if ((error = xfs_bmbt_lookup_eq(cur, +					right.br_startoff, +					right.br_startblock, +					right.br_blockcount, &i))) +				goto done; +			ASSERT(i == 1); +			if ((error = xfs_bmbt_delete(cur, &i))) +				goto done; +			ASSERT(i == 1); +			if ((error = xfs_bmbt_decrement(cur, 0, &i))) +				goto done; +			ASSERT(i == 1); +			if ((error = xfs_bmbt_update(cur, left.br_startoff, +					left.br_startblock, +					left.br_blockcount + +						new->br_blockcount + +						right.br_blockcount, +					left.br_state))) +				goto done;  		} -		*logflagsp = XFS_ILOG_CORE; -		if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, -				right.br_startblock, right.br_blockcount, &i))) -			return error; -		ASSERT(i == 1); -		if ((error = xfs_bmbt_delete(cur, &i))) -			return error; -		ASSERT(i == 1); -		if ((error = xfs_bmbt_decrement(cur, 0, &i))) -			return error; -		ASSERT(i == 1); -		error = xfs_bmbt_update(cur, left.br_startoff, -				left.br_startblock, -				left.br_blockcount + new->br_blockcount + -				right.br_blockcount, left.br_state); -		return error; +		/* DELTA: Two in-core extents were replaced by one. */ +		temp = left.br_startoff; +		temp2 = left.br_blockcount + +			new->br_blockcount + +			right.br_blockcount; +		break;  	case MASK(LEFT_CONTIG):  		/* @@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(  		xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);  		ifp->if_lastex = idx - 1;  		if (cur == NULL) { -			*logflagsp = XFS_ILOG_FEXT(whichfork); -			return 0; +			rval = XFS_ILOG_FEXT(whichfork); +		} else { +			rval = 0; +			if ((error = xfs_bmbt_lookup_eq(cur, +					left.br_startoff, +					left.br_startblock, +					left.br_blockcount, &i))) +				goto done; +			ASSERT(i == 1); +			if ((error = xfs_bmbt_update(cur, left.br_startoff, +					left.br_startblock, +					left.br_blockcount + +						new->br_blockcount, +					left.br_state))) +				goto done;  		} -		*logflagsp = 0; -		if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, -				left.br_startblock, left.br_blockcount, &i))) -			return error; -		ASSERT(i == 1); -		error = xfs_bmbt_update(cur, left.br_startoff, -				left.br_startblock, -				left.br_blockcount + new->br_blockcount, -				left.br_state); -		return error; +		/* DELTA: One in-core extent grew. */ +		temp = left.br_startoff; +		temp2 = left.br_blockcount + +			new->br_blockcount; +		break;  	case MASK(RIGHT_CONTIG):  		/* @@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(  		xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);  		ifp->if_lastex = idx;  		if (cur == NULL) { -			*logflagsp = XFS_ILOG_FEXT(whichfork); -			return 0; +			rval = XFS_ILOG_FEXT(whichfork); +		} else { +			rval = 0; +			if ((error = xfs_bmbt_lookup_eq(cur, +					right.br_startoff, +					right.br_startblock, +					right.br_blockcount, &i))) +				goto done; +			ASSERT(i == 1); +			if ((error = xfs_bmbt_update(cur, new->br_startoff, +					new->br_startblock, +					new->br_blockcount + +						right.br_blockcount, +					right.br_state))) +				goto done;  		} -		*logflagsp = 0; -		if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, -				right.br_startblock, right.br_blockcount, &i))) -			return error; -		ASSERT(i == 1); -		error = xfs_bmbt_update(cur, new->br_startoff, -				new->br_startblock, -				new->br_blockcount + right.br_blockcount, -				right.br_state); -		return error; +		/* DELTA: One in-core extent grew. */ +		temp = new->br_startoff; +		temp2 = new->br_blockcount + +			right.br_blockcount; +		break;  	case 0:  		/* @@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(  		XFS_IFORK_NEXT_SET(ip, whichfork,  			XFS_IFORK_NEXTENTS(ip, whichfork) + 1);  		if (cur == NULL) { -			*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); -			return 0; +			rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); +		} else { +			rval = XFS_ILOG_CORE; +			if ((error = xfs_bmbt_lookup_eq(cur, +					new->br_startoff, +					new->br_startblock, +					new->br_blockcount, &i))) +				goto done; +			ASSERT(i == 0); +			cur->bc_rec.b.br_state = new->br_state; +			if ((error = xfs_bmbt_insert(cur, &i))) +				goto done; +			ASSERT(i == 1);  		} -		*logflagsp = XFS_ILOG_CORE; -		if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, -				new->br_startblock, new->br_blockcount, &i))) -			return error; -		ASSERT(i == 0); -		cur->bc_rec.b.br_state = new->br_state; -		if ((error = xfs_bmbt_insert(cur, &i))) -			return error; -		ASSERT(i == 1); -		return 0; +		/* DELTA: A new extent was added in a hole. */ +		temp = new->br_startoff; +		temp2 = new->br_blockcount; +		break;  	} +	if (delta) { +		temp2 += temp; +		if (delta->xed_startoff > temp) +			delta->xed_startoff = temp; +		if (delta->xed_blockcount < temp2) +			delta->xed_blockcount = temp2; +	} +done: +	*logflagsp = rval; +	return error;  #undef	MASK  #undef	MASK2  #undef	STATE_SET  #undef	STATE_TEST  #undef	STATE_SET_TEST  #undef	SWITCH_STATE -	/* NOTREACHED */ -	ASSERT(0); -	return 0; /* keep gcc quite */  }  /* @@ -2885,6 +3049,7 @@ xfs_bmap_del_extent(  	xfs_btree_cur_t		*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*del,	/* data to remove from extents */  	int			*logflagsp, /* inode logging flags */ +	xfs_extdelta_t		*delta, /* Change made to incore extents */  	int			whichfork, /* data or attr fork */  	int			rsvd)	/* OK to allocate reserved blocks */  { @@ -3193,6 +3358,14 @@ xfs_bmap_del_extent(  	if (da_old > da_new)  		xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),  			rsvd); +	if (delta) { +		/* DELTA: report the original extent. */ +		if (delta->xed_startoff > got.br_startoff) +			delta->xed_startoff = got.br_startoff; +		if (delta->xed_blockcount < got.br_startoff+got.br_blockcount) +			delta->xed_blockcount = got.br_startoff + +							got.br_blockcount; +	}  done:  	*logflagsp = flags;  	return error; @@ -3753,7 +3926,7 @@ xfs_bunmap_trace(  	if (ip->i_rwtrace == NULL)  		return;  	ktrace_enter(ip->i_rwtrace, -		(void *)(__psint_t)XFS_BUNMAPI, +		(void *)(__psint_t)XFS_BUNMAP,  		(void *)ip,  		(void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),  		(void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), @@ -4538,7 +4711,8 @@ xfs_bmapi(  	xfs_extlen_t	total,		/* total blocks needed */  	xfs_bmbt_irec_t	*mval,		/* output: map values */  	int		*nmap,		/* i/o: mval size/count */ -	xfs_bmap_free_t	*flist)		/* i/o: list extents to free */ +	xfs_bmap_free_t	*flist,		/* i/o: list extents to free */ +	xfs_extdelta_t	*delta)		/* o: change made to incore extents */  {  	xfs_fsblock_t	abno;		/* allocated block number */  	xfs_extlen_t	alen;		/* allocated extent length */ @@ -4650,6 +4824,10 @@ xfs_bmapi(  	end = bno + len;  	obno = bno;  	bma.ip = NULL; +	if (delta) { +		delta->xed_startoff = NULLFILEOFF; +		delta->xed_blockcount = 0; +	}  	while (bno < end && n < *nmap) {  		/*  		 * Reading past eof, act as though there's a hole @@ -4886,8 +5064,8 @@ xfs_bmapi(  					got.br_state = XFS_EXT_UNWRITTEN;  			}  			error = xfs_bmap_add_extent(ip, lastx, &cur, &got, -				firstblock, flist, &tmp_logflags, whichfork, -				(flags & XFS_BMAPI_RSVBLOCKS)); +				firstblock, flist, &tmp_logflags, delta, +				whichfork, (flags & XFS_BMAPI_RSVBLOCKS));  			logflags |= tmp_logflags;  			if (error)  				goto error0; @@ -4983,8 +5161,8 @@ xfs_bmapi(  			}  			mval->br_state = XFS_EXT_NORM;  			error = xfs_bmap_add_extent(ip, lastx, &cur, mval, -				firstblock, flist, &tmp_logflags, whichfork, -				(flags & XFS_BMAPI_RSVBLOCKS)); +				firstblock, flist, &tmp_logflags, delta, +				whichfork, (flags & XFS_BMAPI_RSVBLOCKS));  			logflags |= tmp_logflags;  			if (error)  				goto error0; @@ -5073,7 +5251,14 @@ xfs_bmapi(  	ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||  	       XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);  	error = 0; - +	if (delta && delta->xed_startoff != NULLFILEOFF) { +		/* A change was actually made. +		 * Note that delta->xed_blockount is an offset at this +		 * point and needs to be converted to a block count. +		 */ +		ASSERT(delta->xed_blockcount > delta->xed_startoff); +		delta->xed_blockcount -= delta->xed_startoff; +	}  error0:  	/*  	 * Log everything.  Do this after conversion, there's no point in @@ -5185,6 +5370,8 @@ xfs_bunmapi(  	xfs_fsblock_t		*firstblock,	/* first allocated block  						   controls a.g. for allocs */  	xfs_bmap_free_t		*flist,		/* i/o: list extents to free */ +	xfs_extdelta_t		*delta,		/* o: change made to incore +						   extents */  	int			*done)		/* set if not done yet */  {  	xfs_btree_cur_t		*cur;		/* bmap btree cursor */ @@ -5242,6 +5429,10 @@ xfs_bunmapi(  	bno = start + len - 1;  	ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,  		&prev); +	if (delta) { +		delta->xed_startoff = NULLFILEOFF; +		delta->xed_blockcount = 0; +	}  	/*  	 * Check to see if the given block number is past the end of the  	 * file, back up to the last block if so... @@ -5340,7 +5531,8 @@ xfs_bunmapi(  			}  			del.br_state = XFS_EXT_UNWRITTEN;  			error = xfs_bmap_add_extent(ip, lastx, &cur, &del, -				firstblock, flist, &logflags, XFS_DATA_FORK, 0); +				firstblock, flist, &logflags, delta, +				XFS_DATA_FORK, 0);  			if (error)  				goto error0;  			goto nodelete; @@ -5394,7 +5586,7 @@ xfs_bunmapi(  				prev.br_state = XFS_EXT_UNWRITTEN;  				error = xfs_bmap_add_extent(ip, lastx - 1, &cur,  					&prev, firstblock, flist, &logflags, -					XFS_DATA_FORK, 0); +					delta, XFS_DATA_FORK, 0);  				if (error)  					goto error0;  				goto nodelete; @@ -5403,7 +5595,7 @@ xfs_bunmapi(  				del.br_state = XFS_EXT_UNWRITTEN;  				error = xfs_bmap_add_extent(ip, lastx, &cur,  					&del, firstblock, flist, &logflags, -					XFS_DATA_FORK, 0); +					delta, XFS_DATA_FORK, 0);  				if (error)  					goto error0;  				goto nodelete; @@ -5456,7 +5648,7 @@ xfs_bunmapi(  			goto error0;  		}  		error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, -			&tmp_logflags, whichfork, rsvd); +				&tmp_logflags, delta, whichfork, rsvd);  		logflags |= tmp_logflags;  		if (error)  			goto error0; @@ -5513,6 +5705,14 @@ nodelete:  	ASSERT(ifp->if_ext_max ==  	       XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));  	error = 0; +	if (delta && delta->xed_startoff != NULLFILEOFF) { +		/* A change was actually made. +		 * Note that delta->xed_blockount is an offset at this +		 * point and needs to be converted to a block count. +		 */ +		ASSERT(delta->xed_blockcount > delta->xed_startoff); +		delta->xed_blockcount -= delta->xed_startoff; +	}  error0:  	/*  	 * Log everything.  Do this after conversion, there's no point in @@ -5689,7 +5889,8 @@ xfs_getbmap(  		nmap = (nexleft > subnex) ? subnex : nexleft;  		error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),  				  XFS_BB_TO_FSB(mp, bmv->bmv_length), -				  bmapi_flags, NULL, 0, map, &nmap, NULL); +				  bmapi_flags, NULL, 0, map, &nmap, +				  NULL, NULL);  		if (error)  			goto unlock_and_return;  		ASSERT(nmap <= subnex); diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 8e0d73d9ccc..80e93409b78 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -26,6 +26,20 @@ struct xfs_mount;  struct xfs_trans;  /* + * DELTA: describe a change to the in-core extent list. + * + * Internally the use of xed_blockount is somewhat funky. + * xed_blockcount contains an offset much of the time because this + * makes merging changes easier.  (xfs_fileoff_t and xfs_filblks_t are + * the same underlying type). + */ +typedef struct xfs_extdelta +{ +	xfs_fileoff_t		xed_startoff;	/* offset of range */ +	xfs_filblks_t		xed_blockcount;	/* blocks in range */ +} xfs_extdelta_t; + +/*   * List of extents to be free "later".   * The list is kept sorted on xbf_startblock.   */ @@ -275,7 +289,9 @@ xfs_bmapi(  	xfs_extlen_t		total,		/* total blocks needed */  	struct xfs_bmbt_irec	*mval,		/* output: map values */  	int			*nmap,		/* i/o: mval size/count */ -	xfs_bmap_free_t		*flist);	/* i/o: list extents to free */ +	xfs_bmap_free_t		*flist,		/* i/o: list extents to free */ +	xfs_extdelta_t		*delta);	/* o: change made to incore +						   extents */  /*   * Map file blocks to filesystem blocks, simple version. @@ -309,6 +325,8 @@ xfs_bunmapi(  	xfs_fsblock_t		*firstblock,	/* first allocated block  						   controls a.g. for allocs */  	xfs_bmap_free_t		*flist,		/* i/o: list extents to free */ +	xfs_extdelta_t		*delta,		/* o: change made to incore +						   extents */  	int			*done);		/* set if not done yet */  /* diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 8988b905117..47b86f9f69f 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -1655,7 +1655,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  			XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|  			XFS_BMAPI_CONTIG,  			args->firstblock, args->total, &map, &nmap, -			args->flist))) { +			args->flist, NULL))) {  		return error;  	}  	ASSERT(nmap <= 1); @@ -1676,7 +1676,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  					XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|  					XFS_BMAPI_METADATA,  					args->firstblock, args->total, -					&mapp[mapi], &nmap, args->flist))) { +					&mapp[mapi], &nmap, args->flist, +					NULL))) {  				kmem_free(mapp, sizeof(*mapp) * count);  				return error;  			} @@ -1961,7 +1962,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,  		 */  		if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,  				XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, -				0, args->firstblock, args->flist, +				0, args->firstblock, args->flist, NULL,  				&done)) == ENOSPC) {  			if (w != XFS_DATA_FORK)  				goto done; @@ -2086,7 +2087,7 @@ xfs_da_do_buf(  					nfsb,  					XFS_BMAPI_METADATA |  						XFS_BMAPI_AFLAG(whichfork), -					NULL, 0, mapp, &nmap, NULL))) +					NULL, 0, mapp, &nmap, NULL, NULL)))  				goto exit0;  		}  	} else { diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 4968a6358e6..99daf8c0f90 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -54,24 +54,14 @@ xfs_swapext(  	xfs_swapext_t	__user *sxu)  {  	xfs_swapext_t	*sxp; -	xfs_inode_t     *ip=NULL, *tip=NULL, *ips[2]; -	xfs_trans_t     *tp; +	xfs_inode_t     *ip=NULL, *tip=NULL;  	xfs_mount_t     *mp; -	xfs_bstat_t	*sbp;  	struct file	*fp = NULL, *tfp = NULL;  	vnode_t		*vp, *tvp; -	static uint	lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; -	int		ilf_fields, tilf_fields;  	int		error = 0; -	xfs_ifork_t	*tempifp, *ifp, *tifp; -	__uint64_t	tmp; -	int		aforkblks = 0; -	int		taforkblks = 0; -	char		locked = 0;  	sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); -	tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); -	if (!sxp || !tempifp) { +	if (!sxp) {  		error = XFS_ERROR(ENOMEM);  		goto error0;  	} @@ -118,14 +108,56 @@ xfs_swapext(  	mp = ip->i_mount; -	sbp = &sxp->sx_stat; -  	if (XFS_FORCED_SHUTDOWN(mp)) {  		error =  XFS_ERROR(EIO);  		goto error0;  	} -	locked = 1; +	error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp); + + error0: +	if (fp != NULL) +		fput(fp); +	if (tfp != NULL) +		fput(tfp); + +	if (sxp != NULL) +		kmem_free(sxp, sizeof(xfs_swapext_t)); + +	return error; +} + +int +xfs_swap_extents( +	xfs_inode_t	*ip, +	xfs_inode_t	*tip, +	xfs_swapext_t	*sxp) +{ +	xfs_mount_t	*mp; +	xfs_inode_t	*ips[2]; +	xfs_trans_t	*tp; +	xfs_bstat_t	*sbp = &sxp->sx_stat; +	vnode_t		*vp, *tvp; +	xfs_ifork_t	*tempifp, *ifp, *tifp; +	int		ilf_fields, tilf_fields; +	static uint	lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; +	int		error = 0; +	int		aforkblks = 0; +	int		taforkblks = 0; +	__uint64_t	tmp; +	char		locked = 0; + +	mp = ip->i_mount; + +	tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); +	if (!tempifp) { +		error = XFS_ERROR(ENOMEM); +		goto error0; +	} + +	sbp = &sxp->sx_stat; +	vp = XFS_ITOV(ip); +	tvp = XFS_ITOV(tip);  	/* Lock in i_ino order */  	if (ip->i_ino < tip->i_ino) { @@ -137,6 +169,7 @@ xfs_swapext(  	}  	xfs_lock_inodes(ips, 2, 0, lock_flags); +	locked = 1;  	/* Check permissions */  	error = xfs_iaccess(ip, S_IWUSR, NULL); @@ -360,16 +393,7 @@ xfs_swapext(  		xfs_iunlock(ip,  lock_flags);  		xfs_iunlock(tip, lock_flags);  	} - -	if (fp != NULL) -		fput(fp); -	if (tfp != NULL) -		fput(tfp); - -	if (sxp != NULL) -		kmem_free(sxp, sizeof(xfs_swapext_t));  	if (tempifp != NULL)  		kmem_free(tempifp, sizeof(xfs_ifork_t)); -  	return error;  } diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h index f678559abc4..da178205be6 100644 --- a/fs/xfs/xfs_dfrag.h +++ b/fs/xfs/xfs_dfrag.h @@ -48,6 +48,9 @@ typedef struct xfs_swapext   */  int	xfs_swapext(struct xfs_swapext __user *sx); +int	xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, +		struct xfs_swapext *sxp); +  #endif	/* __KERNEL__ */  #endif	/* __XFS_DFRAG_H__ */ diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 022c8398ab6..80238a2263f 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c @@ -549,7 +549,7 @@ xfs_dir2_grow_inode(  	if ((error = xfs_bmapi(tp, dp, bno, count,  			XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,  			args->firstblock, args->total, &map, &nmap, -			args->flist))) { +			args->flist, NULL))) {  		return error;  	}  	ASSERT(nmap <= 1); @@ -585,7 +585,8 @@ xfs_dir2_grow_inode(  			if ((error = xfs_bmapi(tp, dp, b, c,  					XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,  					args->firstblock, args->total, -					&mapp[mapi], &nmap, args->flist))) { +					&mapp[mapi], &nmap, args->flist, +					NULL))) {  				kmem_free(mapp, sizeof(*mapp) * count);  				return error;  			} @@ -786,7 +787,7 @@ xfs_dir2_shrink_inode(  	 */  	if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,  			XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, -			&done))) { +			NULL, &done))) {  		/*  		 * ENOSPC actually can happen if we're in a removename with  		 * no space reservation, and the resulting block removal diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 0f5e2f2ce6e..5fe88d546c7 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -884,7 +884,7 @@ xfs_dir2_leaf_getdents(  					XFS_DIR2_BYTE_TO_DA(mp,  						XFS_DIR2_LEAF_OFFSET) - map_off,  					XFS_BMAPI_METADATA, NULL, 0, -					&map[map_valid], &nmap, NULL); +					&map[map_valid], &nmap, NULL, NULL);  				/*  				 * Don't know if we should ignore this or  				 * try to return an error. diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 94b60dd0380..020de5637e0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -1285,7 +1285,7 @@ xfs_isize_check(  				       (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -  			  map_first),  			 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, -			 NULL)) +			 NULL, NULL))  	    return;  	ASSERT(nimaps == 1);  	ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); @@ -1666,12 +1666,13 @@ xfs_itruncate_finish(  		 * runs.  		 */  		XFS_BMAP_INIT(&free_list, &first_block); -		error = xfs_bunmapi(ntp, ip, first_unmap_block, -				    unmap_len, +		error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore, +				    first_unmap_block, unmap_len,  				    XFS_BMAPI_AFLAG(fork) |  				      (sync ? 0 : XFS_BMAPI_ASYNC),  				    XFS_ITRUNC_MAX_EXTENTS, -				    &first_block, &free_list, &done); +				    &first_block, &free_list, +				    NULL, &done);  		if (error) {  			/*  			 * If the bunmapi call encounters an error, diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c index a07815661a8..d3da194f8b7 100644 --- a/fs/xfs/xfs_iocore.c +++ b/fs/xfs/xfs_iocore.c @@ -26,6 +26,7 @@  #include "xfs_ag.h"  #include "xfs_dir.h"  #include "xfs_dir2.h" +#include "xfs_dfrag.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h" @@ -68,6 +69,7 @@ xfs_ioinit(  xfs_ioops_t	xfs_iocore_xfs = {  	.xfs_ioinit		= (xfs_ioinit_t) xfs_ioinit,  	.xfs_bmapi_func		= (xfs_bmapi_t) xfs_bmapi, +	.xfs_bunmapi_func	= (xfs_bunmapi_t) xfs_bunmapi,  	.xfs_bmap_eof_func	= (xfs_bmap_eof_t) xfs_bmap_eof,  	.xfs_iomap_write_direct =  			(xfs_iomap_write_direct_t) xfs_iomap_write_direct, @@ -84,6 +86,7 @@ xfs_ioops_t	xfs_iocore_xfs = {  	.xfs_unlock		= (xfs_unlk_t) xfs_iunlock,  	.xfs_size_func		= (xfs_size_t) xfs_size_fn,  	.xfs_iodone		= (xfs_iodone_t) fs_noerr, +	.xfs_swap_extents_func	= (xfs_swap_extents_t) xfs_swap_extents,  };  void diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d5dfedcb892..d79055207fb 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -252,7 +252,7 @@ xfs_iomap(  	error = XFS_BMAPI(mp, NULL, io, offset_fsb,  			(xfs_filblks_t)(end_fsb - offset_fsb),  			bmapi_flags,  NULL, 0, &imap, -			&nimaps, NULL); +			&nimaps, NULL, NULL);  	if (error)  		goto out; @@ -519,8 +519,8 @@ xfs_iomap_write_direct(  	 */  	XFS_BMAP_INIT(&free_list, &firstfsb);  	nimaps = 1; -	error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, -		bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); +	error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag, +		&firstfsb, 0, &imap, &nimaps, &free_list, NULL);  	if (error)  		goto error0; @@ -610,8 +610,8 @@ xfs_iomap_eof_want_preallocate(  	while (count_fsb > 0) {  		imaps = nimaps;  		firstblock = NULLFSBLOCK; -		error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, -				  0, &firstblock, 0, imap, &imaps, NULL); +		error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0, +				  &firstblock, 0, imap, &imaps, NULL, NULL);  		if (error)  			return error;  		for (n = 0; n < imaps; n++) { @@ -695,11 +695,11 @@ retry:  	nimaps = XFS_WRITE_IMAPS;  	firstblock = NULLFSBLOCK; -	error = xfs_bmapi(NULL, ip, offset_fsb, +	error = XFS_BMAPI(mp, NULL, io, offset_fsb,  			  (xfs_filblks_t)(last_fsb - offset_fsb),  			  XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |  			  XFS_BMAPI_ENTIRE, &firstblock, 1, imap, -			  &nimaps, NULL); +			  &nimaps, NULL, NULL);  	if (error && (error != ENOSPC))  		return XFS_ERROR(error); @@ -832,9 +832,9 @@ xfs_iomap_write_allocate(  			}  			/* Go get the actual blocks */ -			error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, +			error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,  					XFS_BMAPI_WRITE, &first_block, 1, -					imap, &nimaps, &free_list); +					imap, &nimaps, &free_list, NULL);  			if (error)  				goto trans_cancel; @@ -955,9 +955,9 @@ xfs_iomap_write_unwritten(  		 */  		XFS_BMAP_INIT(&free_list, &firstfsb);  		nimaps = 1; -		error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, +		error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,  				  XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, -				  1, &imap, &nimaps, &free_list); +				  1, &imap, &nimaps, &free_list, NULL);  		if (error)  			goto error_on_bmapi_transaction; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 668ad23fd37..a682eb55810 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -63,6 +63,8 @@ struct xfs_perag;  struct xfs_iocore;  struct xfs_bmbt_irec;  struct xfs_bmap_free; +struct xfs_extdelta; +struct xfs_swapext;  extern struct vfsops xfs_vfsops;  extern struct vnodeops xfs_vnodeops; @@ -194,7 +196,12 @@ typedef int		(*xfs_bmapi_t)(struct xfs_trans *, void *,  				xfs_fileoff_t, xfs_filblks_t, int,  				xfs_fsblock_t *, xfs_extlen_t,  				struct xfs_bmbt_irec *, int *, -				struct xfs_bmap_free *); +				struct xfs_bmap_free *, struct xfs_extdelta *); +typedef int		(*xfs_bunmapi_t)(struct xfs_trans *, +				void *, xfs_fileoff_t, +				xfs_filblks_t, int, xfs_extnum_t, +				xfs_fsblock_t *, struct xfs_bmap_free *, +				struct xfs_extdelta *, int *);  typedef int		(*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);  typedef int		(*xfs_iomap_write_direct_t)(  				void *, xfs_off_t, size_t, int, @@ -214,10 +221,13 @@ typedef int		(*xfs_lock_nowait_t)(void *, uint);  typedef void		(*xfs_unlk_t)(void *, unsigned int);  typedef xfs_fsize_t	(*xfs_size_t)(void *);  typedef xfs_fsize_t	(*xfs_iodone_t)(struct vfs *); +typedef int		(*xfs_swap_extents_t)(void *, void *, +				struct xfs_swapext*);  typedef struct xfs_ioops {  	xfs_ioinit_t			xfs_ioinit;  	xfs_bmapi_t			xfs_bmapi_func; +	xfs_bunmapi_t			xfs_bunmapi_func;  	xfs_bmap_eof_t			xfs_bmap_eof_func;  	xfs_iomap_write_direct_t	xfs_iomap_write_direct;  	xfs_iomap_write_delay_t		xfs_iomap_write_delay; @@ -230,13 +240,17 @@ typedef struct xfs_ioops {  	xfs_unlk_t			xfs_unlock;  	xfs_size_t			xfs_size_func;  	xfs_iodone_t			xfs_iodone; +	xfs_swap_extents_t		xfs_swap_extents_func;  } xfs_ioops_t;  #define XFS_IOINIT(vfsp, args, flags) \  	(*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) -#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist)	\ +#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \  	(*(mp)->m_io_ops.xfs_bmapi_func) \ -		(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) +		(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) +#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \ +	(*(mp)->m_io_ops.xfs_bunmapi_func) \ +		(trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)  #define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \  	(*(mp)->m_io_ops.xfs_bmap_eof_func) \  		((io)->io_obj, endoff, whichfork, eof) @@ -266,6 +280,9 @@ typedef struct xfs_ioops {  	(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)  #define XFS_IODONE(vfsp) \  	(*(mp)->m_io_ops.xfs_iodone)(vfsp) +#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ +	(*(mp)->m_io_ops.xfs_swap_extents_func) \ +		((io)->io_obj, (tio)->io_obj, sxp)  #ifdef HAVE_PERCPU_SB diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 5b413946b1c..f5944c8b378 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -141,7 +141,7 @@ xfs_growfs_rt_alloc(  		cancelflags |= XFS_TRANS_ABORT;  		error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,  			XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, -			resblks, &map, &nmap, &flist); +			resblks, &map, &nmap, &flist, NULL);  		if (!error && nmap < 1)  			error = XFS_ERROR(ENOSPC);  		if (error) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 7027ae68ee3..567d14d06d9 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc.   * All Rights Reserved.   *   * This program is free software; you can redistribute it and/or @@ -1000,7 +1000,7 @@ xfs_readlink(  		nmaps = SYMLINK_MAPS;  		error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), -				  0, NULL, 0, mval, &nmaps, NULL); +				  0, NULL, 0, mval, &nmaps, NULL, NULL);  		if (error) {  			goto error_return; @@ -1208,8 +1208,8 @@ xfs_inactive_free_eofblocks(  	nimaps = 1;  	xfs_ilock(ip, XFS_ILOCK_SHARED); -	error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, -			  NULL, 0, &imap, &nimaps, NULL); +	error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0, +			  NULL, 0, &imap, &nimaps, NULL, NULL);  	xfs_iunlock(ip, XFS_ILOCK_SHARED);  	if (!error && (nimaps != 0) && @@ -1338,7 +1338,7 @@ xfs_inactive_symlink_rmt(  	nmaps = ARRAY_SIZE(mval);  	if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),  			XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, -			&free_list))) +			&free_list, NULL)))  		goto error0;  	/*  	 * Invalidate the block(s). @@ -1353,7 +1353,7 @@ xfs_inactive_symlink_rmt(  	 * Unmap the dead block(s) to the free_list.  	 */  	if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, -			&first_block, &free_list, &done))) +			&first_block, &free_list, NULL, &done)))  		goto error1;  	ASSERT(done);  	/* @@ -3457,7 +3457,7 @@ xfs_symlink(  		error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,  				  XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,  				  &first_block, resblks, mval, &nmaps, -				  &free_list); +				  &free_list, NULL);  		if (error) {  			goto error1;  		} @@ -4116,10 +4116,10 @@ retry:  		 * Issue the xfs_bmapi() call to allocate the blocks  		 */  		XFS_BMAP_INIT(&free_list, &firstfsb); -		error = xfs_bmapi(tp, ip, startoffset_fsb, +		error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,  				  allocatesize_fsb, bmapi_flag,  				  &firstfsb, 0, imapp, &nimaps, -				  &free_list); +				  &free_list, NULL);  		if (error) {  			goto error0;  		} @@ -4199,8 +4199,8 @@ xfs_zero_remaining_bytes(  	for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {  		offset_fsb = XFS_B_TO_FSBT(mp, offset);  		nimap = 1; -		error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, -			&nimap, NULL); +		error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0, +			NULL, 0, &imap, &nimap, NULL, NULL);  		if (error || nimap < 1)  			break;  		ASSERT(imap.br_blockcount >= 1); @@ -4338,8 +4338,8 @@ xfs_free_file_space(  	 */  	if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {  		nimap = 1; -		error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, -			&imap, &nimap, NULL); +		error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb, +			1, 0, NULL, 0, &imap, &nimap, NULL, NULL);  		if (error)  			goto out_unlock_iolock;  		ASSERT(nimap == 0 || nimap == 1); @@ -4353,8 +4353,8 @@ xfs_free_file_space(  				startoffset_fsb += mp->m_sb.sb_rextsize - mod;  		}  		nimap = 1; -		error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, -			&imap, &nimap, NULL); +		error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1, +			1, 0, NULL, 0, &imap, &nimap, NULL, NULL);  		if (error)  			goto out_unlock_iolock;  		ASSERT(nimap == 0 || nimap == 1); @@ -4426,9 +4426,9 @@ xfs_free_file_space(  		 * issue the bunmapi() call to free the blocks  		 */  		XFS_BMAP_INIT(&free_list, &firstfsb); -		error = xfs_bunmapi(tp, ip, startoffset_fsb, +		error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,  				  endoffset_fsb - startoffset_fsb, -				  0, 2, &firstfsb, &free_list, &done); +				  0, 2, &firstfsb, &free_list, NULL, &done);  		if (error) {  			goto error0;  		}  |