xfs: distinguish extra split from real ENOSPC from xfs_attr3_leaf_split
xfs_attr3_leaf_split propagates the need for an extra btree split as -ENOSPC to it's only caller, but the same return value can also be returned from xfs_da_grow_inode when it fails to find free space. Distinguish the two cases by returning 1 for the extra split case instead of overloading -ENOSPC. This can be triggered relatively easily with the pending realtime group support and a file system with a lot of small zones that use metadata space on the main device. In this case every about 5-10th run of xfs/538 runs into the following assert: ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC); in xfs_attr3_leaf_split caused by an allocation failure. Note that the allocation failure is caused by another bug that will be fixed subsequently, but this commit at least sorts out the error handling. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
parent
346c1d46d4
commit
a5f73342ab
@ -1331,6 +1331,9 @@ xfs_attr3_leaf_create(
|
||||
|
||||
/*
|
||||
* Split the leaf node, rebalance, then add the new entry.
|
||||
*
|
||||
* Returns 0 if the entry was added, 1 if a further split is needed or a
|
||||
* negative error number otherwise.
|
||||
*/
|
||||
int
|
||||
xfs_attr3_leaf_split(
|
||||
@ -1387,7 +1390,7 @@ xfs_attr3_leaf_split(
|
||||
oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
|
||||
newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
|
||||
if (!added)
|
||||
return -ENOSPC;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -593,9 +593,8 @@ xfs_da3_split(
|
||||
switch (oldblk->magic) {
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
error = xfs_attr3_leaf_split(state, oldblk, newblk);
|
||||
if ((error != 0) && (error != -ENOSPC)) {
|
||||
if (error < 0)
|
||||
return error; /* GROT: attr is inconsistent */
|
||||
}
|
||||
if (!error) {
|
||||
addblk = newblk;
|
||||
break;
|
||||
@ -617,6 +616,8 @@ xfs_da3_split(
|
||||
error = xfs_attr3_leaf_split(state, newblk,
|
||||
&state->extrablk);
|
||||
}
|
||||
if (error == 1)
|
||||
return -ENOSPC;
|
||||
if (error)
|
||||
return error; /* GROT: attr inconsistent */
|
||||
addblk = newblk;
|
||||
|
Loading…
Reference in New Issue
Block a user