aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorKinglong Mee <kinglongmee@gmail.com>2015-08-26 09:13:37 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-08-27 19:47:07 -0400
commit5334c5bdac926c5f8d89729beccb46fe88eda9e7 (patch)
treebfa8b8757f5d80b3928709d965dd43397638dcfa /fs
parent8c61282ff61c28d5a12bb53f0eaa221d30fd3ae1 (diff)
NFS: Send attributes in OPEN request for NFS4_CREATE_EXCLUSIVE4_1
Client sends a SETATTR request after OPEN for updating attributes. For create file with S_ISGID is set, the S_ISGID in SETATTR will be ignored at nfs server as chmod of no PERMISSION. v3, same as v2. Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c18
-rw-r--r--fs/nfs/nfs4xdr.c26
2 files changed, 32 insertions, 12 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a6a28d45cca4..2923abf2fc0c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2307,15 +2307,25 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
2307 * fields corresponding to attributes that were used to store the verifier. 2307 * fields corresponding to attributes that were used to store the verifier.
2308 * Make sure we clobber those fields in the later setattr call 2308 * Make sure we clobber those fields in the later setattr call
2309 */ 2309 */
2310static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct iattr *sattr) 2310static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
2311 struct iattr *sattr, struct nfs4_label **label)
2311{ 2312{
2312 if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_ACCESS) && 2313 const u32 *attrset = opendata->o_res.attrset;
2314
2315 if ((attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
2313 !(sattr->ia_valid & ATTR_ATIME_SET)) 2316 !(sattr->ia_valid & ATTR_ATIME_SET))
2314 sattr->ia_valid |= ATTR_ATIME; 2317 sattr->ia_valid |= ATTR_ATIME;
2315 2318
2316 if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_MODIFY) && 2319 if ((attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
2317 !(sattr->ia_valid & ATTR_MTIME_SET)) 2320 !(sattr->ia_valid & ATTR_MTIME_SET))
2318 sattr->ia_valid |= ATTR_MTIME; 2321 sattr->ia_valid |= ATTR_MTIME;
2322
2323 /* Except MODE, it seems harmless of setting twice. */
2324 if ((attrset[1] & FATTR4_WORD1_MODE))
2325 sattr->ia_valid &= ~ATTR_MODE;
2326
2327 if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
2328 *label = NULL;
2319} 2329}
2320 2330
2321static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, 2331static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
@@ -2440,7 +2450,7 @@ static int _nfs4_do_open(struct inode *dir,
2440 2450
2441 if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) && 2451 if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
2442 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) { 2452 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
2443 nfs4_exclusive_attrset(opendata, sattr); 2453 nfs4_exclusive_attrset(opendata, sattr, &label);
2444 2454
2445 nfs_fattr_init(opendata->o_res.f_attr); 2455 nfs_fattr_init(opendata->o_res.f_attr);
2446 status = nfs4_do_setattr(state->inode, cred, 2456 status = nfs4_do_setattr(state->inode, cred,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index ad8dde12f23b..a7be571c1666 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1001,7 +1001,8 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
1001 1001
1002static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, 1002static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1003 const struct nfs4_label *label, 1003 const struct nfs4_label *label,
1004 const struct nfs_server *server) 1004 const struct nfs_server *server,
1005 bool excl_check)
1005{ 1006{
1006 char owner_name[IDMAP_NAMESZ]; 1007 char owner_name[IDMAP_NAMESZ];
1007 char owner_group[IDMAP_NAMESZ]; 1008 char owner_group[IDMAP_NAMESZ];
@@ -1067,6 +1068,17 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1067 bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; 1068 bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
1068 len += 4; 1069 len += 4;
1069 } 1070 }
1071
1072 if (excl_check) {
1073 const u32 *excl_bmval = server->exclcreat_bitmask;
1074 bmval[0] &= excl_bmval[0];
1075 bmval[1] &= excl_bmval[1];
1076 bmval[2] &= excl_bmval[2];
1077
1078 if (!(excl_bmval[2] & FATTR4_WORD2_SECURITY_LABEL))
1079 label = NULL;
1080 }
1081
1070 if (label) { 1082 if (label) {
1071 len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); 1083 len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
1072 bmval[2] |= FATTR4_WORD2_SECURITY_LABEL; 1084 bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
@@ -1170,7 +1182,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
1170 } 1182 }
1171 1183
1172 encode_string(xdr, create->name->len, create->name->name); 1184 encode_string(xdr, create->name->len, create->name->name);
1173 encode_attrs(xdr, create->attrs, create->label, create->server); 1185 encode_attrs(xdr, create->attrs, create->label, create->server, false);
1174} 1186}
1175 1187
1176static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) 1188static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
@@ -1384,18 +1396,17 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
1384 1396
1385static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1397static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1386{ 1398{
1387 struct iattr dummy;
1388 __be32 *p; 1399 __be32 *p;
1389 1400
1390 p = reserve_space(xdr, 4); 1401 p = reserve_space(xdr, 4);
1391 switch(arg->createmode) { 1402 switch(arg->createmode) {
1392 case NFS4_CREATE_UNCHECKED: 1403 case NFS4_CREATE_UNCHECKED:
1393 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1404 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
1394 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); 1405 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false);
1395 break; 1406 break;
1396 case NFS4_CREATE_GUARDED: 1407 case NFS4_CREATE_GUARDED:
1397 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1408 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1398 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); 1409 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false);
1399 break; 1410 break;
1400 case NFS4_CREATE_EXCLUSIVE: 1411 case NFS4_CREATE_EXCLUSIVE:
1401 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); 1412 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
@@ -1404,8 +1415,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
1404 case NFS4_CREATE_EXCLUSIVE4_1: 1415 case NFS4_CREATE_EXCLUSIVE4_1:
1405 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1416 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1406 encode_nfs4_verifier(xdr, &arg->u.verifier); 1417 encode_nfs4_verifier(xdr, &arg->u.verifier);
1407 dummy.ia_valid = 0; 1418 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true);
1408 encode_attrs(xdr, &dummy, arg->label, arg->server);
1409 } 1419 }
1410} 1420}
1411 1421
@@ -1661,7 +1671,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
1661{ 1671{
1662 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); 1672 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
1663 encode_nfs4_stateid(xdr, &arg->stateid); 1673 encode_nfs4_stateid(xdr, &arg->stateid);
1664 encode_attrs(xdr, arg->iap, arg->label, server); 1674 encode_attrs(xdr, arg->iap, arg->label, server, false);
1665} 1675}
1666 1676
1667static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) 1677static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)