Message ID | 20170508142648.128870-1-trond.myklebust@primarydata.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Trond, On 05/08/2017 10:26 AM, Trond Myklebust wrote: > When using NFS4_CREATE_EXCLUSIVE4_1 mode, the client will overestimate the > amount of space that it needs for the attributes because it does so > before checking whether or not the server supports a given attribute. > > Fix by checking the attribute mask earlier. Cthon general tests consistently fail with IO errors once this patch is applied, but only for NFS v4.1 (v2, v3, v4.0, and v4.2 all work fine). Here is the output that it gives me: GENERAL TESTS: directory /nfs/general if test ! -x runtests; then chmod a+x runtests; fi cd /nfs/general; rm -f Makefile runtests runtests.wrk *.sh *.c mkdummy rmdummy nroff.in makefile.tst cp Makefile runtests runtests.wrk *.sh *.c mkdummy rmdummy nroff.in makefile.tst /nfs/general cp: cannot create regular file '/nfs/general/Makefile': Input/output error cp: cannot create regular file '/nfs/general/runtests': Input/output error cp: cannot create regular file '/nfs/general/runtests.wrk': Input/output error cp: cannot create regular file '/nfs/general/large4.sh': Input/output error cp: cannot create regular file '/nfs/general/large.c': Input/output error cp: cannot create regular file '/nfs/general/large1.c': Input/output error cp: cannot create regular file '/nfs/general/large2.c': Input/output error cp: cannot create regular file '/nfs/general/large3.c': Input/output error cp: cannot create regular file '/nfs/general/stat.c': Input/output error cp: cannot create regular file '/nfs/general/mkdummy': Input/output error cp: cannot create regular file '/nfs/general/rmdummy': Input/output error cp: cannot create regular file '/nfs/general/nroff.in': Input/output error cp: cannot create regular file '/nfs/general/makefile.tst': Input/output error make: *** [Makefile:32: copy] Error 1 general tests failed Thanks, Anna > > Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> > --- > fs/nfs/nfs4xdr.c | 75 ++++++++++++++++++++++++++------------------------------ > 1 file changed, 35 insertions(+), 40 deletions(-) > > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c > index dbfe48ac3529..3aebfdc82b30 100644 > --- a/fs/nfs/nfs4xdr.c > +++ b/fs/nfs/nfs4xdr.c > @@ -1000,8 +1000,9 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve > > static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > const struct nfs4_label *label, > + const umode_t *umask, > const struct nfs_server *server, > - bool excl_check, const umode_t *umask) > + const uint32_t attrmask[]) > { > char owner_name[IDMAP_NAMESZ]; > char owner_group[IDMAP_NAMESZ]; > @@ -1016,22 +1017,20 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > /* > * We reserve enough space to write the entire attribute buffer at once. > */ > - if (iap->ia_valid & ATTR_SIZE) { > + if ((iap->ia_valid & ATTR_SIZE) && (attrmask[0] & FATTR4_WORD0_SIZE)) { > bmval[0] |= FATTR4_WORD0_SIZE; > len += 8; > } > - if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) > - umask = NULL; > if (iap->ia_valid & ATTR_MODE) { > - if (umask) { > + if (umask && (attrmask[2] & FATTR4_WORD2_MODE_UMASK)) { > bmval[2] |= FATTR4_WORD2_MODE_UMASK; > len += 8; > - } else { > + } else if (attrmask[1] & FATTR4_WORD1_MODE) { > bmval[1] |= FATTR4_WORD1_MODE; > len += 4; > } > } > - if (iap->ia_valid & ATTR_UID) { > + if ((iap->ia_valid & ATTR_UID) && (attrmask[1] & FATTR4_WORD1_OWNER)) { > owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); > if (owner_namelen < 0) { > dprintk("nfs: couldn't resolve uid %d to string\n", > @@ -1044,7 +1043,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > bmval[1] |= FATTR4_WORD1_OWNER; > len += 4 + (XDR_QUADLEN(owner_namelen) << 2); > } > - if (iap->ia_valid & ATTR_GID) { > + if ((iap->ia_valid & ATTR_GID) && > + (attrmask[1] & FATTR4_WORD1_OWNER_GROUP)) { > owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); > if (owner_grouplen < 0) { > dprintk("nfs: couldn't resolve gid %d to string\n", > @@ -1056,32 +1056,26 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > bmval[1] |= FATTR4_WORD1_OWNER_GROUP; > len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); > } > - if (iap->ia_valid & ATTR_ATIME_SET) { > - bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; > - len += 16; > - } else if (iap->ia_valid & ATTR_ATIME) { > - bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; > - len += 4; > - } > - if (iap->ia_valid & ATTR_MTIME_SET) { > - bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; > - len += 16; > - } else if (iap->ia_valid & ATTR_MTIME) { > - bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; > - len += 4; > + if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) { > + if (iap->ia_valid & ATTR_ATIME_SET) { > + bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; > + len += 16; > + } else if (iap->ia_valid & ATTR_ATIME) { > + bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; > + len += 4; > + } > } > - > - if (excl_check) { > - const u32 *excl_bmval = server->exclcreat_bitmask; > - bmval[0] &= excl_bmval[0]; > - bmval[1] &= excl_bmval[1]; > - bmval[2] &= excl_bmval[2]; > - > - if (!(excl_bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) > - label = NULL; > + if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) { > + if (iap->ia_valid & ATTR_MTIME_SET) { > + bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; > + len += 16; > + } else if (iap->ia_valid & ATTR_MTIME) { > + bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; > + len += 4; > + } > } > > - if (label) { > + if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) { > len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); > bmval[2] |= FATTR4_WORD2_SECURITY_LABEL; > } > @@ -1188,8 +1182,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * > } > > encode_string(xdr, create->name->len, create->name->name); > - encode_attrs(xdr, create->attrs, create->label, create->server, false, > - &create->umask); > + encode_attrs(xdr, create->attrs, create->label, &create->umask, > + create->server, create->server->attr_bitmask); > } > > static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) > @@ -1409,13 +1403,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op > switch(arg->createmode) { > case NFS4_CREATE_UNCHECKED: > *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); > - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, > - &arg->umask); > + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, > + arg->server, arg->server->attr_bitmask); > break; > case NFS4_CREATE_GUARDED: > *p = cpu_to_be32(NFS4_CREATE_GUARDED); > - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, > - &arg->umask); > + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, > + arg->server, arg->server->attr_bitmask); > break; > case NFS4_CREATE_EXCLUSIVE: > *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); > @@ -1424,8 +1418,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op > case NFS4_CREATE_EXCLUSIVE4_1: > *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); > encode_nfs4_verifier(xdr, &arg->u.verifier); > - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, > - &arg->umask); > + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, > + arg->server, arg->server->exclcreat_bitmask); > } > } > > @@ -1681,7 +1675,8 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs > { > encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); > encode_nfs4_stateid(xdr, &arg->stateid); > - encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); > + encode_attrs(xdr, arg->iap, arg->label, NULL, server, > + server->attr_bitmask); > } > > static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
T24gVHVlLCAyMDE3LTA1LTA5IGF0IDEzOjU5IC0wNDAwLCBBbm5hIFNjaHVtYWtlciB3cm90ZToN Cj4gSGkgVHJvbmQsDQo+IA0KPiBPbiAwNS8wOC8yMDE3IDEwOjI2IEFNLCBUcm9uZCBNeWtsZWJ1 c3Qgd3JvdGU6DQo+ID4gV2hlbiB1c2luZyBORlM0X0NSRUFURV9FWENMVVNJVkU0XzEgbW9kZSwg dGhlIGNsaWVudCB3aWxsDQo+ID4gb3ZlcmVzdGltYXRlIHRoZQ0KPiA+IGFtb3VudCBvZiBzcGFj ZSB0aGF0IGl0IG5lZWRzIGZvciB0aGUgYXR0cmlidXRlcyBiZWNhdXNlIGl0IGRvZXMgc28NCj4g PiBiZWZvcmUgY2hlY2tpbmcgd2hldGhlciBvciBub3QgdGhlIHNlcnZlciBzdXBwb3J0cyBhIGdp dmVuDQo+ID4gYXR0cmlidXRlLg0KPiA+IA0KPiA+IEZpeCBieSBjaGVja2luZyB0aGUgYXR0cmli dXRlIG1hc2sgZWFybGllci4NCj4gDQo+IEN0aG9uIGdlbmVyYWwgdGVzdHMgY29uc2lzdGVudGx5 IGZhaWwgd2l0aCBJTyBlcnJvcnMgb25jZSB0aGlzIHBhdGNoDQo+IGlzIGFwcGxpZWQsIGJ1dCBv bmx5IGZvciBORlMgdjQuMSAodjIsIHYzLCB2NC4wLCBhbmQgdjQuMiBhbGwgd29yaw0KPiBmaW5l KS7CoMKgSGVyZSBpcyB0aGUgb3V0cHV0IHRoYXQgaXQgZ2l2ZXMgbWU6DQo+IA0KPiBHRU5FUkFM IFRFU1RTOiBkaXJlY3RvcnkgL25mcy9nZW5lcmFsDQo+IGlmIHRlc3QgISAteCBydW50ZXN0czsg dGhlbiBjaG1vZCBhK3ggcnVudGVzdHM7IGZpDQo+IGNkIC9uZnMvZ2VuZXJhbDsgcm0gLWYgTWFr ZWZpbGUgcnVudGVzdHMgcnVudGVzdHMud3JrICouc2ggKi5jDQo+IG1rZHVtbXkgcm1kdW1teSBu cm9mZi5pbiBtYWtlZmlsZS50c3QNCj4gY3AgTWFrZWZpbGUgcnVudGVzdHMgcnVudGVzdHMud3Jr ICouc2ggKi5jIG1rZHVtbXkgcm1kdW1teSBucm9mZi5pbg0KPiBtYWtlZmlsZS50c3QgL25mcy9n ZW5lcmFsDQo+IGNwOiBjYW5ub3QgY3JlYXRlIHJlZ3VsYXIgZmlsZSAnL25mcy9nZW5lcmFsL01h a2VmaWxlJzogSW5wdXQvb3V0cHV0DQo+IGVycm9yDQo+IGNwOiBjYW5ub3QgY3JlYXRlIHJlZ3Vs YXIgZmlsZSAnL25mcy9nZW5lcmFsL3J1bnRlc3RzJzogSW5wdXQvb3V0cHV0DQo+IGVycm9yDQo+ IGNwOiBjYW5ub3QgY3JlYXRlIHJlZ3VsYXIgZmlsZSAnL25mcy9nZW5lcmFsL3J1bnRlc3RzLndy ayc6DQo+IElucHV0L291dHB1dCBlcnJvcg0KPiBjcDogY2Fubm90IGNyZWF0ZSByZWd1bGFyIGZp bGUgJy9uZnMvZ2VuZXJhbC9sYXJnZTQuc2gnOiBJbnB1dC9vdXRwdXQNCj4gZXJyb3INCj4gY3A6 IGNhbm5vdCBjcmVhdGUgcmVndWxhciBmaWxlICcvbmZzL2dlbmVyYWwvbGFyZ2UuYyc6IElucHV0 L291dHB1dA0KPiBlcnJvcg0KPiBjcDogY2Fubm90IGNyZWF0ZSByZWd1bGFyIGZpbGUgJy9uZnMv Z2VuZXJhbC9sYXJnZTEuYyc6IElucHV0L291dHB1dA0KPiBlcnJvcg0KPiBjcDogY2Fubm90IGNy ZWF0ZSByZWd1bGFyIGZpbGUgJy9uZnMvZ2VuZXJhbC9sYXJnZTIuYyc6IElucHV0L291dHB1dA0K PiBlcnJvcg0KPiBjcDogY2Fubm90IGNyZWF0ZSByZWd1bGFyIGZpbGUgJy9uZnMvZ2VuZXJhbC9s YXJnZTMuYyc6IElucHV0L291dHB1dA0KPiBlcnJvcg0KPiBjcDogY2Fubm90IGNyZWF0ZSByZWd1 bGFyIGZpbGUgJy9uZnMvZ2VuZXJhbC9zdGF0LmMnOiBJbnB1dC9vdXRwdXQNCj4gZXJyb3INCj4g Y3A6IGNhbm5vdCBjcmVhdGUgcmVndWxhciBmaWxlICcvbmZzL2dlbmVyYWwvbWtkdW1teSc6IElu cHV0L291dHB1dA0KPiBlcnJvcg0KPiBjcDogY2Fubm90IGNyZWF0ZSByZWd1bGFyIGZpbGUgJy9u ZnMvZ2VuZXJhbC9ybWR1bW15JzogSW5wdXQvb3V0cHV0DQo+IGVycm9yDQo+IGNwOiBjYW5ub3Qg Y3JlYXRlIHJlZ3VsYXIgZmlsZSAnL25mcy9nZW5lcmFsL25yb2ZmLmluJzogSW5wdXQvb3V0cHV0 DQo+IGVycm9yDQo+IGNwOiBjYW5ub3QgY3JlYXRlIHJlZ3VsYXIgZmlsZSAnL25mcy9nZW5lcmFs L21ha2VmaWxlLnRzdCc6DQo+IElucHV0L291dHB1dCBlcnJvcg0KPiBtYWtlOiAqKiogW01ha2Vm aWxlOjMyOiBjb3B5XSBFcnJvciAxDQo+IGdlbmVyYWwgdGVzdHMgZmFpbGVkDQo+IA0KDQpEdWgu Li4gVGhlIExpbnV4IHNlcnZlciBpcyByZXR1cm5pbmcgdGhlIGxpc3Qgb2YgX2FsbF8gYXR0cmli dXRlcyB3aGVuDQp3ZSBhc2sgZm9yIHN1cHBhdHRyX2V4Y2xjcmVhdCBpbnN0ZWFkIG9mIHNhbml0 aXNpbmcgYnkgbWlub3IgdmVyc2lvbi4NCkJydWNlPw0KDQotLSANClRyb25kIE15a2xlYnVzdA0K TGludXggTkZTIGNsaWVudCBtYWludGFpbmVyLCBQcmltYXJ5RGF0YQ0KdHJvbmQubXlrbGVidXN0 QHByaW1hcnlkYXRhLmNvbQ0K -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index dbfe48ac3529..3aebfdc82b30 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1000,8 +1000,9 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs4_label *label, + const umode_t *umask, const struct nfs_server *server, - bool excl_check, const umode_t *umask) + const uint32_t attrmask[]) { char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; @@ -1016,22 +1017,20 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, /* * We reserve enough space to write the entire attribute buffer at once. */ - if (iap->ia_valid & ATTR_SIZE) { + if ((iap->ia_valid & ATTR_SIZE) && (attrmask[0] & FATTR4_WORD0_SIZE)) { bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } - if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) - umask = NULL; if (iap->ia_valid & ATTR_MODE) { - if (umask) { + if (umask && (attrmask[2] & FATTR4_WORD2_MODE_UMASK)) { bmval[2] |= FATTR4_WORD2_MODE_UMASK; len += 8; - } else { + } else if (attrmask[1] & FATTR4_WORD1_MODE) { bmval[1] |= FATTR4_WORD1_MODE; len += 4; } } - if (iap->ia_valid & ATTR_UID) { + if ((iap->ia_valid & ATTR_UID) && (attrmask[1] & FATTR4_WORD1_OWNER)) { owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); if (owner_namelen < 0) { dprintk("nfs: couldn't resolve uid %d to string\n", @@ -1044,7 +1043,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, bmval[1] |= FATTR4_WORD1_OWNER; len += 4 + (XDR_QUADLEN(owner_namelen) << 2); } - if (iap->ia_valid & ATTR_GID) { + if ((iap->ia_valid & ATTR_GID) && + (attrmask[1] & FATTR4_WORD1_OWNER_GROUP)) { owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); if (owner_grouplen < 0) { dprintk("nfs: couldn't resolve gid %d to string\n", @@ -1056,32 +1056,26 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, bmval[1] |= FATTR4_WORD1_OWNER_GROUP; len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); } - if (iap->ia_valid & ATTR_ATIME_SET) { - bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; - len += 16; - } else if (iap->ia_valid & ATTR_ATIME) { - bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; - len += 4; - } - if (iap->ia_valid & ATTR_MTIME_SET) { - bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; - len += 16; - } else if (iap->ia_valid & ATTR_MTIME) { - bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; - len += 4; + if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) { + if (iap->ia_valid & ATTR_ATIME_SET) { + bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; + len += 16; + } else if (iap->ia_valid & ATTR_ATIME) { + bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; + len += 4; + } } - - if (excl_check) { - const u32 *excl_bmval = server->exclcreat_bitmask; - bmval[0] &= excl_bmval[0]; - bmval[1] &= excl_bmval[1]; - bmval[2] &= excl_bmval[2]; - - if (!(excl_bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) - label = NULL; + if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) { + if (iap->ia_valid & ATTR_MTIME_SET) { + bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; + len += 16; + } else if (iap->ia_valid & ATTR_MTIME) { + bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; + len += 4; + } } - if (label) { + if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) { len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); bmval[2] |= FATTR4_WORD2_SECURITY_LABEL; } @@ -1188,8 +1182,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * } encode_string(xdr, create->name->len, create->name->name); - encode_attrs(xdr, create->attrs, create->label, create->server, false, - &create->umask); + encode_attrs(xdr, create->attrs, create->label, &create->umask, + create->server, create->server->attr_bitmask); } static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) @@ -1409,13 +1403,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op switch(arg->createmode) { case NFS4_CREATE_UNCHECKED: *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, - &arg->umask); + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, + arg->server, arg->server->attr_bitmask); break; case NFS4_CREATE_GUARDED: *p = cpu_to_be32(NFS4_CREATE_GUARDED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, - &arg->umask); + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, + arg->server, arg->server->attr_bitmask); break; case NFS4_CREATE_EXCLUSIVE: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); @@ -1424,8 +1418,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op case NFS4_CREATE_EXCLUSIVE4_1: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); encode_nfs4_verifier(xdr, &arg->u.verifier); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, - &arg->umask); + encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, + arg->server, arg->server->exclcreat_bitmask); } } @@ -1681,7 +1675,8 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); encode_nfs4_stateid(xdr, &arg->stateid); - encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); + encode_attrs(xdr, arg->iap, arg->label, NULL, server, + server->attr_bitmask); } static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
When using NFS4_CREATE_EXCLUSIVE4_1 mode, the client will overestimate the amount of space that it needs for the attributes because it does so before checking whether or not the server supports a given attribute. Fix by checking the attribute mask earlier. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> --- fs/nfs/nfs4xdr.c | 75 ++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 40 deletions(-)