diff options
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 13 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 38 | 
2 files changed, 14 insertions, 37 deletions
| diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index c21e01a9b2dd..cf4dee01983a 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -1746,11 +1746,18 @@ xfs_bmap_add_extent_unwritten_real(  			if ((error = xfs_bmbt_insert(cur, &i)))  				goto done;  			XFS_WANT_CORRUPTED_GOTO(i == 1, done); -			if ((error = xfs_bmbt_increment(cur, 0, &i))) +			/* +			 * Reset the cursor to the position of the new extent +			 * we are about to insert as we can't trust it after +			 * the previous insert. +			 */ +			if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, +					new->br_startblock, new->br_blockcount, +					&i)))  				goto done; -			XFS_WANT_CORRUPTED_GOTO(i == 1, done); +			XFS_WANT_CORRUPTED_GOTO(i == 0, done);  			/* new middle extent - newext */ -			cur->bc_rec.b = *new; +			cur->bc_rec.b.br_state = new->br_state;  			if ((error = xfs_bmbt_insert(cur, &i)))  				goto done;  			XFS_WANT_CORRUPTED_GOTO(i == 1, done); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 4f0e849d973e..4aa2f11ba563 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -2029,22 +2029,8 @@ xfs_bmbt_increment(   * Insert the current record at the point referenced by cur.   *   * A multi-level split of the tree on insert will invalidate the original - * cursor. It appears, however, that some callers assume that the cursor is - * always valid. Hence if we do a multi-level split we need to revalidate the - * cursor. - * - * When a split occurs, we will see a new cursor returned. Use that as a - * trigger to determine if we need to revalidate the original cursor. If we get - * a split, then use the original irec to lookup up the path of the record we - * just inserted. - * - * Note that the fact that the btree root is in the inode means that we can - * have the level of the tree change without a "split" occurring at the root - * level. What happens is that the root is migrated to an allocated block and - * the inode root is pointed to it. This means a single split can change the - * level of the tree (level 2 -> level 3) and invalidate the old cursor. Hence - * the level change should be accounted as a split so as to correctly trigger a - * revalidation of the old cursor. + * cursor.  All callers of this function should assume that the cursor is + * no longer valid and revalidate it.   */  int					/* error */  xfs_bmbt_insert( @@ -2057,14 +2043,11 @@ xfs_bmbt_insert(  	xfs_fsblock_t	nbno;  	xfs_btree_cur_t	*ncur;  	xfs_bmbt_rec_t	nrec; -	xfs_bmbt_irec_t	oirec;		/* original irec */  	xfs_btree_cur_t	*pcur; -	int		splits = 0;  	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);  	level = 0;  	nbno = NULLFSBLOCK; -	oirec = cur->bc_rec.b;  	xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);  	ncur = NULL;  	pcur = cur; @@ -2073,13 +2056,11 @@ xfs_bmbt_insert(  				&i))) {  			if (pcur != cur)  				xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); -			goto error0; +			XFS_BMBT_TRACE_CURSOR(cur, ERROR); +			return error;  		}  		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);  		if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) { -			/* allocating a new root is effectively a split */ -			if (cur->bc_nlevels != pcur->bc_nlevels) -				splits++;  			cur->bc_nlevels = pcur->bc_nlevels;  			cur->bc_private.b.allocated +=  				pcur->bc_private.b.allocated; @@ -2093,21 +2074,10 @@ xfs_bmbt_insert(  			xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);  		}  		if (ncur) { -			splits++;  			pcur = ncur;  			ncur = NULL;  		}  	} while (nbno != NULLFSBLOCK); - -	if (splits > 1) { -		/* revalidate the old cursor as we had a multi-level split */ -		error = xfs_bmbt_lookup_eq(cur, oirec.br_startoff, -				oirec.br_startblock, oirec.br_blockcount, &i); -		if (error) -			goto error0; -		ASSERT(i == 1); -	} -  	XFS_BMBT_TRACE_CURSOR(cur, EXIT);  	*stat = i;  	return 0; | 
