aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c5
-rw-r--r--fs/nfs/dir.c4
-rw-r--r--fs/nfs/internal.h6
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfs/nfs3xdr.c2
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/nfs4xdr.c55
8 files changed, 39 insertions, 38 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 876ba8592706..da2f2f024a4d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1358,8 +1358,9 @@ static int nfs4_init_server(struct nfs_server *server,
1358 1358
1359 /* Initialise the client representation from the mount data */ 1359 /* Initialise the client representation from the mount data */
1360 server->flags = data->flags; 1360 server->flags = data->flags;
1361 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR| 1361 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|NFS_CAP_POSIX_LOCK;
1362 NFS_CAP_POSIX_LOCK; 1362 if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
1363 server->caps |= NFS_CAP_READDIRPLUS;
1363 server->options = data->options; 1364 server->options = data->options;
1364 1365
1365 /* Get a client record */ 1366 /* Get a client record */
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 0cbb714a09d8..2a768d05a534 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -172,7 +172,7 @@ struct nfs_cache_array {
172 172
173#define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry)) 173#define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry))
174 174
175typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int); 175typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
176typedef struct { 176typedef struct {
177 struct file *file; 177 struct file *file;
178 struct page *page; 178 struct page *page;
@@ -360,7 +360,7 @@ error:
360static 360static
361int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream) 361int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream)
362{ 362{
363 __be32 *p = desc->decode(stream, entry, desc->plus); 363 __be32 *p = desc->decode(stream, entry, NFS_SERVER(desc->file->f_path.dentry->d_inode), desc->plus);
364 if (IS_ERR(p)) 364 if (IS_ERR(p))
365 return PTR_ERR(p); 365 return PTR_ERR(p);
366 366
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 7b0e894d00c8..db08ff3ff454 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -187,15 +187,15 @@ extern void nfs_destroy_directcache(void);
187/* nfs2xdr.c */ 187/* nfs2xdr.c */
188extern int nfs_stat_to_errno(int); 188extern int nfs_stat_to_errno(int);
189extern struct rpc_procinfo nfs_procedures[]; 189extern struct rpc_procinfo nfs_procedures[];
190extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); 190extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
191 191
192/* nfs3xdr.c */ 192/* nfs3xdr.c */
193extern struct rpc_procinfo nfs3_procedures[]; 193extern struct rpc_procinfo nfs3_procedures[];
194extern __be32 *nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); 194extern __be32 *nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
195 195
196/* nfs4xdr.c */ 196/* nfs4xdr.c */
197#ifdef CONFIG_NFS_V4 197#ifdef CONFIG_NFS_V4
198extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *entry, int plus); 198extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
199#endif 199#endif
200#ifdef CONFIG_NFS_V4_1 200#ifdef CONFIG_NFS_V4_1
201extern const u32 nfs41_maxread_overhead; 201extern const u32 nfs41_maxread_overhead;
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 82f026422424..e6bf45710cc7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -454,7 +454,7 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
454} 454}
455 455
456__be32 * 456__be32 *
457nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus) 457nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
458{ 458{
459 __be32 *p; 459 __be32 *p;
460 p = xdr_inline_decode(xdr, 4); 460 p = xdr_inline_decode(xdr, 4);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index dc98eb7976c3..31a44df40aea 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -590,7 +590,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
590} 590}
591 591
592__be32 * 592__be32 *
593nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus) 593nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
594{ 594{
595 __be32 *p; 595 __be32 *p;
596 struct nfs_entry old = *entry; 596 struct nfs_entry old = *entry;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index c58ea6377506..9fa496387fdf 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -331,7 +331,7 @@ extern void nfs_free_seqid(struct nfs_seqid *seqid);
331extern const nfs4_stateid zero_stateid; 331extern const nfs4_stateid zero_stateid;
332 332
333/* nfs4xdr.c */ 333/* nfs4xdr.c */
334extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *entry, int plus); 334extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
335extern struct rpc_procinfo nfs4_procedures[]; 335extern struct rpc_procinfo nfs4_procedures[];
336 336
337struct nfs4_mount_data; 337struct nfs4_mount_data;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cb33c73206e3..f5ab216e8870 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2832,6 +2832,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2832 .pgbase = 0, 2832 .pgbase = 0,
2833 .count = count, 2833 .count = count,
2834 .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask, 2834 .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
2835 .plus = plus,
2835 }; 2836 };
2836 struct nfs4_readdir_res res; 2837 struct nfs4_readdir_res res;
2837 struct rpc_message msg = { 2838 struct rpc_message msg = {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index b7eff205d3d8..ccfb1c92b262 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1385,12 +1385,20 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
1385 1385
1386static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1386static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1387{ 1387{
1388 uint32_t attrs[2] = { 1388 uint32_t attrs[2] = {0, 0};
1389 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
1390 FATTR4_WORD1_MOUNTED_ON_FILEID,
1391 };
1392 __be32 *p; 1389 __be32 *p;
1393 1390
1391 if (readdir->plus) {
1392 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
1393 FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE;
1394 attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
1395 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
1396 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
1397 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1398 }
1399 attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID;
1400 attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
1401
1394 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); 1402 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
1395 *p++ = cpu_to_be32(OP_READDIR); 1403 *p++ = cpu_to_be32(OP_READDIR);
1396 p = xdr_encode_hyper(p, readdir->cookie); 1404 p = xdr_encode_hyper(p, readdir->cookie);
@@ -1398,11 +1406,15 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1398 *p++ = cpu_to_be32(readdir->count >> 1); /* We're not doing readdirplus */ 1406 *p++ = cpu_to_be32(readdir->count >> 1); /* We're not doing readdirplus */
1399 *p++ = cpu_to_be32(readdir->count); 1407 *p++ = cpu_to_be32(readdir->count);
1400 *p++ = cpu_to_be32(2); 1408 *p++ = cpu_to_be32(2);
1401 /* Switch to mounted_on_fileid if the server supports it */ 1409
1402 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) 1410 if (!readdir->plus) {
1403 attrs[0] &= ~FATTR4_WORD0_FILEID; 1411 /* Switch to mounted_on_fileid if the server supports it */
1404 else 1412 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1405 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 1413 attrs[0] &= ~FATTR4_WORD0_FILEID;
1414 else
1415 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1416 }
1417
1406 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1418 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
1407 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1419 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
1408 hdr->nops++; 1420 hdr->nops++;
@@ -5768,7 +5780,8 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, uint32_t *p,
5768} 5780}
5769#endif /* CONFIG_NFS_V4_1 */ 5781#endif /* CONFIG_NFS_V4_1 */
5770 5782
5771__be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus) 5783__be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
5784 struct nfs_server *server, int plus)
5772{ 5785{
5773 uint32_t bitmap[2] = {0}; 5786 uint32_t bitmap[2] = {0};
5774 uint32_t len; 5787 uint32_t len;
@@ -5824,24 +5837,10 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int
5824 goto out_overflow; 5837 goto out_overflow;
5825 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */ 5838 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
5826 if (len > 0) { 5839 if (len > 0) {
5827 if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) { 5840 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, server, 1) < 0)
5828 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; 5841 goto out_overflow;
5829 /* Ignore the return value of rdattr_error for now */ 5842 if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
5830 p = xdr_inline_decode(xdr, 4); 5843 entry->ino = entry->fattr->fileid;
5831 if (unlikely(!p))
5832 goto out_overflow;
5833 }
5834 if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID) {
5835 p = xdr_inline_decode(xdr, 8);
5836 if (unlikely(!p))
5837 goto out_overflow;
5838 xdr_decode_hyper(p, &entry->ino);
5839 } else if (bitmap[0] == FATTR4_WORD0_FILEID) {
5840 p = xdr_inline_decode(xdr, 8);
5841 if (unlikely(!p))
5842 goto out_overflow;
5843 xdr_decode_hyper(p, &entry->ino);
5844 }
5845 } 5844 }
5846 5845
5847 p = xdr_inline_peek(xdr, 8); 5846 p = xdr_inline_peek(xdr, 8);