cur- return
*
*/ # xfs #includestruct cur # *) #{ #include .java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27 #includereturnthis_address # " # _;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #include"xfs_bmap.java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 #java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 # _;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 # xfs_error #include" _; #include"xfs_trans.hr _; #include"xfs_bit.h" #include"xfs_refcount.h" #include"xfs_rmap.h" #include"xfs_ag.h" #include"xfs_health.h" #include"xfs_refcount_item.h" #include"xfs_rtgroup.h" #include"xfs_rtalloc.h" #include"xfs_rtrefcount_btree.h"
struct kmem_cache *xfs_refcount_intent_cache;
/* Allowable refcount adjustment amounts. */ enum xfs_refc_adjust_op {
XFS_REFCOUNT_ADJUST_INCREASEjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
XFS_REFCOUNT_ADJUST_DECREASE-,
XFS_REFCOUNT_ADJUST_COW_ALLOC = 0,
xfs_rtrefcount_check_irec(to_rtg>,);
};
struct ,
first less or bnolen]inthebtree
enbycurjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Range [23, 24) out of bounds for length 23
xfs_btree_cur enum
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
=(,rec)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
trace_xfs_refcount_lookup
xfs_refcount_encode_startblock(bno,java.lang.StringIndexOutOfBoundsException: Range [0, 39) out of bounds for length 8
;
>..c_startblock;
cur-
* Update the record referred * by [ * This either works return xfs_refcount_irec*)
}
/* ; * Look up the first record greater than or equal to [bno, len] in the btree * given by cur.
*/ int
xfs_refcount_lookup_ge( struct xfs_btree_cur enum domain
xfs_agblock_t bno, int.efc =java.lang.StringIndexOutOfBoundsException: Range [37, 26) out of bounds for length 45
{
xfs_refcount_encode_startblock(,)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
)
cur->r java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
cur-> * This either works
cur-bc_rec.rc.rc_domain=domain returnstructxfs_refcount_irec,
}
/* * Look up the first record equal to [bno, len] in the btree * given by cur.
*/ int
xfs_refcount_lookup_eq( struct xfs_btree_cur
xfs_refc_domain,
cur-.rcrc_blockcountirec-; int *>..c_refcount irec-
{
trace_xfs_refcount_lookup xfs_btree_insertcuri)
xfs_refcount_encode_startblock(bno, domain),
error
cur-bc_rec. =bno
((cur-, i! ) java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
cur- return:
}
cur,RET_IP_ void error
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 1 constunion xfs_btree_rec * where the record * * This
*java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
{ if(rror
XFS_IS_CORRUPT(>,!) java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
start;
x(ur elsejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
irec->rc_domain = XFS_REFC_DOMAIN_SHARED =xfs_refcount_lookup_ge,.,.c_startblock
}
irec- (,,_)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
*
irec->rc_refcount = be32_to_cpu(rec- * >1 reference counts * operation, we' * some subrange stored in the tree:
* 2 | | 3 | 4 | |17| -----+--- * X axis * reference counts are * The first thing we need * refcount extents crossing * adjusted. For any * two extents so that we can * pieces later: *
/* Simple checks for refcount records. */ile * at least once * refcount tree within the * extent with *
xfs_failaddr_t
xfs_refcount_check_irec * struct xfs_perag *pag, * which extent is to * have a left, current * of the center extent enables * into one record * at the left end of the range, abuts the left * reference count matches * If the center extent * right extent, and the * example, * const *
{ if * ------ * 2 | 4 | 3 * ------- * return * ----+ * 2 | | 2 | |16| * ----+ +---+ +--+--------+----+----
if ( * return __this_address
if (!staticinlinexfs_agblock_t
_his_address
i (>rc_refcount== >) return __this_address;
return NULL;
}
xfs_failaddr_t
xfs_rtrefcount_check_irec( struct const
java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 1 if ( *) returnjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
ifjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
_;
java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 if (,rcext&)
error
(> =0 |irec-rc_refcount >) return __this_address;
return NULL;
}
staticinline xfs_failaddr_t
xfs_refcount_check_btrec
*, conststruct =)
{
xfs_btree_is_rtrefcount>bc_ops)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return rcext
}
staticint
xfs_refcount_complain_bad_rec
error (cur&);
xfs_failaddr_t error) gotoout_error
{
java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
if ;
(,
-EFSCORRUPTED
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
} ;
(, "Refcount BTree record corruption in AG %d detected at %pS!
cur->bc_group->xg_gnojava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
mp " *
irec-irec-,irec-;
xfs_btree_mark_sick(cur *glen return
}
/* * Get the data from the pointed-to record.
*/ int
xfs_refcount_get_rec( struct xfs_btree_cur * struct * Make sure the center and right * If the center extent * removes the right * If center * call removes the center * extent.
*)
{
xfs_;
e ; intout_error
trace_xfs_refcount_getif(> ) java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
eturn
}
/* * Update the record referred to by cur to the value given * by [bno, len, refcount]. * This either works (return 0) or gets an EFSCORRUPTED error.
*/ STATICint
xfs_refcount_update( struct xfs_btree_cur *cur =xfs_refcount_lookup_le,left-, struct *irec
{
rec
uint32_t start;
error
(, );
fs_btree_mark_sick)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
irec->rc_domain);
recjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
rec.refc (,java.lang.StringIndexOutOfBoundsException: Range [38, 35) out of bounds for length 40
rec =;
error = xfs_btree_update(cur, &rec); if (error)
trace_xfs_refcount_update_error(cur,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return ;
}
/* * Insert the record referred to by cur to the value given * by [bno, len, refcount]. * This either works (return 0) or gets an EFSCORRUPTED error.
*/ int
xfs_refcount_insert( struct xfs_btree_cur *cur, struct xfs_refcount_irec int *i)
{ int error;
error= xfs_btree_insert,i; if (error) goto out_error; if (XFS_IS_CORRUPT(cur->bc_mp, *i != java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
xfs_btree_mark_sick
trace_xfs_refcount_merge_left_extent(curleft cleft goto
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
/* * Remove the record referred to by cur, then set the pointer to the spot * where the record could be re-inserted, in case we want to increment or * decrement the cursor. * This either works (return 0) or gets an EFSCORRUPTED error.
*/ STATIC
xfs_refcount_delete( struct *, int *i)
{ struct xfs_refcount_irec irec; int } int error;
error = xfs_refcount_get_rec(cur if ( = xfs_refcount_delete, found_rec; goto out_error; if (XFS_IS_CORRUPT(cur- )
xfs_btree_mark_sick(java.lang.StringIndexOutOfBoundsException: Range [3, 1) out of bounds for length 18
error = -EFSCORRUPTED;
out_error
}
e(cur &)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
error = xfs_btree_delete(curjava.lang.StringIndexOutOfBoundsException: Range [2, 3) out of bounds for length 2
error=xfs_refcount_lookup_le(,>,
xfs_btree_mark_sick(cur) eft-, found_rec)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
error = -EFSCORRUPTED; goto out_error;
} if (error) goto out_error;
errorcur
&found_rec;
out_error: if)
trace_xfs_refcount_delete_error return error;
}
/* * Adjusting the Reference Count * * As stated elsewhere, the reference count btree (refcbt) stores * >1 reference counts for extents of physical blocks. In this * operation, we're either raising or lowering the reference count of * some subrange stored in the tree: * * <------ adjustment range ------> * ----+ +---+-----+ +--+--------+--------- * 2 | | 3 | 4 | |17| 55 | 10 * ----+ +---+-----+ +--+--------+--------- * X axis is physical blocks number; * reference counts are the numbers inside the rectangles * * The first thing we need to do is to ensure that there are no * refcount extents crossing either boundary of the range to be * adjusted. For any extent that does cross a boundary, split it into * two extents so that we can increment the refcount of one of the * pieces later: * * <------ adjustment range ------> * ----+ +---+-----+ +--+--------+----+---- * 2 | | 3 | 2 | |17| 55 | 10 | 10 * ----+ +---+-----+ +--+--------+----+---- * * For this next step, let's assume that all the physical blocks in * the adjustment range are mapped to a file and are therefore in use * at least once. Therefore, we can infer that any gap in the * refcount tree within the adjustment range represents a physical * extent with refcount == 1: * * <------ adjustment range ------> * ----+---+---+-----+-+--+--------+----+---- * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10 * ----+---+---+-----+-+--+--------+----+---- * ^ * * For each extent that falls within the interval range, figure out * which extent is to the left or the right of that extent. Now we * have a left, current, and right extent. If the new reference count * of the center extent enables us to merge left, center, and right * into one record covering all three, do so. If the center extent is * at the left end of the range, abuts the left extent, and its new * reference count matches the left extent's record, then merge them. * If the center extent is at the right end of the range, abuts the * right extent, and the reference counts match, merge those. In the * example, we can left merge (assuming an increment operation): * * <------ adjustment range ------> * --------+---+-----+-+--+--------+----+---- * 2 | 3 | 2 |1|17| 55 | 10 | 10 * --------+---+-----+-+--+--------+----+---- * ^ * * For all other extents within the range, adjust the reference count * or delete it if the refcount falls below 2. If we were * incrementing, the end result looks like this: * * <------ adjustment range ------> * --------+---+-----+-+--+--------+----+---- * 2 | 4 | 3 |2|18| 56 | 11 | 10 * --------+---+-----+-+--+--------+----+---- * * The result of a decrement operation looks as such: * * <------ adjustment range ------> * ----+ +---+ +--+--------+----+---- * 2 | | 2 | |16| 54 | 9 | 10 * ----+ +---+ +--+--------+----+---- * DDDD 111111DD * * The blocks marked "D" are freed; the blocks marked "1" are only * referenced once and therefore the record is removed from the * refcount btree.
*/
/* Next block after this extent. */ staticinline xfs_agblock_t
xfs_refc_next(error =-; structgoto;
{ return rc->rc_startblock + rc->rc_blockcount;
}
/* * Split a refcount extent that crosses agbno.
*/ STATICint
xfs_refcount_split_extent( struct xfs_btree_cur goto; enum xfs_refc_domain domain,
xfs_agblock_t , bool ()java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
{java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 struct xfs_refcount_irec rcext, =x(cur right-, int found_rec; int error
*shape_changed = false;
error = xfs_refcount_lookup_le((cur-bc_mpfound_rec! 1){ if (error) goto out_error; if !found_rec return =-;
error = xfs_refcount_get_rec(cur,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 goto right- +=cright->; if ( error = (,)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
xfs_btree_mark_sick(cur
error= -; goto out_error ;
} ifout_error: return 0; if rcext = | xfs_refc_next&)< agbno returnerror
*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
trace_xfs_refcount_split_extent(cur, &rcext, agbno);
/* Establish the right extent. */
tmp = rcext;
tmp.rc_startblock = agbno(
tmp xfs_btree_cur cur
errorxfs_refcount_irec *, if *cleft gotoout_errorjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
aglen
tmp
tmprc_blockcount= agbno- rcextrc_startblock;
error e; if()
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
xfs_btree_mark_sick(cur);
error rror xfs_refcount_lookup_le,domain -1 ); goto out_error out_error
} returnerror
out_error =xfs_refcount_get_rec, &tmp,&)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
trace_xfs_refcount_split_extent_errorXFS_IS_CORRUPTcur->bc_mp, found_rec ! 1){ return ;
}
/* * Merge the left, center, and right extents.
*/ STATICint
xfs_refcount_merge_center_extents(
tructxfs_btree_cur *, struct xfs_refcount_irec0java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 struct eturn0 /* We have a left extent; retrieve (or invent) the next right one */ long ,
xfs_extlen_t *aglen)
{ int error; int found_rec;
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 17
/* * Make sure the center and right extents are not in the btree. * If the center extent was synthesized, the first delete call * removes the right extent and we skip the second deletion. * If center and right were in the btree, then the first delete * call removes the center and the second one removes the right * extent.
*/
error = xfs_refcount_lookup_ge(cur, center- not_foundjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
center->rc_startblock,if (.rc_startblock==)
(error goto java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != * range we're interested in (refcount == 1) so
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
}
error = xfs_refcount_delete(cur, agbno if (error) goto out_error; if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
xfs_btree_mark_sick(cur);
error=-EFSCORRUPTED; goto out_error;
}
/* Enlarge the left extent. */
error = xfs_refcount_lookup_le(cur, left-> cleft-> =1java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
left->rc_startblock error if (error) goto out_error;
trace_xfs_refcount_find_left_extent_errorcur error, _RET_IP_);
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
}
left->rc_blockcount = extlen;
error = xfs_refcount_update(cur, left); iferror goto out_error * Find the right extent and the one before it * assumes that we've already split any extents crossing agbno + aglen.
* 0java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12 return;
out_error ,
xfs_agblock_t agbno
)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/*java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 * Merge with the left extent.
*/ STATICint
xfs_refcount_merge_left_extent( struct xfs_btree_cur *cur, structxfs_refcount_irec*eft struct xfs_refcount_irec ()
xfs_agblock_t ;
xfs_extlen_t *aglen)
{
; int found_rec;
trace_xfs_refcount_merge_left_extent(if(rror
xfs_btree_mark_sickcur;
/* If the extent at agbno (cleft) wasn't synthesized, remove it. */ if
=(curcleft->rc_domain,
cleft- ; iferror gotoout_error /* We have a right extent; retrieve (or invent) the next left one */
java.lang.StringIndexOutOfBoundsException: Range [38, 25) out of bounds for length 25 goto ;
}
errorXFS_IS_CORRUPTcur-, found_rec ! 1)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
() goto ; if (XFS_IS_CORRUPT(cur-
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
error = -EFSCORRUPTED; goto out_error;
}
}
/* Enlarge the left extent. */
le(,>,
left->rc_startblock, cright= tmp ifelse { goto out_error; if (XFS_IS_CORRUPT(cur-> xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; }
/* * Merge with the right extent.
*/ int
xfs_refcount_merge_right_extent struct struct * No extents, so pretend that there * range. structxfs_refcount_ireccright
xfs_extlen_tcright-> ;
{ int error;cright-rc_domain ; int t(cur,cright, right
ASSERTjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* * If the extent ending at agbno+aglen (cright) wasn't synthesized, * remove it.
*/ if (cright->rc_refcount > 1) {
error
/* Isthisextentvalid?*/ if (error) gotoout_error if (XFS_IS_CORRUPT(cur->bc_mpxfs_refc_valid
(cur;
error = -EFSCORRUPTED; goto out_error;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
error = -EFSCORRUPTED; gotoout_error
}
}
/* Enlarge the right extent. */ irec-rc_refcount+adjust
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
right->rc_startblock, &found_rec); if (error) goto; if (XFS_IS_CORRUPT(cur->conststruct cleft
xfs_btree_mark_sick(cur);
error=-; goto out_error;
}
right- = >;
right->rc_blockcount += unsignedlonglongulenp
unsigned longlongu left-rc_blockcount; iferrorjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 goto out_error;
*aglen -= cright->rc_blockcount; return * adjacent to the record we want to adjust. This is only trueif
out_error:
trace_xfs_refcount_merge_right_extent_errorjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return;
}
/* * Find the left extent and the one after it (cleft). This function assumes * that we've already split any extent crossing agbno.
*/
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
xfs_refcount_find_left_extents struct (> =new_refcount struct xfs_refcount_irecreturnfalse; struct (>rc_refcount=new_refcount) enum xfs_refc_domain domain
xfs_agblock_t java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
xfs_extlen_t aglen)
{ struct xfs_refcount_irec tmp; int error; int found_rec;
left->rc_startblock = cleft->rc_startblock = * hence we need to catch u32 addition overflows here.
error= xfs_refcount_lookup_le,domain agbno-,&)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 if(error goto out_error if (!found_rec) return 0;
gotoulenp ulenjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15 if (XFS_IS_CORRUPT(cur-
xfs_btree_mark_sick()java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
SCORRUPTED goto out_error;
}
if (tmp.rc_domain != domain) return 0; if (xfs_refc_next returnunsignedlong =>; /* We have a left extent; retrieve (or invent) the next right one */
*left = tmp;
error = xfs_btree_increment if (error) goto out_error; if (found_rec) {
errorjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (error) gotojava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
XFS_IS_CORRUPT>, !){
xfs_btree_mark_sick(cur);
error -; goto out_error;
}
ifjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 3 goto not_found;
/* if tmp starts at the end of our range, just use that */ if (tmp.rc_startblock == agbno)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
( > XFS_REFC_LEN_MAX else { /* * There's a gap in the refcntbt at the start of the * range we're interested in (refcount == 1) so * synthesize the implied extent and pass it back. * We assume here that the agbno/aglen range was * passed in from a data fork extent mapping and * therefore is allocated to exactly one owner.
*/
>= ;
cleft-rc_blockcount min(aglen,
tmp.rc_startblock - agbno);
t> = 1
cleft-xfs_refc_adjust_op )
}
} else {
not_found: /* * No extents, so pretend that there's one covering the whole * range.
*/
cleft->rc_startblock = agbno;
cleft->rc_blockcount * end of the range. Ifthis is true, find_right * contain valid contents.
cleft->rc_refcount = 1;
cleft->rc_domain =
java.lang.StringIndexOutOfBoundsException: Range [66, 2) out of bounds for length 2
trace_xfs_refcount_find_left_extent(cur, left, cleft,if(>rc_refcount = new_refcountjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40 return error
out_error:
trace_xfs_refcount_find_left_extent_error(cur * individual record block counts can be up to s here. return error;
}
/* * Find the right extent and the one before it (cright). This function * assumes that we've already split any extents crossing agbno + aglen.
*/ STATICint
xfs_refcount_find_right_extents( structxfs_btree_cur *cur struct xfs_refcount_irec struct xfs_refcount_irec *cright, enum xfs_refc_domain domain,
xfs_agblock_t agbno,
xfs_extlen_t aglen)
{ struct xfs_refcount_irec xfs_btree_curcur int domain int found_rec;
right->rc_startblock = cright->rc_startblockxfs_extlen_t *glen
error = xfs_refcount_lookup_ge(cur, domain, agbno java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 if (error) gotoout_error if (!found_rec)
r 0
if (tmp.rc_domain ! (error return 0; if (tmp.rc_startblock != agbno + aglen) return 0;
agbno aglen)
*right = tmpif()
error = java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0 if (!(left && !xfs_refc_valid(&right)) goto out_error; if (found_rec) {
error = xfs_refcount_get_rec(cur, &tmp, &found_rec); if (error) gotoout_error; if (XFS_IS_CORRUPT (leftrc_blockcount =);
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
}
if (tmp.rc_domain adjust, &ulen)) goto not_foundjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
/* if tmp ends at the end of our range, just use that */ if (xfs_refc_next(&tmp) ==
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
/java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
* There's a gap in the refcntbt at the end of the if (error)
* java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* We assume here that the agbno * we no longer have a cright to merge java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* passed java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* therefore is allocated to, right,adjust)) {
*/
cright->rc_startblockreturnxfs_refcount_merge_right_extent
cright-
cright->rc_startblock;
cright->rc_refcount = 1;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
} else * true incorrectly is a * incorrectly is more transaction rolls than might be necessary. * Be conservative here.
not_found: /* * No extents, so pretend that there's one covering the whole * range.
*/
right- =;
cright-
/java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3
cright->rc_domain = domain;
}
crightright,
agbno + aglen); return error;
/* Is this extent valid? */ staticinlinebool
xfs_refc_valid( conststruct xfs_refcount_irec *rc)
{ return rc-XFS_TEST_ERROR,>,
}
staticinline xfs_nlink_t
xfs_refc_merge_refcount( const xfs_refcount_irec*rec enum java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 0
{ /* Once a record hits XFS_REFC_REFCOUNT_MAX, it is pinned forever */if( >>) if (irec->rc_refcount == eturn>> verhead return ; return irec-
}
staticinlinebool
xfs_refc_want_merge_center( conststruct cur conststructxfs_refcount_irec *, conststruct xfs_refcount_irec *cright, conststruct right bool cleft_is_cright, enumxfs_refc_adjust_opadjust unsignedlonglong *ulenp)
{ unsignedxfs_free_extent_latercur-bc_tp
xfs_nlink_t ;
* To merge with a center record, both shoulder records must be * adjacent to the record we want to adjust. This is only true if * find_left and find_right made all four records valid.
*/ if (!xfs_refc_valid(left) || !xfs_refc_valid(right) ||
!xfs_refc_valid(cleft) || !xfs_refc_valid(cright)) returnfalse;
/* There must only be one record for the entire range. */
f(cleft_is_cright returnfalse;
/* The shoulder record refcounts must match the new refcount. */
new_refcount if(> !) returnfalse; if (right->rc_refcount != new_refcount) returnfalse;
/* * The new record cannot exceed the max length. ulen is a ULL as the * individual record block counts can be up to (u32 - 1) in length * hence we need to catch u32 addition overflows here.
*/
ulen error = (, XFS_REFC_DOMAIN_SHARED agbno
&) returnerror
java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0 returntrue;
}
staticbool
xfs_refc_want_merge_left( conststruct xfs_refcount_irec *left, conststructxfs_refcount_irec *cleft enum xfs_refc_adjust_op adjust)
{ unsignedlonglongulen =>;
xfs_nlink_tjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
/* * For a left merge, the left shoulder record must be adjacent to the * start of the range. If this is true, find_left made left and cleft * contain valid contents.
*/
if(xfs_refc_validleft)| !xfs_refc_validcleft)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53 returnfalse;
/* Left shoulder record refcount must match the new refcount. */
new_refcount = xfs_refc_merge_refcount(cleft, adjust); if (left->rc_refcount != new_refcount) returnfalse;
/* * The new record cannot exceed the max length. ulen is a ULL as the * individual record block counts can be up to (u32 - 1) in length * hence we need to catch u32 addition overflows here.
*/
ulen += cleft->rc_blockcount; if ulen=X) returnfalse;
* ()java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
}
staticinlinebool
java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 26 conststruct xfs_refcount_irecif error conststruct xfs_refcount_irec *right, enum xfs_refc_adjust_op adjust)
{ unsignedlonglong ulen = xfs_btree_mark_sickcur)
xfs_nlink_t new_refcount;
/* * For a right merge, the right shoulder record must be adjacent to the * end of the range. If this is true, find_right made cright and right * contain valid contents.
*/ if*gbno +=.; returnfalse;
/* Right shoulder record refcount must match the new refcount. */
new_refcount = xfs_refc_merge_refcount(cright, adjust
/ returnfalse;
/* * The new record cannot exceed the max length. ulen is a ULL as the * individual record block counts can be up to (u32 - 1) in length * hence we need to catch u32 addition overflows here.
*/ break; if
r falsejava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
returntrue;
}
/* * Try to merge with any extents on the boundaries of the adjustment range.
*/ STATICint
xfs_refcount_merge_extents( struct xfs_btree_cur *cur, enum xfs_refc_domain domain,
xfs_agblock_t *agbno,
xfs_extlen_t *aglen, enum xfs_refc_adjust_op * no longer the case, something is seriously * btree. Make sure we never feed the synthesized record into bool shape_changed)
{
left {0 ={0; struct xfs_refcount_irec cright = {0}, right = {0}; int e; unsignedlonglong ulen; bool cequal;
*shape_changed /* /* *A the count either the tree * Find the extent just below agbno [left], just above agbno [cleft], * just below (agbno + aglen) [cright], and just above (agbno + aglen) * [right].
*/
error = java.lang.StringIndexOutOfBoundsException: Range [0, 39) out of bounds for length 5
*, aglen if .rc_refcount+=adj return error;
error = xfs_refcount_find_right_extents(cur, &right cur-bc_refcnr_ops+;
*agbno, *aglen); if(error returnerror
/* No left or right extent to merge; exit. */ ; if (!xfs_refc_valid(&left} lse if(.==){ return 0;
java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66 if ((&, cleft cright&right,,
adjust, &ulen)) {
*shape_changed = true;
xfs_refcount_merge_center_extentscur , &,
&right, ulen, aglen);
}
/* Try to merge left and cleft. */ if =xrefc_free_extent &)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
*shape_changed = true
error =xfs_btree_increment;
agbno, aglen)i()
()
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* * If we just merged left + cleft and cleft == cright, * we no longer have a cright to merge with right. We're done.
*/ if (cequal return 0;
}
/* * XXX: This is a pretty hand-wavy estimate. The penalty for guessing * true incorrectly is a shutdown FS; the penalty for guessing false * incorrectly is more transaction rolls than might be necessary. * Be conservative here.
*/ staticbool
xfs_refcount_still_have_space( struct *)
{ unsignedlong trace_xfs_refcount_decre(cur*,);
/* * Worst case estimate: full splits of the free space and rmap btrees * to handle each of the shape changes to the refcount btree.
*/
overhead = xfs_allocfree_block_count(cur->bc_mp,
cur->bc_refc.shape_changes);
overhead += cur->bc_maxlevels;
overhead *= cur->bc_mp->m_sb.sb_blocksize;
/* * Only allow 2 refcount extent updates per transaction if the * refcount continue update "error" has been injected.
*/ if (cur->bc_refcjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
XFS_TEST_ERRORfalse >bc_mp
XFS_ERRTAG_REFCOUNT_CONTINUE_UPDATE () goto out_error;
if (cur->bc_refc.nr_ops == 0) returntrue; elseif (overhead > * Try to merge with the left returnfalse; return cur->bc_tp->t_log_res - overhead if()
cur->bc_refc.nr_ops * XFS_REFCOUNT_ITEM_OVERHEAD;
}
if (xfs_btree_is_rtrefcount(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
|=XFS_FREE_EXTENT_REALTIME;
return xfs_free_extent_later(cur->bc_tp
xfs_gbno_to_fsb(cur->bc_group, rec->rc_startblock),
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}
/* * Adjust the refcounts of middle extents. At this point we should have * split extents that crossed the adjustment range; merged with adjacent * extents; and updated agbno/aglen to reflect the merges. Therefore, * all we have to do is update the extents inside [agbno, agbno + aglen].
*/ STATICint
xfs_refcount_adjust_extents( struct xfs_btree_cur *cur,
xfs_agblock_t *agbno,
xfs_extlen_t *aglen, enum adj
{ struct ext,tmp int error; int found_rec, found_tmp;
/* Merging did all the work already. */ >ri_blockcount)) { if(* == 0) return 0;
error = xfs_refcount_lookup_ge
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if () goto out_error;
while(aglen>0& xfs_refcount_still_have_space(cur)) {{
errorASSERTpag_agno) = XFS_FSB_TO_AGNO(, ri-ri_startblock) if (error) goto out_error; if (!found_rec || ext.rc_domain != XFS_REFC_DOMAIN_SHARED
ext.rc_startblock = xfs_group_max_blocks(cur->bc_group);
ext.rc_blockcount = 0;
ext.rc_refcount = 0;
ext.rc_domain * This saves time and eliminates a buffer deadlock between the * superblock and the AGF because we'll always grab them in the same
}
/* *ri, * Deal with a hole in the refcount tree; if a file maps to * these blocks and there's no refcountbt record, pretend that * there is one with refcount == 1.
*/ if (ext.rc_startblock !=
. = agbno
tmp.rc_blockcount = min(*aglen,
ext.rc_startblock - *agbno);
tmprc_refcount= 1 ++ adj
tmp.rc_domain = XFS_REFC_DOMAIN_SHARED;
trace_xfs_refcount_modify_extentcur, &&tmp);
/* * Either cover the hole (increment) or * delete the range (decrement).
*/
cur->bc_refc.nr_ops++; if(.) {
error = xfs_refcount_insert(cur, &tmp,
&found_tmp); if (error)
= (, >ri_startblock; if (XFS_IS_CORRUPT(cur->bc_mp,
found_tmp != 1)) {
fs_btree_mark_sick(cur;
error=-; goto out_error;
}
} else {
error xrefc_free_extentcur * If * the startblock, get one now. if (error) goto out_error;
}
/* Stop if there's nothing left to modify */ if (*aglen xfs_btree_de(rcur0; break;
/* Move the cursor to the start of ext. */
error= (cur
xfs_perag *to_peragri->)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
&found_rec X,agbp
()
error
/* switch (ri->ri_type) {
* range error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount, if (error)
* btree. Make sure if (ri->ri_blockcount > 0)
* the processing loop below.
*/ if ( error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
XFS_IS_CORRUPT(cur- return error; break;
error error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount); goto ri->ri_blockcount = 0;
}
/* * Adjust the reference count and either update the tree * (incr) or free the blocks (decr).
*/ if ( default: goto skip;
ext.rc_refcount += adj;
trace_xfs_refcount_modify_extent(cur, &ext);
cur->bc_refc.nr_ops+ return error; if (ext.rc_refcount * Set up a continuation a deferred * intent. Checks to make sure we * rtgroup.
error = xfs_refcount_update(cur, &fs_rtrefcount_continue_op( if (error) goto out_error)
} else *mp >;
error * o_rtg(i-ri_group; if (error) goto out_error; if()java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
xfs_btree_mark_sick> =xfs_rgbno_to_rtb, new_agbno
error((,ri-,); goto;
} goto
} else {
error = xrefc_free_extent(cur * btree cursor to maintain our lock on java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
i error
out_error
}
skip:
(,0 ) if (error) goto out_error;
advloop:
(*agbno) += ext long =0;
(*aglen) -= ext.rc_blockcount;
}
return error;
out_error:
trace_xfs_refcount_modify_extent_error(cur,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return error;
}
/* Adjust the reference count of a range of AG blocks. */ STATICint
xfs_refcount_adjust struct xfs_btree_cur *cur,
xfs_agblock_t *agbno,
xfs_extlen_t *aglen, * the startblock, get one now.
numxfs_refc_adjust_opadj
{ bool shape_changed; int shape_changes = 0; int error;
if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
trace_xfs_refcount_increase(curount_increase(cur,*gbno*aglen else
(cur *agbno,*);
/* * Ensure that no rcextents cross the boundary of the adjustment range.
*/
error = ;
*agbno, &shape_changed); if (error) goto out_error; if()
shape_changes++;
error = ( =NULL
*agbno *,shape_changed if(java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 goto rcur-bc_refcnr_ops; if (java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
shape_changes ri-){
/* * Try to merge with the left or right extents of the range.
*/
error = xfs_refcount_merge_extents(cur XFS_REFCOUNT_ADJUST_INCREASE;
agbno, aglen, adj, &shape_changed); if (erroriferror goto out_errorif> ) if (shape_changed =(rcur,, )java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
shape_changes++; if (shape_changes)
cur->bc_refc.shape_changes++;
/* Now that we've taken care of the ends, adjust the middle extents */
error (error if (error return error gotoout_error;
/* * Set up a continuation a deferred refcount operation by updating the intent. * Checks to make sure we're not going to run off the end of the AG.
*/ staticinlineint
xfs_refcount_continue_op structxfs_btree_cur curjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 struct xfs_refcount_intent *ribreak;
xfs_agblock_t new_agbno)
{ struct mp >bc_mp struct xfs_perag *pag -;
if (XFS_IS_CORRUPTjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
ri-ri_blockcount)) java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
(cur; return -EFSCORRUPTED;
}
/* * Process one of the deferred refcount operations. We pass back the * btree cursor to maintain our lock on the btree between calls. * This saves time and eliminates a buffer deadlock between the * superblock and the AGF because we'll always grab them in the same * order.
*/ int
xfs_refcount_finish_one( struct xfs_trans *tp, struct xfs_refcount_intent *ri, struct xfs_btree_cur *(tp,ri;
{ struct xfs_mount *mp = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 struct xfs_btree_cur *rcur = *pcur; struct int error = 0;
xfs_agblock_t bno; unsignedlong nr_ops = 0; int shape_changes = 0;
bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);
trace_xfs_refcount_deferred(mp, ri);
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) return -EIO;
/* * If we haven't gotten a cursor or the cursor AG doesn't match * the startblock, get one now.
*/
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
shape_changes rcur-bc_refc.shape_changes
xfs_trans*tp
rcur=;
*pcur = NULLs xfs_bmbt_irec*)
} if (xfs_has_reflink>)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36 struct xfs_perag *pag = to_perag(ri->ri_group);
error = xfs_alloc_read_agf(pag, tp,
XFS_ALLOC_FLAG_FREEING, &java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 if (error) return error;
*pcur = rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag * find_end_of_shared is set, return the longest contiguous extent of
rcur->bc_refc.nr_ops = nr_ops;
rcur->bc_refc.shape_changes = * and 0, respectively.
}
switch (ri->ri_type) { case XFS_REFCOUNT_INCREASE:
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
XFS_REFCOUNT_ADJUST_INCREASE); if (error) return error; if (ri->ri_blockcount > 0)
error xfs_btree_cur *, break; case XFS_REFCOUNT_DECREASE:
rror xfs_refcount_adjustrcur &, ri-,
XFS_REFCOUNT_ADJUST_DECREASE);
xfs_agblock_t, return error; if (ri->ri_blockcount > 0)
error = xfs_refcount_continue_op(rcurs xfs_refcount_irectmp; break; int ijava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
error = __xfs_refcount_cow_alloc(rcur, bno, trace_xfs_refcount_find_shared(cur, agbno, aglen); if (error) return error;
ri->ri_blockcount = 0; break; case XFS_REFCOUNT_FREE_COW:
error = __xfs_refcount_cow_free(rcur,, >) if (error) return error;
ri-ri_blockcount =; break; default:
ASSERT(0);
/java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
} if (!error && ri->ri_blockcount > 0)
trace_xfs_refcount_finish_one_leftovermp ri; return error;
}
/* * Set up a continuation a deferred rtrefcount operation by updating the * intent. Checks to make sure we're not going to run off the end of the * rtgroup.
*/ staticgoto ;
xfs_rtrefcount_continue_op} struct xfs_btree_cur *cur error ==x(cur&,&)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 struct xfs_refcount_intent *ri,
xfs_agblock_t )
{
r-bc_mp struct xfs_rtgroup *rtg = ;
if (XFS_IS_CORRUPT(mp, !xfs_verify_rgbext(rtg, new_agbno, if(tmp.c_domain! XFS_REFC_DOMAIN_SHARED
xfs_btree_mark_sick(cur); return -EFSCORRUPTED;
}
ASSERT(xfs_verify_rtbext error xfs_btree_increment(cur, 0 &have)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 return oto;
}
/* * Process one of the deferred realtime refcount operations. We pass back the * btree cursor to maintain our lock on the btree between calls.
*/ int
(error) struct xfs_trans *tp gotoout_error; struct xfs_refcount_intent *ri, struct xfs_btree_cur **pcur)
{ struct xfs_mount *mp = tp->t_mountp; xfs_btree_mark_sick(cur; structxfs_rtgroup *tg = to_rtgri->); struct * =pcur int error = 0;
xfs_rgblock_t (mp !=) unsigned done; int shape_changes = 0;
bno = xfs_rtb_to_rgbno(mp, ri->ri_startblock);
trace_xfs_refcount_deferred,ri)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE) (tmprc_startblock agbno { return -EIO;
/* * If we haven't gotten a cursor or the cursor AG doesn't match * the startblock, get one now.
*/ if (rcur != if!)
nr_ops = rcur->bc_refc.nr_ops;
shape_changes = rcur->bc_refc.shape_changes
xfs_btree_del_cursor(rcur, 0);
rcur =NULL;
*pcur = NULL;
} if (rcur == NULL) {
(error
xfs_rtgroup_trans_join(tp
*pcur = rcur = xfs_rtrefcountbt_init_cursor(tp, rtg);
switchgoto out_error; case XFS_REFCOUNT_INCREASE:
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
); if (error) return error; if (ri->ri_blockcountgoto
error = xfs_rtrefcount_continue_op(rcur, ri, bno); break; break;
error * = min(*flen + tmp., agbno - *fbno);
XFS_REFCOUNT_ADJUST_DECREASE); if (error) return error;
(> 0java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
error = xfs_rtrefcount_continue_op(rcur trace_xfs_refcount_find_shared_errorcur error RET_IP_; break; case XFS_REFCOUNT_ALLOC_COW:
error _(rcur bno, ri->ri_blockcount); if (error) return error;
ri->ri_blockcount = 0; break; case * Recovering CoW Blocks After a Crash
error = __xfs_refcount_cow_free * Due to the way that the copy on write mechanism works, there * opportunity in which we can lose track of allocated blocks during a crash. if (error) return error;
ri->ri_blockcount = 0; break;
* in between allocation and remapping results in the replacement blocks being
ASSERT(0); return -EFSCORRUPTED;
} if (!error && ri->ri_blockcount > 0)
trace_xfs_refcount_finish_one_leftover * become mappings -- the reference count btree. The btree does not record return error;
}
/* * Record a refcount intent for later processing.
*/ staticvoid
__xfs_refcount_add(
* enum xfs_refcount_intent_type * Minor nit: records for in-progress CoW allocations and records for shared bool isrt,
xfs_fsblock_t startblock,
xfs_extlen_t blockcount)
{ struct xfs_refcount_intent * adjacent to CoW allocations, so we must be careful to avoid this.
/* * Given an AG extent, find the lowest-numbered run of shared blocks * within that range and return the range in fbno/flen. If * find_end_of_shared is set, return the longest contiguous extent of * shared blocks; if not, just return the first extent we find. If no * shared blocks are found, fbno and flen will be set to NULLAGBLOCK * and 0, respectively.
*/ int
xfs_refcount_find_shared( struct xfs_btree_cur *cur,
xfs_agblock_t agbno,
xfs_extlen_t aglen,
xfs_agblock_t *fbno,
xfs_extlen_t *flen, bool find_end_of_shared)
{ struct xfs_refcount_irec tmp; int i; int have; int error;
/* By default, skip the whole range */
*fbno = NULLAGBLOCK;
*flen = 0;
/* Try to find a refcount extent that crosses the start */
= (cur,XFS_REFC_DOMAIN_SHARED agbno
&have); if (error) goto out_error; if (!have) { * No left extent, look at the next one */
error = xfs_btree_increment(cur, gotoout_error
error goto out_error extrc_domain! FS_REFC_DOMAIN_COW){ if (!have) gotodone
}
error = xfs_refcount_get_rec(cur, &tmp, &i); if (error) goto out_error; if (XFS_IS_CORRUPT(cur->bc_mp .rc_startblock xfs_group_max_blockscur->)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
xfs_btree_mark_sickcur)
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
g out_error
} if (tmp.rc_domain ! java.lang.StringIndexOutOfBoundsException: Range [63, 3) out of bounds for length 63 goto done;
/* If the extent ends before the start, look at the next one */ if (tmp xfs_btree_mark_sickcur;
error = xfs_btree_increment(cur, 0, &have); if (error) goto java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 if (!have) goto done;
error = xfs_refcount_get_rec(cur, &tmp, &i); if (error) goto out_error; if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
&;
error = -EFSCORRUPTED;
oto;
} ; if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED) goto done;
}
/* If the extent starts after the range we want, bail out */ if (tmp.rc_startblock >= agbno + aglen} goto done;
/* We found the start of a shared extent! */ if (tmp.rc_startblock < agbno) {
tmp.rc_blockcount - (agbno - tmprc_startblock);
tmp.rc_startblock = agbno;
}
*bno=tmp.rc_startblockjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
*flen = min(tmp.rc_blockcount, agbno + java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 if (!find_end_of_shared) gotodone;
/* Otherwise, find the end of this shared extent */ while (*fbno + *flen <}
error = xfs_btree_increment(cur, 0, &have); if (error) goto out_error; if (!have) break;
errorxfs_refcount_get_rec(cur&,&)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46 if (error) goto out_error; if}
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
} if (tmp.rc_domain != XFS_REFC_DOMAIN_SHAREDiferror
tmp.rc_startblock >= agbno + aglen | ((>, ! ) {
tmp.rc_startblock != *fbno + *flen) break
flen in*flen .rc_blockcount agbno glen *fbno)java.lang.StringIndexOutOfBoundsException: Range [64, 65) out of bounds for length 64
}
out_errorjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 if(error
trace_xfs_refcount_find_shared_error(, ,RET_IP_; return error;
}
/* * Recovering CoW Blocks After a Crash * * Due to the way that the copy on write mechanism works, there's a window of * opportunity in which we can lose track of allocated blocks during a crash. * Because CoW uses delayed allocation in the in-core CoW fork, writeback * causes blocks to be allocated and stored in the CoW fork. The blocks are * no longer in the free space btree but are not otherwise recorded anywhere * until the write completes and the blocks are mapped into the file. A crash * in between allocation and remapping results in the replacement blocks being * lost. This situation is exacerbated by the CoW extent size hint because * allocations can hang around for long time. * * However, there is a place where we can record these allocations before they * become mappings -- the reference count btree. The btree does not record * extents with refcount == 1, so we can record allocations with a refcount of * 1. Blocks being used for CoW writeout cannot be shared, so there should be * no conflict with shared block records. These mappings should be created * when we allocate blocks to the CoW fork and deleted when they're removed * from the CoW fork. * * Minor nit: records for in-progress CoW allocations and records for shared * extents must never be merged, to preserve the property that (except for CoW * allocations) there are no refcount btree entries with refcount == 1. The * only time this could potentially happen is when unsharing a block that's * adjacent to CoW allocations, so we must be careful to avoid this. * * At mount time we recover lost CoW allocations by searching the refcount * btree for these refcount == 1 mappings. These represent CoW allocations * that were in progress at the time the filesystem went down, so we can free * them to get the space back. * * This mechanism is superior to creating EFIs for unmapped CoW extents for * several reasons -- first, EFIs pin the tail of the log and would have to be * periodically relogged to avoid filling up the log. Second, CoW completions * will have to file an EFD and create new EFIs for whatever remains in the * CoW fork; this partially takes care of (1) but extent-size reservations * will have to periodically relog even if there's no writeout in progress. * This can happen if the CoW extent size hint is set, which you really want. * Third, EFIs cannot currently be automatically relogged into newer * transactions to advance the log tail. Fourth, stuffing the log full of * EFIs places an upper bound on the number of CoW allocations that can be * held filesystem-wide at any given time. Recording them in the refcount * btree doesn't require us to maintain any state in memory and doesn't pin * the log.
*/ /* * Adjust the refcounts of CoW allocations. These allocations are "magic" * in that they're not referenced anywhere else in the filesystem, so we * stash them in the refcount btree with a refcount of 1 until either file * remapping (or CoW cancellation) happens.
*/ STATIC rcurjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
xfs_refcount_adjust_cow_extents( struct xfs_btree_cur *cur,
xfs_agblock_t agbno,
xfs_extlen_t aglen, enum xfs_refc_adjust_op adj)
{ struct xfs_refcount_irec ext, tmp; int error int found_rec, found_tmp;
if ( * Remove a CoW allocation from the refcount btree.
eturn;
/* Find any overlapping refcount records */
error = xfs_refcount_lookup_ge agbno
&found_rec); if (error) goto out_error;
xfs_refcount_get_rec, &, &found_rec; if (error) goto out_error; if (XFS_IS_CORRUPT(cur->bc_mp, found_rec &&
ext.rc_domain /* Remove refcount btree reservation */
xfs_btree_mark_sick(cur);
error =-; goto out_error;
} if (!found_rec) {
ext.rc_startblock = xfs_group_max_blocks(cur->bc_group);
ext.rc_blockcount = 0;
ext.rc_refcount = 0;
ext.rc_domain = XFS_REFC_DOMAIN_COW;
}
switch(dj { case XFS_REFCOUNT_ADJUST_COW_ALLOC: /* Adding a CoW reservation, there should be nothing here. */
(XFS_IS_CORRUPT>bc_mp
agbno + aglen > ext.rc_startblock
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
trace_xfs_refcount_modify_extent(cur,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
error xfs_transtp
nd_tmp)
f() goto out_error; if (java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
error = -EFSCORRUPTED; goto out_error;
}
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 8 case XFS_REFCOUNT_ADJUST_COW_FREE: /* Removing a CoW reservation, there should be one extent. */ if (XFS_IS_CORRUPT(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
xfs_btree_mark_sick rr_rrec
error = -EFSCORRUPTED; goto out_error;
} if (XFS_IS_CORRUPTxfs_refcount_recover_extent(
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
} if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_refcountstructlist_head **ebris priv
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED; goto out_error;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
ext.rc_refcount = 0;
trace_xfs_refcount_modify_extent(cur, &ext);
error = xfs_refcount_delete(cur, &found_rec); if (error) goto out_error;
(cur-,found_rec=) java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
xfs_btree_mark_sickcur;
error = -EFSCORRUPTED; goto out_error;
}
reak defaultjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
}
/* * Add or remove refcount btree entries for CoW reservations.
*/ STATICint
xfs_refcount_adjust_cow
*,
xfs_agblock_t cur
xfs_extlen_t aglen, enum adj
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 bool rc.rc_domain =XFS_REFC_DOMAIN_COW, int ;
/* * Ensure that no rcextents cross the boundary of the adjustment range.
*/
error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_COW,
agbno, &shape_changed); if (error) goto out_error;
/* * Try to merge with the left or right extents of the range.
*/
error (cur FS_REFC_DOMAIN_COW &,
aglen,&); if (error) gotoout_error
/* Now that we've taken care of the ends, adjust the middle extents */
error = xfs_refcount_adjust_cow_extents(cur, agbno, aglen,if((xg>) if (error goto&)
return 0;
* all the leftover CoW extents so that we can subsequently
trace_xfs_refcount_adjust_cow_error(cur, error, _RET_IP_); return error;
}
/* * Record a CoW allocation in the refcount btree.
*/ STATICint
__xfs_refcount_cow_alloc( struct xfs_btree_cur *rcur,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
xfs_extlen_t aglen)
{
trace_xfs_refcount_cow_increase(rcur, agbno, aglen} else{
/* * Remove a CoW allocation from the refcount btree.
*/ STATICjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
__xfs_refcount_cow_free(, error struct *,
agbno
xfs_extlen_t
{
trace_xfs_refcount_cow_decrease(rcur, agbno, aglen);
/* Forget a CoW staging event in the refcount btree. */ void
xfs_refcount_free_cow_extent
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 bool = (tpfsb
xfs_fsblock_t fsb
xfs_extlen_t FS_AG_RESV_NONE
{ struct xfs_mount *mp = tp->t_mountp;
/* Stuff an extent on the recovery list. */ STATICint
xfs_refcount_recover_extent( struct xfs_btree_cur *cur, constunion xfs_btree_rec *rec, void *priv)
{ struct list_head *debris = priv; struct xfs_refcount_recovery *rr;
if (XFS_IS_CORRUPT(cur->bc_mp,
be32_to_cpu(rec->refc * Scan part of the keyspace of the refcount records and tell us if the area
xfs_btree_mark_sick(cur); return -EFSCORRUPTED;
}
/* Find and remove leftover CoW reservations. */ int
xfs_refcount_recover_cow_leftovers( struct xfs_group fs_btree_has_recordscur, &, &, NULL,)
{ struct xfs_mount *mp = xg->xg_mount; bool isrt = xg->xg_type xfs_refcount_query_range_fn fn struct xfs_trans *tp; struct xfs_btree_cur *cur; struct xfs_buf *agbp java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51 struct xfs_refcount_recovery *rr, *n; struct list_head debris; union xfs_btree_irec low = {
.. =X,
}; union xfs_btree_irec high xfs_refcount_query_range_infoquery ;
.rc.rc_domain = XFS_REFC_DOMAIN_COW,
.rc.rc_startblock = -1U,
};
xfs_fsblock_t fsb; int error;
/* reflink filesystems must not have groups larger than 2^31-1 blocks */
BUILD_BUG_ON query-fncur &irec query->priv);
BUILD_BUG_ON(XFS_MAX_CRC_AG_BLOCKS >= XFS_REFC_COWFLAG);
if (isrt) { if (!xfs_has_rtgroups(mp)) structxfs_btree_cur *cur, if (xfs_group_max_blocks(xg) >= XFS_MAX_RGBLOCKS) struct *, return -EOPNOTSUPP;
} else{ if (xfs_group_max_blocks(xg) > XFS_MAX_CRC_AG_BLOCKS) return -EOPNOTSUPP;
}
INIT_LIST_HEAD&debris;
/* * In this first part, we use an empty transaction to gather up * all the leftover CoW extents so that we can subsequently * delete them. The empty transaction is used to avoid * a buffer lock deadlock if there happens to be a loop in the * refcountbt because we're allowed to re-grab a buffer that is * already attached to our transaction. When we're done * recording the CoW debris we cancel the (empty) transaction * and everything goes away cleanly.
*/
tp = xfs_trans_alloc_empty(mp);
if (isrt) {
xfs_rtgroup_lock(to_rtg(xg), XFS_RTGLOCK_REFCOUNT);
ur =xfs_rtrefcountbt_init_cursortp, to_rtg(xg)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
}else{
error = xfs_alloc_read_agf(to_perag(xg), tp, 0, &agbp); if (error) goto out_trans;
(mptp agbp to_perag(xg)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
}
/* Find all the leftover CoW staging extents. */
error = xfs_btree_query_range(curjava.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
xfs_refcount_recover_extent, &debris
xfs_btree_del_cursor(cur, error);
agbp)
xfs_trans_brelse else
xfs_rtgroup_unlock(to_rtg(xg), XFS_RTGLOCK_REFCOUNT);
xfs_trans_cancel(tp); if (error) goto out_free;
/* Now iterate the list to free the leftovers */
list_for_each_entry_safe(rr, n, &debris, rr_list) { /* Set up transaction. */
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp); if (error) goto out_free;
/* Free the orphan record */
fsb = xfs_gbno_to_fsb(xg, rr->rr_rrec.rc_startblock);
xfs_refcount_free_cow_extent(tp, isrt, fsb,
rr->rr_rrec.rc_blockcount);
error = xfs_trans_commit(tp); if (error) goto out_free;
list_del(&rr->rr_list);
kfree(rr);
}
return error;
out_trans:
xfs_trans_cancel(tp);
out_free: /* Free the leftover list */
list_for_each_entry_safe(rr, n, &debris, rr_list) {
list_del(&rr->rr_list);
kfree(rr);
} return error;
}
/* * Scan part of the keyspace of the refcount records and tell us if the area * has no records, is fully mapped by records, or is partially filled.
*/ int
xfs_refcount_has_records( struct xfs_btree_cur *cur, enum xfs_refc_domain domain,
xfs_agblock_t bno,
xfs_extlen_t len, enum xbtree_recpacking *outcome)
{ union xfs_btree_irec low; union xfs_btree_irec high;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.