diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 5 | ||||
-rw-r--r-- | fs/nfs/dir.c | 4 | ||||
-rw-r--r-- | fs/nfs/internal.h | 6 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 55 |
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 | ||
175 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int); | 175 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); |
176 | typedef struct { | 176 | typedef struct { |
177 | struct file *file; | 177 | struct file *file; |
178 | struct page *page; | 178 | struct page *page; |
@@ -360,7 +360,7 @@ error: | |||
360 | static | 360 | static |
361 | int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream) | 361 | int 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 */ |
188 | extern int nfs_stat_to_errno(int); | 188 | extern int nfs_stat_to_errno(int); |
189 | extern struct rpc_procinfo nfs_procedures[]; | 189 | extern struct rpc_procinfo nfs_procedures[]; |
190 | extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); | 190 | extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); |
191 | 191 | ||
192 | /* nfs3xdr.c */ | 192 | /* nfs3xdr.c */ |
193 | extern struct rpc_procinfo nfs3_procedures[]; | 193 | extern struct rpc_procinfo nfs3_procedures[]; |
194 | extern __be32 *nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); | 194 | extern __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 |
198 | extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *entry, int plus); | 198 | extern __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 |
201 | extern const u32 nfs41_maxread_overhead; | 201 | extern 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 * |
457 | nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus) | 457 | nfs_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 * |
593 | nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus) | 593 | nfs3_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); | |||
331 | extern const nfs4_stateid zero_stateid; | 331 | extern const nfs4_stateid zero_stateid; |
332 | 332 | ||
333 | /* nfs4xdr.c */ | 333 | /* nfs4xdr.c */ |
334 | extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *entry, int plus); | 334 | extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); |
335 | extern struct rpc_procinfo nfs4_procedures[]; | 335 | extern struct rpc_procinfo nfs4_procedures[]; |
336 | 336 | ||
337 | struct nfs4_mount_data; | 337 | struct 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 | ||
1386 | static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) | 1386 | static 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); |