|
@@ -1133,6 +1133,7 @@ xfs_dialloc_ag_inobt(
|
|
int error;
|
|
int error;
|
|
int offset;
|
|
int offset;
|
|
int i, j;
|
|
int i, j;
|
|
|
|
+ int searchdistance = 10;
|
|
|
|
|
|
pag = xfs_perag_get(mp, agno);
|
|
pag = xfs_perag_get(mp, agno);
|
|
|
|
|
|
@@ -1159,7 +1160,6 @@ xfs_dialloc_ag_inobt(
|
|
if (pagno == agno) {
|
|
if (pagno == agno) {
|
|
int doneleft; /* done, to the left */
|
|
int doneleft; /* done, to the left */
|
|
int doneright; /* done, to the right */
|
|
int doneright; /* done, to the right */
|
|
- int searchdistance = 10;
|
|
|
|
|
|
|
|
error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
|
|
error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
|
|
if (error)
|
|
if (error)
|
|
@@ -1220,21 +1220,9 @@ xfs_dialloc_ag_inobt(
|
|
/*
|
|
/*
|
|
* Loop until we find an inode chunk with a free inode.
|
|
* Loop until we find an inode chunk with a free inode.
|
|
*/
|
|
*/
|
|
- while (!doneleft || !doneright) {
|
|
|
|
|
|
+ while (--searchdistance > 0 && (!doneleft || !doneright)) {
|
|
int useleft; /* using left inode chunk this time */
|
|
int useleft; /* using left inode chunk this time */
|
|
|
|
|
|
- if (!--searchdistance) {
|
|
|
|
- /*
|
|
|
|
- * Not in range - save last search
|
|
|
|
- * location and allocate a new inode
|
|
|
|
- */
|
|
|
|
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
|
|
|
|
- pag->pagl_leftrec = trec.ir_startino;
|
|
|
|
- pag->pagl_rightrec = rec.ir_startino;
|
|
|
|
- pag->pagl_pagino = pagino;
|
|
|
|
- goto newino;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* figure out the closer block if both are valid. */
|
|
/* figure out the closer block if both are valid. */
|
|
if (!doneleft && !doneright) {
|
|
if (!doneleft && !doneright) {
|
|
useleft = pagino -
|
|
useleft = pagino -
|
|
@@ -1278,26 +1266,37 @@ xfs_dialloc_ag_inobt(
|
|
goto error1;
|
|
goto error1;
|
|
}
|
|
}
|
|
|
|
|
|
- /*
|
|
|
|
- * We've reached the end of the btree. because
|
|
|
|
- * we are only searching a small chunk of the
|
|
|
|
- * btree each search, there is obviously free
|
|
|
|
- * inodes closer to the parent inode than we
|
|
|
|
- * are now. restart the search again.
|
|
|
|
- */
|
|
|
|
- pag->pagl_pagino = NULLAGINO;
|
|
|
|
- pag->pagl_leftrec = NULLAGINO;
|
|
|
|
- pag->pagl_rightrec = NULLAGINO;
|
|
|
|
- xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
|
|
|
|
- xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
|
|
|
|
- goto restart_pagno;
|
|
|
|
|
|
+ if (searchdistance <= 0) {
|
|
|
|
+ /*
|
|
|
|
+ * Not in range - save last search
|
|
|
|
+ * location and allocate a new inode
|
|
|
|
+ */
|
|
|
|
+ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
|
|
|
|
+ pag->pagl_leftrec = trec.ir_startino;
|
|
|
|
+ pag->pagl_rightrec = rec.ir_startino;
|
|
|
|
+ pag->pagl_pagino = pagino;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * We've reached the end of the btree. because
|
|
|
|
+ * we are only searching a small chunk of the
|
|
|
|
+ * btree each search, there is obviously free
|
|
|
|
+ * inodes closer to the parent inode than we
|
|
|
|
+ * are now. restart the search again.
|
|
|
|
+ */
|
|
|
|
+ pag->pagl_pagino = NULLAGINO;
|
|
|
|
+ pag->pagl_leftrec = NULLAGINO;
|
|
|
|
+ pag->pagl_rightrec = NULLAGINO;
|
|
|
|
+ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
|
|
|
|
+ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
|
|
|
|
+ goto restart_pagno;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* In a different AG from the parent.
|
|
* In a different AG from the parent.
|
|
* See if the most recently allocated block has any free.
|
|
* See if the most recently allocated block has any free.
|
|
*/
|
|
*/
|
|
-newino:
|
|
|
|
if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
|
|
if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
|
|
error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
|
|
error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
|
|
XFS_LOOKUP_EQ, &i);
|
|
XFS_LOOKUP_EQ, &i);
|