NFSv4: Fix an Oops in the open recovery code
The open recovery code does not need to request a new value for the mdsthreshold, and so does not allocate a struct nfs4_threshold. The problem is that encode_getfattr_open() will still request an mdsthreshold, and so we end up Oopsing in decode_attr_mdsthreshold. This patch fixes encode_getfattr_open so that it doesn't request an mdsthreshold when the caller isn't asking for one. It also fixes decode_attr_mdsthreshold so that it errors if the server returns an mdsthreshold that we didn't ask for (instead of Oopsing). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Andy Adamson <andros@netapp.com>
This commit is contained in:
@@ -1198,12 +1198,13 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c
|
||||
}
|
||||
|
||||
static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
|
||||
const u32 *open_bitmap,
|
||||
struct compound_hdr *hdr)
|
||||
{
|
||||
encode_getattr_three(xdr,
|
||||
bitmask[0] & nfs4_fattr_bitmap[0],
|
||||
bitmask[1] & nfs4_fattr_bitmap[1],
|
||||
bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD,
|
||||
bitmask[0] & open_bitmap[0],
|
||||
bitmask[1] & open_bitmap[1],
|
||||
bitmask[2] & open_bitmap[2],
|
||||
hdr);
|
||||
}
|
||||
|
||||
@@ -2221,7 +2222,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||
encode_putfh(xdr, args->fh, &hdr);
|
||||
encode_open(xdr, args, &hdr);
|
||||
encode_getfh(xdr, &hdr);
|
||||
encode_getfattr_open(xdr, args->bitmask, &hdr);
|
||||
encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
|
||||
encode_nops(&hdr);
|
||||
}
|
||||
|
||||
@@ -4360,6 +4361,9 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
|
||||
if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U)))
|
||||
return -EIO;
|
||||
if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) {
|
||||
/* Did the server return an unrequested attribute? */
|
||||
if (unlikely(res == NULL))
|
||||
return -EREMOTEIO;
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
goto out_overflow;
|
||||
|
Reference in New Issue
Block a user