aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c25
-rw-r--r--include/linux/nfs4.h2
2 files changed, 22 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7e28b5c77cbc..ed2a0e6b9aed 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2706,6 +2706,10 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
2706 nfs4_close_state(ctx->state, ctx->mode); 2706 nfs4_close_state(ctx->state, ctx->mode);
2707} 2707}
2708 2708
2709#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
2710#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
2711#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL)
2712
2709static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 2713static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
2710{ 2714{
2711 struct nfs4_server_caps_arg args = { 2715 struct nfs4_server_caps_arg args = {
@@ -2721,12 +2725,25 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
2721 2725
2722 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 2726 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2723 if (status == 0) { 2727 if (status == 0) {
2728 /* Sanity check the server answers */
2729 switch (server->nfs_client->cl_minorversion) {
2730 case 0:
2731 res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK;
2732 res.attr_bitmask[2] = 0;
2733 break;
2734 case 1:
2735 res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK;
2736 break;
2737 case 2:
2738 res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK;
2739 }
2724 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 2740 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
2725 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| 2741 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
2726 NFS_CAP_SYMLINKS|NFS_CAP_FILEID| 2742 NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
2727 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| 2743 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
2728 NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| 2744 NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
2729 NFS_CAP_CTIME|NFS_CAP_MTIME); 2745 NFS_CAP_CTIME|NFS_CAP_MTIME|
2746 NFS_CAP_SECURITY_LABEL);
2730 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 2747 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
2731 server->caps |= NFS_CAP_ACLS; 2748 server->caps |= NFS_CAP_ACLS;
2732 if (res.has_links != 0) 2749 if (res.has_links != 0)
@@ -2755,14 +2772,12 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
2755#endif 2772#endif
2756 memcpy(server->attr_bitmask_nl, res.attr_bitmask, 2773 memcpy(server->attr_bitmask_nl, res.attr_bitmask,
2757 sizeof(server->attr_bitmask)); 2774 sizeof(server->attr_bitmask));
2775 server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2758 2776
2759 if (server->caps & NFS_CAP_SECURITY_LABEL) {
2760 server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2761 res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2762 }
2763 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); 2777 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
2764 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; 2778 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
2765 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 2779 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
2780 server->cache_consistency_bitmask[2] = 0;
2766 server->acl_bitmask = res.acl_bitmask; 2781 server->acl_bitmask = res.acl_bitmask;
2767 server->fh_expire_type = res.fh_expire_type; 2782 server->fh_expire_type = res.fh_expire_type;
2768 } 2783 }
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index bfe6c379a24e..c6f41b616965 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -396,6 +396,8 @@ enum lock_type4 {
396#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) 396#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1)
397#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) 397#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4)
398#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) 398#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
399#define FATTR4_WORD2_CHANGE_SECURITY_LABEL \
400 (1UL << 17)
399 401
400/* MDS threshold bitmap bits */ 402/* MDS threshold bitmap bits */
401#define THRESHOLD_RD (1UL << 0) 403#define THRESHOLD_RD (1UL << 0)