Commit 8edd73a1 authored by Omar Sandoval's avatar Omar Sandoval Committed by Greg Kroah-Hartman

xfs: fix inobt inode allocation search optimization

commit c44245b3 upstream.

When we try to allocate a free inode by searching the inobt, we try to
find the inode nearest the parent inode by searching chunks both left
and right of the chunk containing the parent. As an optimization, we
cache the leftmost and rightmost records that we previously searched; if
we do another allocation with the same parent inode, we'll pick up the
search where it last left off.

There's a bug in the case where we found a free inode to the left of the
parent's chunk: we need to update the cached left and right records, but
because we already reassigned the right record to point to the left, we
end up assigning the left record to both the cached left and right
records.

This isn't a correctness problem strictly, but it can result in the next
allocation rechecking chunks unnecessarily or allocating inodes further
away from the parent than it needs to. Fix it by swapping the record
pointer after we update the cached left and right records.

Fixes: bd169565 ("xfs: speed up free inode search")
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f90756d7
...@@ -1236,13 +1236,13 @@ xfs_dialloc_ag_inobt( ...@@ -1236,13 +1236,13 @@ xfs_dialloc_ag_inobt(
/* free inodes to the left? */ /* free inodes to the left? */
if (useleft && trec.ir_freecount) { if (useleft && trec.ir_freecount) {
rec = trec;
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
cur = tcur; cur = tcur;
pag->pagl_leftrec = trec.ir_startino; pag->pagl_leftrec = trec.ir_startino;
pag->pagl_rightrec = rec.ir_startino; pag->pagl_rightrec = rec.ir_startino;
pag->pagl_pagino = pagino; pag->pagl_pagino = pagino;
rec = trec;
goto alloc_inode; goto alloc_inode;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment