spufs_create_context() takes a reference on the gang with gang->alive++
and is meant to hold it until the context directory is closed, at which
point spufs_dir_close() -> unuse_gang() drops it again.
The error epilogue instead reads:
ret = spufs_context_open(&path);
...
if (ret && gang)
gang->alive--; // can't reach 0
spufs_context_open() returns a non-negative file descriptor on success,
which is non-zero whenever the caller already holds an open fd. The
condition therefore fires on the success path too, dropping the
reference immediately; unuse_gang() then decrements it a second time at
close. The unbalanced double decrement can drive gang->alive to zero
prematurely, while contexts still reference the gang, triggering
simple_recursive_removal() of the gang directory too early.
Test the sign of the return value instead, so the reference is only
released on actual failure -- matching the idiom already used by
spufs_create_gang(), which calls unuse_gang() only on ret < 0.
Fixes: c134deabf478 ("spufs: fix gang directory lifetimes")
Reported-by: Yuhao Jiang <[email protected]>
Assisted-by: Claude:claude-opus-5
Cc: [email protected]
Signed-off-by: Zhenhao Wan <[email protected]>
---
arch/powerpc/platforms/cell/spufs/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c
b/arch/powerpc/platforms/cell/spufs/inode.c
index 2b54afb31529..23619fbe0bd9 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -436,7 +436,7 @@ spufs_create_context(struct inode *inode, struct dentry
*dentry,
out_aff_unlock:
if (affinity)
mutex_unlock(&gang->aff_mutex);
- if (ret && gang)
+ if (ret < 0 && gang)
gang->alive--; // can't reach 0
return ret;
}
--
2.34.1