diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 21 | 
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 0abfb8466e79..3850b018815f 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -999,6 +999,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,  	__be32 *p;  	__be32 *q;  	int len; +	uint32_t bmval_len = 2;  	uint32_t bmval0 = 0;  	uint32_t bmval1 = 0;  	uint32_t bmval2 = 0; @@ -1010,7 +1011,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,  	 * = 40 bytes, plus any contribution from variable-length fields  	 *            such as owner/group.  	 */ -	len = 20; +	len = 8;  	/* Sigh */  	if (iap->ia_valid & ATTR_SIZE) @@ -1040,8 +1041,6 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,  		}  		len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);  	} -	if (label) -		len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);  	if (iap->ia_valid & ATTR_ATIME_SET)  		len += 16;  	else if (iap->ia_valid & ATTR_ATIME) @@ -1050,15 +1049,22 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,  		len += 16;  	else if (iap->ia_valid & ATTR_MTIME)  		len += 4; +	if (label) { +		len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); +		bmval_len = 3; +	} + +	len += bmval_len << 2;  	p = reserve_space(xdr, len);  	/*  	 * We write the bitmap length now, but leave the bitmap and the attribute  	 * buffer length to be backfilled at the end of this routine.  	 */ -	*p++ = cpu_to_be32(3); +	*p++ = cpu_to_be32(bmval_len);  	q = p; -	p += 4; +	/* Skip bitmap entries + attrlen */ +	p += bmval_len + 1;  	if (iap->ia_valid & ATTR_SIZE) {  		bmval0 |= FATTR4_WORD0_SIZE; @@ -1112,10 +1118,11 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,  				len, ((char *)p - (char *)q) + 4);  		BUG();  	} -	len = (char *)p - (char *)q - 16;  	*q++ = htonl(bmval0);  	*q++ = htonl(bmval1); -	*q++ = htonl(bmval2); +	if (bmval_len == 3) +		*q++ = htonl(bmval2); +	len = (char *)p - (char *)(q + 1);  	*q = htonl(len);  /* out: */  | 
