summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Schumaker <anna.schumaker@hammerspace.com>2026-06-30 15:39:45 -0400
committerAnna Schumaker <anna.schumaker@hammerspace.com>2026-07-20 11:04:04 -0400
commit4aeb63d5ac2dba2a474e7b64d60776d9dd1c6cd2 (patch)
tree4e48598aece31d80c74bdced9c761ad951194a28
parentcf616096a0f3a2b60f7d68b6b39674a6867ded9c (diff)
NFS: Decrement refcounts if allocating nfs_free_stateid_data fails
I noticed that we were immediately exiting this function if the allocation fails, leaving the client and server object refcounts bumped. Fix this by creating a common exit point to clean up dangling references. Fixes: 576acc259146 ("nfs4: take a reference on the nfs_client when running FREE_STATEID") Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
-rw-r--r--fs/nfs/nfs4proc.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 71b6ab863b39..7d98e9a98580 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -10403,21 +10403,22 @@ static int nfs41_free_stateid(struct nfs_server *server,
struct nfs_free_stateid_data *data;
struct rpc_task *task;
struct nfs_client *clp = server->nfs_client;
+ int ret = -EIO;
if (!refcount_inc_not_zero(&clp->cl_count))
- return -EIO;
- if (!nfs_sb_active(server->super)) {
- nfs_put_client(clp);
- return -EIO;
- }
+ return ret;
+ if (!nfs_sb_active(server->super))
+ goto out_put_clp;
nfs4_state_protect(clp, NFS_SP4_MACH_CRED_STATEID,
&task_setup.rpc_client, &msg);
dprintk("NFS call free_stateid %p\n", stateid);
data = kmalloc_obj(*data);
- if (!data)
- return -ENOMEM;
+ if (!data) {
+ ret = -ENOMEM;
+ goto out_put_server;
+ }
data->server = server;
nfs4_stateid_copy(&data->args.stateid, stateid);
@@ -10433,6 +10434,11 @@ static int nfs41_free_stateid(struct nfs_server *server,
rpc_put_task(task);
stateid->type = NFS4_FREED_STATEID_TYPE;
return 0;
+out_put_server:
+ nfs_sb_deactive(server->super);
+out_put_clp:
+ nfs_put_client(clp);
+ return ret;
}
static void