diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-05 09:16:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-05 10:00:14 -0400 |
commit | 1549210fcc17e9ae20c09ac8cd4c48a8dfd431bd (patch) | |
tree | 87db73acf11d00c1c4366e488faf86cd70ed996a /fs/nfs/nfs4xdr.c | |
parent | b3b02ae5865c2dcd506322e0fc6def59a042e72f (diff) |
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>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ee4a74db95d0..9ca1428da9d9 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -1198,12 +1198,13 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c | |||
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, | 1200 | static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, |
1201 | const u32 *open_bitmap, | ||
1201 | struct compound_hdr *hdr) | 1202 | struct compound_hdr *hdr) |
1202 | { | 1203 | { |
1203 | encode_getattr_three(xdr, | 1204 | encode_getattr_three(xdr, |
1204 | bitmask[0] & nfs4_fattr_bitmap[0], | 1205 | bitmask[0] & open_bitmap[0], |
1205 | bitmask[1] & nfs4_fattr_bitmap[1], | 1206 | bitmask[1] & open_bitmap[1], |
1206 | bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD, | 1207 | bitmask[2] & open_bitmap[2], |
1207 | hdr); | 1208 | hdr); |
1208 | } | 1209 | } |
1209 | 1210 | ||
@@ -2221,7 +2222,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2221 | encode_putfh(xdr, args->fh, &hdr); | 2222 | encode_putfh(xdr, args->fh, &hdr); |
2222 | encode_open(xdr, args, &hdr); | 2223 | encode_open(xdr, args, &hdr); |
2223 | encode_getfh(xdr, &hdr); | 2224 | encode_getfh(xdr, &hdr); |
2224 | encode_getfattr_open(xdr, args->bitmask, &hdr); | 2225 | encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); |
2225 | encode_nops(&hdr); | 2226 | encode_nops(&hdr); |
2226 | } | 2227 | } |
2227 | 2228 | ||
@@ -4360,6 +4361,9 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr, | |||
4360 | if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U))) | 4361 | if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U))) |
4361 | return -EIO; | 4362 | return -EIO; |
4362 | if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) { | 4363 | if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) { |
4364 | /* Did the server return an unrequested attribute? */ | ||
4365 | if (unlikely(res == NULL)) | ||
4366 | return -EREMOTEIO; | ||
4363 | p = xdr_inline_decode(xdr, 4); | 4367 | p = xdr_inline_decode(xdr, 4); |
4364 | if (unlikely(!p)) | 4368 | if (unlikely(!p)) |
4365 | goto out_overflow; | 4369 | goto out_overflow; |