diff options
author | Kinglong Mee <kinglongmee@gmail.com> | 2015-08-26 09:13:37 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-08-27 19:47:07 -0400 |
commit | 5334c5bdac926c5f8d89729beccb46fe88eda9e7 (patch) | |
tree | bfa8b8757f5d80b3928709d965dd43397638dcfa /fs | |
parent | 8c61282ff61c28d5a12bb53f0eaa221d30fd3ae1 (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.c | 18 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 26 |
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 | */ |
2310 | static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct iattr *sattr) | 2310 | static 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 | ||
2321 | static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | 2331 | static 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 | ||
1002 | static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | 1002 | static 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 | ||
1176 | static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) | 1188 | static 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 | ||
1385 | static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) | 1397 | static 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 | ||
1667 | static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) | 1677 | static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) |