]> git.dujemihanovic.xyz Git - linux.git/commitdiff
nfsd: call cache_put if xdr_reserve_space returns NULL
authorGuoqing Jiang <guoqing.jiang@linux.dev>
Wed, 21 Aug 2024 14:03:18 +0000 (22:03 +0800)
committerChuck Lever <chuck.lever@oracle.com>
Fri, 20 Sep 2024 23:31:03 +0000 (19:31 -0400)
If not enough buffer space available, but idmap_lookup has triggered
lookup_fn which calls cache_get and returns successfully. Then we
missed to call cache_put here which pairs with cache_get.

Fixes: ddd1ea563672 ("nfsd4: use xdr_reserve_space in attribute encoding")
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
Reviwed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4idmap.c

index 7a806ac13e317e021afcfaa5a711db158ee4e41c..8cca1329f3485c9f69783efda7dba0b752784dbd 100644 (file)
@@ -581,6 +581,7 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr,
                .id = id,
                .type = type,
        };
+       __be32 status = nfs_ok;
        __be32 *p;
        int ret;
        struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
@@ -593,12 +594,16 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr,
                return nfserrno(ret);
        ret = strlen(item->name);
        WARN_ON_ONCE(ret > IDMAP_NAMESZ);
+
        p = xdr_reserve_space(xdr, ret + 4);
-       if (!p)
-               return nfserr_resource;
-       p = xdr_encode_opaque(p, item->name, ret);
+       if (unlikely(!p)) {
+               status = nfserr_resource;
+               goto out_put;
+       }
+       xdr_encode_opaque(p, item->name, ret);
+out_put:
        cache_put(&item->h, nn->idtoname_cache);
-       return 0;
+       return status;
 }
 
 static bool