History

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).

Trond Myklebust committed 14 years ago

Commit 15492101 parent b3b02ae4 files · +31 −6Browse files

Unified · Split

4 files
  1. fs/nfs/nfs4_fs.h +1 −1
  2. fs/nfs/nfs4proc.c +21 −1
  3. fs/nfs/nfs4xdr.c +8 −4
  4. include/linux/nfs_xdr.h +1 −0
fs/nfs/nfs4_fs.h+1−1
@@ -295,7 +295,7 @@ is_ds_client(struct nfs_client *clp) · 294 unmodified lines
295 295
296extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];296extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
297 297
298extern const u32 nfs4_fattr_bitmap[2];298extern const u32 nfs4_fattr_bitmap[3];
299extern const u32 nfs4_statfs_bitmap[2];299extern const u32 nfs4_statfs_bitmap[2];
300extern const u32 nfs4_pathconf_bitmap[2];300extern const u32 nfs4_pathconf_bitmap[2];
301extern const u32 nfs4_fsinfo_bitmap[3];301extern const u32 nfs4_fsinfo_bitmap[3];
fs/nfs/nfs4proc.c+21−1
@@ -116,7 +116,7 @@ static int nfs4_map_errors(int err) · 115 unmodified lines
116/*116/*
117 * This is our standard bitmap for GETATTR requests.117 * This is our standard bitmap for GETATTR requests.
118 */118 */
119const u32 nfs4_fattr_bitmap[2] = {119const u32 nfs4_fattr_bitmap[3] = {
120 FATTR4_WORD0_TYPE120 FATTR4_WORD0_TYPE
121 | FATTR4_WORD0_CHANGE121 | FATTR4_WORD0_CHANGE
122 | FATTR4_WORD0_SIZE122 | FATTR4_WORD0_SIZE
@@ -133,6 +133,24 @@ const u32 nfs4_fattr_bitmap[2] = { · 10 unmodified lines
133 | FATTR4_WORD1_TIME_MODIFY133 | FATTR4_WORD1_TIME_MODIFY
134};134};
135 135
136static const u32 nfs4_pnfs_open_bitmap[3] = {
137 FATTR4_WORD0_TYPE
138 | FATTR4_WORD0_CHANGE
139 | FATTR4_WORD0_SIZE
140 | FATTR4_WORD0_FSID
141 | FATTR4_WORD0_FILEID,
142 FATTR4_WORD1_MODE
143 | FATTR4_WORD1_NUMLINKS
144 | FATTR4_WORD1_OWNER
145 | FATTR4_WORD1_OWNER_GROUP
146 | FATTR4_WORD1_RAWDEV
147 | FATTR4_WORD1_SPACE_USED
148 | FATTR4_WORD1_TIME_ACCESS
149 | FATTR4_WORD1_TIME_METADATA
150 | FATTR4_WORD1_TIME_MODIFY,
151 FATTR4_WORD2_MDSTHRESHOLD
152};
153
136const u32 nfs4_statfs_bitmap[2] = {154const u32 nfs4_statfs_bitmap[2] = {
137 FATTR4_WORD0_FILES_AVAIL155 FATTR4_WORD0_FILES_AVAIL
138 | FATTR4_WORD0_FILES_FREE156 | FATTR4_WORD0_FILES_FREE
@@ -844,6 +862,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, · 705 unmodified lines
844 p->o_arg.name = &dentry->d_name;862 p->o_arg.name = &dentry->d_name;
845 p->o_arg.server = server;863 p->o_arg.server = server;
846 p->o_arg.bitmask = server->attr_bitmask;864 p->o_arg.bitmask = server->attr_bitmask;
865 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
847 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;866 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
848 if (attrs != NULL && attrs->ia_valid != 0) {867 if (attrs != NULL && attrs->ia_valid != 0) {
849 __be32 verf[2];868 __be32 verf[2];
@@ -1820,6 +1839,7 @@ static int _nfs4_do_open(struct inode *dir, · 970 unmodified lines
1820 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();1839 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
1821 if (!opendata->f_attr.mdsthreshold)1840 if (!opendata->f_attr.mdsthreshold)
1822 goto err_opendata_put;1841 goto err_opendata_put;
1842 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
1823 }1843 }
1824 if (dentry->d_inode != NULL)1844 if (dentry->d_inode != NULL)
1825 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);1845 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
fs/nfs/nfs4xdr.c+8−4
@@ -1198,12 +1198,13 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c · 1197 unmodified lines
1198}1198}
1199 1199
1200static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,1200static 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, · 1011 unmodified lines
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, · 2132 unmodified lines
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;
include/linux/nfs_xdr.h+1−0
@@ -348,6 +348,7 @@ struct nfs_openargs { · 347 unmodified lines
348 const struct qstr * name;348 const struct qstr * name;
349 const struct nfs_server *server; /* Needed for ID mapping */349 const struct nfs_server *server; /* Needed for ID mapping */
350 const u32 * bitmask;350 const u32 * bitmask;
351 const u32 * open_bitmap;
351 __u32 claim;352 __u32 claim;
352 struct nfs4_sequence_args seq_args;353 struct nfs4_sequence_args seq_args;
353};354};