summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-12-02 22:53:30 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-12-09 23:47:10 -0500
commitdff25ddb48086afcb434770caa3d6849a4489b85 (patch)
tree5072c5bf9d907cabcfa354e7c100d0302b10cb36 /fs/nfs/nfs4xdr.c
parentd9152114f7c9abb096275b72db8527c004d57bf9 (diff)
nfs: add support for the umask attribute
Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1c1768a8fcd1..1af6268a7d8c 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -52,6 +52,7 @@
52#include <linux/nfs.h> 52#include <linux/nfs.h>
53#include <linux/nfs4.h> 53#include <linux/nfs4.h>
54#include <linux/nfs_fs.h> 54#include <linux/nfs_fs.h>
55#include <linux/fs_struct.h>
55 56
56#include "nfs4_fs.h" 57#include "nfs4_fs.h"
57#include "internal.h" 58#include "internal.h"
@@ -1008,7 +1009,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
1008static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, 1009static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1009 const struct nfs4_label *label, 1010 const struct nfs4_label *label,
1010 const struct nfs_server *server, 1011 const struct nfs_server *server,
1011 bool excl_check) 1012 bool excl_check, const umode_t *umask)
1012{ 1013{
1013 char owner_name[IDMAP_NAMESZ]; 1014 char owner_name[IDMAP_NAMESZ];
1014 char owner_group[IDMAP_NAMESZ]; 1015 char owner_group[IDMAP_NAMESZ];
@@ -1022,18 +1023,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1022 1023
1023 /* 1024 /*
1024 * We reserve enough space to write the entire attribute buffer at once. 1025 * We reserve enough space to write the entire attribute buffer at once.
1025 * In the worst-case, this would be
1026 * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
1027 * = 40 bytes, plus any contribution from variable-length fields
1028 * such as owner/group.
1029 */ 1026 */
1030 if (iap->ia_valid & ATTR_SIZE) { 1027 if (iap->ia_valid & ATTR_SIZE) {
1031 bmval[0] |= FATTR4_WORD0_SIZE; 1028 bmval[0] |= FATTR4_WORD0_SIZE;
1032 len += 8; 1029 len += 8;
1033 } 1030 }
1031 if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
1032 umask = NULL;
1034 if (iap->ia_valid & ATTR_MODE) { 1033 if (iap->ia_valid & ATTR_MODE) {
1035 bmval[1] |= FATTR4_WORD1_MODE; 1034 if (umask) {
1036 len += 4; 1035 bmval[2] |= FATTR4_WORD2_MODE_UMASK;
1036 len += 8;
1037 } else {
1038 bmval[1] |= FATTR4_WORD1_MODE;
1039 len += 4;
1040 }
1037 } 1041 }
1038 if (iap->ia_valid & ATTR_UID) { 1042 if (iap->ia_valid & ATTR_UID) {
1039 owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); 1043 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,
1134 *p++ = cpu_to_be32(label->len); 1138 *p++ = cpu_to_be32(label->len);
1135 p = xdr_encode_opaque_fixed(p, label->label, label->len); 1139 p = xdr_encode_opaque_fixed(p, label->label, label->len);
1136 } 1140 }
1141 if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
1142 *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
1143 *p++ = cpu_to_be32(*umask);
1144 }
1137 1145
1138/* out: */ 1146/* out: */
1139} 1147}
@@ -1188,7 +1196,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
1188 } 1196 }
1189 1197
1190 encode_string(xdr, create->name->len, create->name->name); 1198 encode_string(xdr, create->name->len, create->name->name);
1191 encode_attrs(xdr, create->attrs, create->label, create->server, false); 1199 encode_attrs(xdr, create->attrs, create->label, create->server, false,
1200 &create->umask);
1192} 1201}
1193 1202
1194static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) 1203static 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
1408 switch(arg->createmode) { 1417 switch(arg->createmode) {
1409 case NFS4_CREATE_UNCHECKED: 1418 case NFS4_CREATE_UNCHECKED:
1410 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1419 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
1411 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); 1420 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false,
1421 &arg->umask);
1412 break; 1422 break;
1413 case NFS4_CREATE_GUARDED: 1423 case NFS4_CREATE_GUARDED:
1414 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1424 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1415 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); 1425 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false,
1426 &arg->umask);
1416 break; 1427 break;
1417 case NFS4_CREATE_EXCLUSIVE: 1428 case NFS4_CREATE_EXCLUSIVE:
1418 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); 1429 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
@@ -1421,7 +1432,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
1421 case NFS4_CREATE_EXCLUSIVE4_1: 1432 case NFS4_CREATE_EXCLUSIVE4_1:
1422 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1433 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1423 encode_nfs4_verifier(xdr, &arg->u.verifier); 1434 encode_nfs4_verifier(xdr, &arg->u.verifier);
1424 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true); 1435 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true,
1436 &arg->umask);
1425 } 1437 }
1426} 1438}
1427 1439
@@ -1677,7 +1689,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
1677{ 1689{
1678 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); 1690 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
1679 encode_nfs4_stateid(xdr, &arg->stateid); 1691 encode_nfs4_stateid(xdr, &arg->stateid);
1680 encode_attrs(xdr, arg->iap, arg->label, server, false); 1692 encode_attrs(xdr, arg->iap, arg->label, server, false, NULL);
1681} 1693}
1682 1694
1683static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) 1695static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)