|
@@ -1,5 +1,5 @@
|
|
/*
|
|
/*
|
|
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
|
|
|
|
|
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
|
* All Rights Reserved.
|
|
* All Rights Reserved.
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* 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_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
int *logflagsp, /* inode logging flags */
|
|
int *logflagsp, /* inode logging flags */
|
|
|
|
+ xfs_extdelta_t *delta, /* Change made to incore extents */
|
|
int whichfork, /* data or attr fork */
|
|
int whichfork, /* data or attr fork */
|
|
int rsvd); /* OK to allocate reserved blocks */
|
|
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_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
int *logflagsp, /* inode logging flags */
|
|
int *logflagsp, /* inode logging flags */
|
|
|
|
+ xfs_extdelta_t *delta, /* Change made to incore extents */
|
|
int rsvd); /* OK to allocate reserved blocks */
|
|
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_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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 */
|
|
int rsvd); /* OK to allocate reserved blocks */
|
|
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_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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 */
|
|
int whichfork); /* data or attr fork */
|
|
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_extnum_t idx, /* extent number to update/insert */
|
|
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
|
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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.
|
|
* 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_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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 */
|
|
int whichfork, /* data or attr fork */
|
|
int whichfork, /* data or attr fork */
|
|
int rsvd); /* OK to allocate reserved blocks */
|
|
int rsvd); /* OK to allocate reserved blocks */
|
|
|
|
|
|
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
|
|
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
int *logflagsp, /* inode logging flags */
|
|
int *logflagsp, /* inode logging flags */
|
|
|
|
+ xfs_extdelta_t *delta, /* Change made to incore extents */
|
|
int whichfork, /* data or attr fork */
|
|
int whichfork, /* data or attr fork */
|
|
int rsvd) /* OK to use reserved data blocks */
|
|
int rsvd) /* OK to use reserved data blocks */
|
|
{
|
|
{
|
|
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
|
|
logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
|
logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
|
} else
|
|
} else
|
|
logflags = 0;
|
|
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.
|
|
* Any kind of new delayed allocation goes here.
|
|
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
|
|
ASSERT((cur->bc_private.b.flags &
|
|
ASSERT((cur->bc_private.b.flags &
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
|
|
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
|
|
- &logflags, rsvd)))
|
|
|
|
|
|
+ &logflags, delta, rsvd)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
|
|
ASSERT((cur->bc_private.b.flags &
|
|
ASSERT((cur->bc_private.b.flags &
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
|
|
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
|
|
- &logflags, whichfork)))
|
|
|
|
|
|
+ &logflags, delta, whichfork)))
|
|
goto done;
|
|
goto done;
|
|
} else {
|
|
} else {
|
|
xfs_bmbt_irec_t prev; /* old extent at offset idx */
|
|
xfs_bmbt_irec_t prev; /* old extent at offset idx */
|
|
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
|
|
XFS_BTCUR_BPRV_WASDEL);
|
|
XFS_BTCUR_BPRV_WASDEL);
|
|
if ((error = xfs_bmap_add_extent_delay_real(ip,
|
|
if ((error = xfs_bmap_add_extent_delay_real(ip,
|
|
idx, &cur, new, &da_new, first, flist,
|
|
idx, &cur, new, &da_new, first, flist,
|
|
- &logflags, rsvd)))
|
|
|
|
|
|
+ &logflags, delta, rsvd)))
|
|
goto done;
|
|
goto done;
|
|
} else if (new->br_state == XFS_EXT_NORM) {
|
|
} else if (new->br_state == XFS_EXT_NORM) {
|
|
ASSERT(new->br_state == XFS_EXT_NORM);
|
|
ASSERT(new->br_state == XFS_EXT_NORM);
|
|
if ((error = xfs_bmap_add_extent_unwritten_real(
|
|
if ((error = xfs_bmap_add_extent_unwritten_real(
|
|
- ip, idx, &cur, new, &logflags)))
|
|
|
|
|
|
+ ip, idx, &cur, new, &logflags, delta)))
|
|
goto done;
|
|
goto done;
|
|
} else {
|
|
} else {
|
|
ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
|
|
ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
|
|
if ((error = xfs_bmap_add_extent_unwritten_real(
|
|
if ((error = xfs_bmap_add_extent_unwritten_real(
|
|
- ip, idx, &cur, new, &logflags)))
|
|
|
|
|
|
+ ip, idx, &cur, new, &logflags, delta)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
ASSERT(*curp == cur || *curp == NULL);
|
|
ASSERT(*curp == cur || *curp == NULL);
|
|
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
|
|
ASSERT((cur->bc_private.b.flags &
|
|
ASSERT((cur->bc_private.b.flags &
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
XFS_BTCUR_BPRV_WASDEL) == 0);
|
|
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
|
|
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
|
|
- new, &logflags, whichfork)))
|
|
|
|
|
|
+ new, &logflags, delta, whichfork)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
|
|
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
|
int *logflagsp, /* inode logging flags */
|
|
int *logflagsp, /* inode logging flags */
|
|
|
|
+ xfs_extdelta_t *delta, /* Change made to incore extents */
|
|
int rsvd) /* OK to use reserved data block allocation */
|
|
int rsvd) /* OK to use reserved data block allocation */
|
|
{
|
|
{
|
|
xfs_btree_cur_t *cur; /* btree cursor */
|
|
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 */
|
|
/* left is 0, right is 1, prev is 2 */
|
|
int rval=0; /* return value (logging flags) */
|
|
int rval=0; /* return value (logging flags) */
|
|
int state = 0;/* state bits, accessed thru macros */
|
|
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 */
|
|
int tmp_rval; /* partial logging flags */
|
|
enum { /* bit number definitions for state */
|
|
enum { /* bit number definitions for state */
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
*dnew = 0;
|
|
*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;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
|
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
*dnew = 0;
|
|
*dnew = 0;
|
|
|
|
+ /* DELTA: Two in-core extents are replaced by one. */
|
|
|
|
+ temp = LEFT.br_startoff;
|
|
|
|
+ temp2 = LEFT.br_blockcount +
|
|
|
|
+ PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
|
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
*dnew = 0;
|
|
*dnew = 0;
|
|
|
|
+ /* DELTA: Two in-core extents are replaced by one. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount +
|
|
|
|
+ RIGHT.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
|
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
|
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
|
|
ASSERT(i == 1);
|
|
ASSERT(i == 1);
|
|
}
|
|
}
|
|
*dnew = 0;
|
|
*dnew = 0;
|
|
|
|
+ /* DELTA: The in-core extent described by new changed type. */
|
|
|
|
+ temp = new->br_startoff;
|
|
|
|
+ temp2 = new->br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(LEFT_FILLING, LEFT_CONTIG):
|
|
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_bmap_trace_post_update(fname, "LF|LC", ip, idx,
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
*dnew = temp;
|
|
*dnew = temp;
|
|
|
|
+ /* DELTA: The boundary between two in-core extents moved. */
|
|
|
|
+ temp = LEFT.br_startoff;
|
|
|
|
+ temp2 = LEFT.br_blockcount +
|
|
|
|
+ PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK(LEFT_FILLING):
|
|
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_bmap_trace_post_update(fname, "LF", ip, idx + 1,
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
*dnew = temp;
|
|
*dnew = temp;
|
|
|
|
+ /* DELTA: One in-core extent is split in two. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
|
|
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_bmap_trace_post_update(fname, "RF|RC", ip, idx,
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
*dnew = temp;
|
|
*dnew = temp;
|
|
|
|
+ /* DELTA: The boundary between two in-core extents moved. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount +
|
|
|
|
+ RIGHT.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK(RIGHT_FILLING):
|
|
case MASK(RIGHT_FILLING):
|
|
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
|
|
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
|
|
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
|
|
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
|
|
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
|
|
*dnew = temp;
|
|
*dnew = temp;
|
|
|
|
+ /* DELTA: One in-core extent is split in two. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case 0:
|
|
case 0:
|
|
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
|
|
xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
|
|
xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
*dnew = temp + temp2;
|
|
*dnew = temp + temp2;
|
|
|
|
+ /* DELTA: One in-core extent is split in three. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
|
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
|
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
|
|
ASSERT(0);
|
|
ASSERT(0);
|
|
}
|
|
}
|
|
*curp = cur;
|
|
*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:
|
|
done:
|
|
*logflagsp = rval;
|
|
*logflagsp = rval;
|
|
return error;
|
|
return error;
|
|
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
|
|
xfs_extnum_t idx, /* extent number to update/insert */
|
|
xfs_extnum_t idx, /* extent number to update/insert */
|
|
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
|
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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_btree_cur_t *cur; /* btree cursor */
|
|
xfs_bmbt_rec_t *ep; /* extent entry for idx */
|
|
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 */
|
|
/* left is 0, right is 1, prev is 2 */
|
|
int rval=0; /* return value (logging flags) */
|
|
int rval=0; /* return value (logging flags) */
|
|
int state = 0;/* state bits, accessed thru macros */
|
|
int state = 0;/* state bits, accessed thru macros */
|
|
|
|
+ xfs_filblks_t temp=0;
|
|
|
|
+ xfs_filblks_t temp2=0;
|
|
enum { /* bit number definitions for state */
|
|
enum { /* bit number definitions for state */
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_FILLING, RIGHT_FILLING,
|
|
LEFT_FILLING, RIGHT_FILLING,
|
|
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
|
|
RIGHT.br_blockcount, LEFT.br_state)))
|
|
RIGHT.br_blockcount, LEFT.br_state)))
|
|
goto done;
|
|
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;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
|
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|
LEFT.br_state)))
|
|
LEFT.br_state)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: Two in-core extents are replaced by one. */
|
|
|
|
+ temp = LEFT.br_startoff;
|
|
|
|
+ temp2 = LEFT.br_blockcount +
|
|
|
|
+ PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
|
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
|
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|
newext)))
|
|
newext)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: Two in-core extents are replaced by one. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount +
|
|
|
|
+ RIGHT.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
|
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
|
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|
newext)))
|
|
newext)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: The in-core extent described by new changed type. */
|
|
|
|
+ temp = new->br_startoff;
|
|
|
|
+ temp2 = new->br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(LEFT_FILLING, LEFT_CONTIG):
|
|
case MASK2(LEFT_FILLING, LEFT_CONTIG):
|
|
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|
LEFT.br_state))
|
|
LEFT.br_state))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: The boundary between two in-core extents moved. */
|
|
|
|
+ temp = LEFT.br_startoff;
|
|
|
|
+ temp2 = LEFT.br_blockcount +
|
|
|
|
+ PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK(LEFT_FILLING):
|
|
case MASK(LEFT_FILLING):
|
|
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|
goto done;
|
|
goto done;
|
|
ASSERT(i == 1);
|
|
ASSERT(i == 1);
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: One in-core extent is split in two. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
|
|
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
|
|
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|
newext)))
|
|
newext)))
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: The boundary between two in-core extents moved. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount +
|
|
|
|
+ RIGHT.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK(RIGHT_FILLING):
|
|
case MASK(RIGHT_FILLING):
|
|
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|
goto done;
|
|
goto done;
|
|
ASSERT(i == 1);
|
|
ASSERT(i == 1);
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: One in-core extent is split in two. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case 0:
|
|
case 0:
|
|
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|
goto done;
|
|
goto done;
|
|
ASSERT(i == 1);
|
|
ASSERT(i == 1);
|
|
}
|
|
}
|
|
|
|
+ /* DELTA: One in-core extent is split in three. */
|
|
|
|
+ temp = PREV.br_startoff;
|
|
|
|
+ temp2 = PREV.br_blockcount;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
|
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
|
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
|
|
ASSERT(0);
|
|
ASSERT(0);
|
|
}
|
|
}
|
|
*curp = cur;
|
|
*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:
|
|
done:
|
|
*logflagsp = rval;
|
|
*logflagsp = rval;
|
|
return error;
|
|
return error;
|
|
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
|
|
xfs_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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 */
|
|
int rsvd) /* OK to allocate reserved blocks */
|
|
int rsvd) /* OK to allocate reserved blocks */
|
|
{
|
|
{
|
|
xfs_bmbt_rec_t *ep; /* extent record for idx */
|
|
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_filblks_t oldlen=0; /* old indirect size */
|
|
xfs_bmbt_irec_t right; /* right neighbor extent entry */
|
|
xfs_bmbt_irec_t right; /* right neighbor extent entry */
|
|
int state; /* state bits, accessed thru macros */
|
|
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 */
|
|
enum { /* bit number definitions for state */
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_DELAY, RIGHT_DELAY,
|
|
LEFT_DELAY, RIGHT_DELAY,
|
|
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
xfs_iext_remove(ifp, idx, 1);
|
|
xfs_iext_remove(ifp, idx, 1);
|
|
ip->i_df.if_lastex = 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;
|
|
break;
|
|
|
|
|
|
case MASK(LEFT_CONTIG):
|
|
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_bmap_trace_post_update(fname, "LC", ip, idx - 1,
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
ip->i_df.if_lastex = idx - 1;
|
|
ip->i_df.if_lastex = idx - 1;
|
|
|
|
+ /* DELTA: One in-core extent grew into a hole. */
|
|
|
|
+ temp2 = temp;
|
|
|
|
+ temp = left.br_startoff;
|
|
break;
|
|
break;
|
|
|
|
|
|
case MASK(RIGHT_CONTIG):
|
|
case MASK(RIGHT_CONTIG):
|
|
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
|
|
NULLSTARTBLOCK((int)newlen), temp, right.br_state);
|
|
NULLSTARTBLOCK((int)newlen), temp, right.br_state);
|
|
xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
|
|
xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
|
|
ip->i_df.if_lastex = idx;
|
|
ip->i_df.if_lastex = idx;
|
|
|
|
+ /* DELTA: One in-core extent grew into a hole. */
|
|
|
|
+ temp2 = temp;
|
|
|
|
+ temp = new->br_startoff;
|
|
break;
|
|
break;
|
|
|
|
|
|
case 0:
|
|
case 0:
|
|
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
|
|
XFS_DATA_FORK);
|
|
XFS_DATA_FORK);
|
|
xfs_iext_insert(ifp, idx, 1, new);
|
|
xfs_iext_insert(ifp, idx, 1, new);
|
|
ip->i_df.if_lastex = idx;
|
|
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;
|
|
break;
|
|
}
|
|
}
|
|
if (oldlen != newlen) {
|
|
if (oldlen != newlen) {
|
|
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
|
|
* Nothing to do for disk quota accounting here.
|
|
* 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;
|
|
*logflagsp = 0;
|
|
return 0;
|
|
return 0;
|
|
#undef MASK
|
|
#undef MASK
|
|
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
|
|
xfs_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
|
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 */
|
|
int whichfork) /* data or attr fork */
|
|
int whichfork) /* data or attr fork */
|
|
{
|
|
{
|
|
xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
|
|
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_ifork_t *ifp; /* inode fork pointer */
|
|
xfs_bmbt_irec_t left; /* left neighbor extent entry */
|
|
xfs_bmbt_irec_t left; /* left neighbor extent entry */
|
|
xfs_bmbt_irec_t right; /* right 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 */
|
|
int state; /* state bits, accessed thru macros */
|
|
|
|
+ xfs_filblks_t temp=0;
|
|
|
|
+ xfs_filblks_t temp2=0;
|
|
enum { /* bit number definitions for state */
|
|
enum { /* bit number definitions for state */
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_CONTIG, RIGHT_CONTIG,
|
|
LEFT_DELAY, RIGHT_DELAY,
|
|
LEFT_DELAY, RIGHT_DELAY,
|
|
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
|
|
left.br_blockcount + new->br_blockcount +
|
|
left.br_blockcount + new->br_blockcount +
|
|
right.br_blockcount <= MAXEXTLEN));
|
|
right.br_blockcount <= MAXEXTLEN));
|
|
|
|
|
|
|
|
+ error = 0;
|
|
/*
|
|
/*
|
|
* Select which case we're in here, and implement it.
|
|
* 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_NEXT_SET(ip, whichfork,
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
|
|
if (cur == NULL) {
|
|
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):
|
|
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);
|
|
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
|
|
ifp->if_lastex = idx - 1;
|
|
ifp->if_lastex = idx - 1;
|
|
if (cur == NULL) {
|
|
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):
|
|
case MASK(RIGHT_CONTIG):
|
|
/*
|
|
/*
|
|
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
|
|
xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
|
|
xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
|
|
ifp->if_lastex = idx;
|
|
ifp->if_lastex = idx;
|
|
if (cur == NULL) {
|
|
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:
|
|
case 0:
|
|
/*
|
|
/*
|
|
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
|
|
XFS_IFORK_NEXT_SET(ip, whichfork,
|
|
XFS_IFORK_NEXT_SET(ip, whichfork,
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
|
|
if (cur == NULL) {
|
|
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 MASK
|
|
#undef MASK2
|
|
#undef MASK2
|
|
#undef STATE_SET
|
|
#undef STATE_SET
|
|
#undef STATE_TEST
|
|
#undef STATE_TEST
|
|
#undef STATE_SET_TEST
|
|
#undef STATE_SET_TEST
|
|
#undef SWITCH_STATE
|
|
#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_btree_cur_t *cur, /* if null, not a btree */
|
|
xfs_bmbt_irec_t *del, /* data to remove from extents */
|
|
xfs_bmbt_irec_t *del, /* data to remove from extents */
|
|
int *logflagsp, /* inode logging flags */
|
|
int *logflagsp, /* inode logging flags */
|
|
|
|
+ xfs_extdelta_t *delta, /* Change made to incore extents */
|
|
int whichfork, /* data or attr fork */
|
|
int whichfork, /* data or attr fork */
|
|
int rsvd) /* OK to allocate reserved blocks */
|
|
int rsvd) /* OK to allocate reserved blocks */
|
|
{
|
|
{
|
|
@@ -3193,6 +3358,14 @@ xfs_bmap_del_extent(
|
|
if (da_old > da_new)
|
|
if (da_old > da_new)
|
|
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
|
|
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
|
|
rsvd);
|
|
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:
|
|
done:
|
|
*logflagsp = flags;
|
|
*logflagsp = flags;
|
|
return error;
|
|
return error;
|
|
@@ -3753,7 +3926,7 @@ xfs_bunmap_trace(
|
|
if (ip->i_rwtrace == NULL)
|
|
if (ip->i_rwtrace == NULL)
|
|
return;
|
|
return;
|
|
ktrace_enter(ip->i_rwtrace,
|
|
ktrace_enter(ip->i_rwtrace,
|
|
- (void *)(__psint_t)XFS_BUNMAPI,
|
|
|
|
|
|
+ (void *)(__psint_t)XFS_BUNMAP,
|
|
(void *)ip,
|
|
(void *)ip,
|
|
(void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
|
|
(void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
|
|
(void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
|
|
(void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
|
|
@@ -4538,7 +4711,8 @@ xfs_bmapi(
|
|
xfs_extlen_t total, /* total blocks needed */
|
|
xfs_extlen_t total, /* total blocks needed */
|
|
xfs_bmbt_irec_t *mval, /* output: map values */
|
|
xfs_bmbt_irec_t *mval, /* output: map values */
|
|
int *nmap, /* i/o: mval size/count */
|
|
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_fsblock_t abno; /* allocated block number */
|
|
xfs_extlen_t alen; /* allocated extent length */
|
|
xfs_extlen_t alen; /* allocated extent length */
|
|
@@ -4650,6 +4824,10 @@ xfs_bmapi(
|
|
end = bno + len;
|
|
end = bno + len;
|
|
obno = bno;
|
|
obno = bno;
|
|
bma.ip = NULL;
|
|
bma.ip = NULL;
|
|
|
|
+ if (delta) {
|
|
|
|
+ delta->xed_startoff = NULLFILEOFF;
|
|
|
|
+ delta->xed_blockcount = 0;
|
|
|
|
+ }
|
|
while (bno < end && n < *nmap) {
|
|
while (bno < end && n < *nmap) {
|
|
/*
|
|
/*
|
|
* Reading past eof, act as though there's a hole
|
|
* Reading past eof, act as though there's a hole
|
|
@@ -4886,8 +5064,8 @@ xfs_bmapi(
|
|
got.br_state = XFS_EXT_UNWRITTEN;
|
|
got.br_state = XFS_EXT_UNWRITTEN;
|
|
}
|
|
}
|
|
error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
|
|
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;
|
|
logflags |= tmp_logflags;
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
@@ -4983,8 +5161,8 @@ xfs_bmapi(
|
|
}
|
|
}
|
|
mval->br_state = XFS_EXT_NORM;
|
|
mval->br_state = XFS_EXT_NORM;
|
|
error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
|
|
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;
|
|
logflags |= tmp_logflags;
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
@@ -5073,7 +5251,14 @@ xfs_bmapi(
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
|
|
error = 0;
|
|
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:
|
|
error0:
|
|
/*
|
|
/*
|
|
* Log everything. Do this after conversion, there's no point in
|
|
* Log everything. Do this after conversion, there's no point in
|
|
@@ -5185,6 +5370,8 @@ xfs_bunmapi(
|
|
xfs_fsblock_t *firstblock, /* first allocated block
|
|
xfs_fsblock_t *firstblock, /* first allocated block
|
|
controls a.g. for allocs */
|
|
controls a.g. for allocs */
|
|
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 */
|
|
int *done) /* set if not done yet */
|
|
int *done) /* set if not done yet */
|
|
{
|
|
{
|
|
xfs_btree_cur_t *cur; /* bmap btree cursor */
|
|
xfs_btree_cur_t *cur; /* bmap btree cursor */
|
|
@@ -5242,6 +5429,10 @@ xfs_bunmapi(
|
|
bno = start + len - 1;
|
|
bno = start + len - 1;
|
|
ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
|
|
ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
|
|
&prev);
|
|
&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
|
|
* Check to see if the given block number is past the end of the
|
|
* file, back up to the last block if so...
|
|
* file, back up to the last block if so...
|
|
@@ -5340,7 +5531,8 @@ xfs_bunmapi(
|
|
}
|
|
}
|
|
del.br_state = XFS_EXT_UNWRITTEN;
|
|
del.br_state = XFS_EXT_UNWRITTEN;
|
|
error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
|
|
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)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
goto nodelete;
|
|
goto nodelete;
|
|
@@ -5394,7 +5586,7 @@ xfs_bunmapi(
|
|
prev.br_state = XFS_EXT_UNWRITTEN;
|
|
prev.br_state = XFS_EXT_UNWRITTEN;
|
|
error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
|
|
error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
|
|
&prev, firstblock, flist, &logflags,
|
|
&prev, firstblock, flist, &logflags,
|
|
- XFS_DATA_FORK, 0);
|
|
|
|
|
|
+ delta, XFS_DATA_FORK, 0);
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
goto nodelete;
|
|
goto nodelete;
|
|
@@ -5403,7 +5595,7 @@ xfs_bunmapi(
|
|
del.br_state = XFS_EXT_UNWRITTEN;
|
|
del.br_state = XFS_EXT_UNWRITTEN;
|
|
error = xfs_bmap_add_extent(ip, lastx, &cur,
|
|
error = xfs_bmap_add_extent(ip, lastx, &cur,
|
|
&del, firstblock, flist, &logflags,
|
|
&del, firstblock, flist, &logflags,
|
|
- XFS_DATA_FORK, 0);
|
|
|
|
|
|
+ delta, XFS_DATA_FORK, 0);
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
goto nodelete;
|
|
goto nodelete;
|
|
@@ -5456,7 +5648,7 @@ xfs_bunmapi(
|
|
goto error0;
|
|
goto error0;
|
|
}
|
|
}
|
|
error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
|
|
error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
|
|
- &tmp_logflags, whichfork, rsvd);
|
|
|
|
|
|
+ &tmp_logflags, delta, whichfork, rsvd);
|
|
logflags |= tmp_logflags;
|
|
logflags |= tmp_logflags;
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
@@ -5513,6 +5705,14 @@ nodelete:
|
|
ASSERT(ifp->if_ext_max ==
|
|
ASSERT(ifp->if_ext_max ==
|
|
XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
error = 0;
|
|
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:
|
|
error0:
|
|
/*
|
|
/*
|
|
* Log everything. Do this after conversion, there's no point in
|
|
* Log everything. Do this after conversion, there's no point in
|
|
@@ -5689,7 +5889,8 @@ xfs_getbmap(
|
|
nmap = (nexleft > subnex) ? subnex : nexleft;
|
|
nmap = (nexleft > subnex) ? subnex : nexleft;
|
|
error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
|
|
error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
|
|
XFS_BB_TO_FSB(mp, bmv->bmv_length),
|
|
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)
|
|
if (error)
|
|
goto unlock_and_return;
|
|
goto unlock_and_return;
|
|
ASSERT(nmap <= subnex);
|
|
ASSERT(nmap <= subnex);
|