diff options
| -rw-r--r-- | fs/nfs/nfs4proc.c | 25 | ||||
| -rw-r--r-- | include/linux/nfs4.h | 2 |
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 | |||
| 2709 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) | 2713 | static 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) |
