diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
| -rw-r--r-- | fs/nfs/nfs4proc.c | 25 | 
1 files changed, 20 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)  		nfs4_close_state(ctx->state, ctx->mode);  } +#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) +#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) +#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL) +  static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)  {  	struct nfs4_server_caps_arg args = { @@ -2721,12 +2725,25 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f  	status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);  	if (status == 0) { +		/* Sanity check the server answers */ +		switch (server->nfs_client->cl_minorversion) { +		case 0: +			res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK; +			res.attr_bitmask[2] = 0; +			break; +		case 1: +			res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK; +			break; +		case 2: +			res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; +		}  		memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));  		server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|  				NFS_CAP_SYMLINKS|NFS_CAP_FILEID|  				NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|  				NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| -				NFS_CAP_CTIME|NFS_CAP_MTIME); +				NFS_CAP_CTIME|NFS_CAP_MTIME| +				NFS_CAP_SECURITY_LABEL);  		if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)  			server->caps |= NFS_CAP_ACLS;  		if (res.has_links != 0) @@ -2755,14 +2772,12 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f  #endif  		memcpy(server->attr_bitmask_nl, res.attr_bitmask,  				sizeof(server->attr_bitmask)); +		server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; -		if (server->caps & NFS_CAP_SECURITY_LABEL) { -			server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; -			res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL; -		}  		memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));  		server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;  		server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; +		server->cache_consistency_bitmask[2] = 0;  		server->acl_bitmask = res.acl_bitmask;  		server->fh_expire_type = res.fh_expire_type;  	} | 
