@ -52,6 +52,7 @@
# include <linux/nfs.h>
# include <linux/nfs4.h>
# include <linux/nfs_fs.h>
# include <linux/fs_struct.h>
# include "nfs4_fs.h"
# include "internal.h"
@ -1008,7 +1009,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
static void encode_attrs ( struct xdr_stream * xdr , const struct iattr * iap ,
const struct nfs4_label * label ,
const struct nfs_server * server ,
bool excl_check )
bool excl_check , const umode_t * umask )
{
char owner_name [ IDMAP_NAMESZ ] ;
char owner_group [ IDMAP_NAMESZ ] ;
@ -1022,18 +1023,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
/*
* We reserve enough space to write the entire attribute buffer at once .
* In the worst - case , this would be
* 16 ( bitmap ) + 4 ( attrlen ) + 8 ( size ) + 4 ( mode ) + 4 ( atime ) + 4 ( mtime )
* = 40 bytes , plus any contribution from variable - length fields
* such as owner / group .
*/
if ( iap - > ia_valid & ATTR_SIZE ) {
bmval [ 0 ] | = FATTR4_WORD0_SIZE ;
len + = 8 ;
}
if ( ! ( server - > attr_bitmask [ 2 ] & FATTR4_WORD2_MODE_UMASK ) )
umask = NULL ;
if ( iap - > ia_valid & ATTR_MODE ) {
bmval [ 1 ] | = FATTR4_WORD1_MODE ;
len + = 4 ;
if ( umask ) {
bmval [ 2 ] | = FATTR4_WORD2_MODE_UMASK ;
len + = 8 ;
} else {
bmval [ 1 ] | = FATTR4_WORD1_MODE ;
len + = 4 ;
}
}
if ( iap - > ia_valid & ATTR_UID ) {
owner_namelen = nfs_map_uid_to_name ( server , iap - > ia_uid , owner_name , IDMAP_NAMESZ ) ;
@ -1134,6 +1138,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
* p + + = cpu_to_be32 ( label - > len ) ;
p = xdr_encode_opaque_fixed ( p , label - > label , label - > len ) ;
}
if ( bmval [ 2 ] & FATTR4_WORD2_MODE_UMASK ) {
* p + + = cpu_to_be32 ( iap - > ia_mode & S_IALLUGO ) ;
* p + + = cpu_to_be32 ( * umask ) ;
}
/* out: */
}
@ -1188,7 +1196,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
}
encode_string ( xdr , create - > name - > len , create - > name - > name ) ;
encode_attrs ( xdr , create - > attrs , create - > label , create - > server , false ) ;
encode_attrs ( xdr , create - > attrs , create - > label , create - > server , false ,
& create - > umask ) ;
}
static void encode_getattr_one ( struct xdr_stream * xdr , uint32_t bitmap , struct compound_hdr * hdr )
@ -1408,11 +1417,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
switch ( arg - > createmode ) {
case NFS4_CREATE_UNCHECKED :
* p = cpu_to_be32 ( NFS4_CREATE_UNCHECKED ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , false ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , false ,
& arg - > umask ) ;
break ;
case NFS4_CREATE_GUARDED :
* p = cpu_to_be32 ( NFS4_CREATE_GUARDED ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , false ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , false ,
& arg - > umask ) ;
break ;
case NFS4_CREATE_EXCLUSIVE :
* p = cpu_to_be32 ( NFS4_CREATE_EXCLUSIVE ) ;
@ -1421,7 +1432,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
case NFS4_CREATE_EXCLUSIVE4_1 :
* p = cpu_to_be32 ( NFS4_CREATE_EXCLUSIVE4_1 ) ;
encode_nfs4_verifier ( xdr , & arg - > u . verifier ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , true ) ;
encode_attrs ( xdr , arg - > u . attrs , arg - > label , arg - > server , true ,
& arg - > umask ) ;
}
}
@ -1677,7 +1689,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
{
encode_op_hdr ( xdr , OP_SETATTR , decode_setattr_maxsz , hdr ) ;
encode_nfs4_stateid ( xdr , & arg - > stateid ) ;
encode_attrs ( xdr , arg - > iap , arg - > label , server , false ) ;
encode_attrs ( xdr , arg - > iap , arg - > label , server , false , NULL ) ;
}
static void encode_setclientid ( struct xdr_stream * xdr , const struct nfs4_setclientid * setclientid , struct compound_hdr * hdr )