aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-11-04 13:23:59 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-11-04 16:42:51 -0500
commitd204c5d2b8f7614350cd4609f4d4cdcf25494d74 (patch)
treebad66f4fac985065c1466a5186c629da41ae77cc /fs/nfs
parent3da580aab9482f5bf88ea79a4bf0a511eea6fa44 (diff)
NFSv4.2: encode_readdir - only ask for labels when doing readdirplus
Currently, if the server is doing NFSv4.2 and supports labeled NFS, then our on-the-wire READDIR request ends up asking for the label information, which is then ignored unless we're doing readdirplus. This patch ensures that READDIR doesn't ask the server for label information at all unless the readdir->bitmask contains the FATTR4_WORD2_SECURITY_LABEL attribute, and the readdir->plus flag is set. While we're at it, optimise away the 3rd bitmap field if it is zero. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4xdr.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index f903389d90f1..5be2868c02f1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -105,12 +105,8 @@ static int nfs4_stat_to_errno(int);
105#ifdef CONFIG_NFS_V4_SECURITY_LABEL 105#ifdef CONFIG_NFS_V4_SECURITY_LABEL
106/* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */ 106/* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */
107#define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN)) 107#define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN))
108#define encode_readdir_space 24
109#define encode_readdir_bitmask_sz 3
110#else 108#else
111#define nfs4_label_maxsz 0 109#define nfs4_label_maxsz 0
112#define encode_readdir_space 20
113#define encode_readdir_bitmask_sz 2
114#endif 110#endif
115/* We support only one layout type per file system */ 111/* We support only one layout type per file system */
116#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) 112#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
@@ -1581,6 +1577,8 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1581 }; 1577 };
1582 uint32_t dircount = readdir->count >> 1; 1578 uint32_t dircount = readdir->count >> 1;
1583 __be32 *p, verf[2]; 1579 __be32 *p, verf[2];
1580 uint32_t attrlen = 0;
1581 unsigned int i;
1584 1582
1585 if (readdir->plus) { 1583 if (readdir->plus) {
1586 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| 1584 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
@@ -1589,26 +1587,27 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1589 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 1587 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
1590 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 1588 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
1591 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 1589 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1590 attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
1592 dircount >>= 1; 1591 dircount >>= 1;
1593 } 1592 }
1594 /* Use mounted_on_fileid only if the server supports it */ 1593 /* Use mounted_on_fileid only if the server supports it */
1595 if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) 1594 if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
1596 attrs[0] |= FATTR4_WORD0_FILEID; 1595 attrs[0] |= FATTR4_WORD0_FILEID;
1596 for (i = 0; i < ARRAY_SIZE(attrs); i++) {
1597 attrs[i] &= readdir->bitmask[i];
1598 if (attrs[i] != 0)
1599 attrlen = i+1;
1600 }
1597 1601
1598 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); 1602 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr);
1599 encode_uint64(xdr, readdir->cookie); 1603 encode_uint64(xdr, readdir->cookie);
1600 encode_nfs4_verifier(xdr, &readdir->verifier); 1604 encode_nfs4_verifier(xdr, &readdir->verifier);
1601 p = reserve_space(xdr, encode_readdir_space); 1605 p = reserve_space(xdr, 12 + (attrlen << 2));
1602 *p++ = cpu_to_be32(dircount); 1606 *p++ = cpu_to_be32(dircount);
1603 *p++ = cpu_to_be32(readdir->count); 1607 *p++ = cpu_to_be32(readdir->count);
1604 *p++ = cpu_to_be32(encode_readdir_bitmask_sz); 1608 *p++ = cpu_to_be32(attrlen);
1605 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1609 for (i = 0; i < attrlen; i++)
1606 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1610 *p++ = cpu_to_be32(attrs[i]);
1607 if (encode_readdir_bitmask_sz > 2) {
1608 if (hdr->minorversion > 1)
1609 attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
1610 p++, *p++ = cpu_to_be32(attrs[2] & readdir->bitmask[2]);
1611 }
1612 memcpy(verf, readdir->verifier.data, sizeof(verf)); 1611 memcpy(verf, readdir->verifier.data, sizeof(verf));
1613 1612
1614 dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n", 1613 dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n",