mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
8c61282ff6
commit
5334c5bdac
|
@ -2307,15 +2307,25 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
|
||||||
* fields corresponding to attributes that were used to store the verifier.
|
* fields corresponding to attributes that were used to store the verifier.
|
||||||
* Make sure we clobber those fields in the later setattr call
|
* Make sure we clobber those fields in the later setattr call
|
||||||
*/
|
*/
|
||||||
static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct iattr *sattr)
|
static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
|
||||||
|
struct iattr *sattr, struct nfs4_label **label)
|
||||||
{
|
{
|
||||||
if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
|
const u32 *attrset = opendata->o_res.attrset;
|
||||||
|
|
||||||
|
if ((attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
|
||||||
!(sattr->ia_valid & ATTR_ATIME_SET))
|
!(sattr->ia_valid & ATTR_ATIME_SET))
|
||||||
sattr->ia_valid |= ATTR_ATIME;
|
sattr->ia_valid |= ATTR_ATIME;
|
||||||
|
|
||||||
if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
|
if ((attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
|
||||||
!(sattr->ia_valid & ATTR_MTIME_SET))
|
!(sattr->ia_valid & ATTR_MTIME_SET))
|
||||||
sattr->ia_valid |= ATTR_MTIME;
|
sattr->ia_valid |= ATTR_MTIME;
|
||||||
|
|
||||||
|
/* Except MODE, it seems harmless of setting twice. */
|
||||||
|
if ((attrset[1] & FATTR4_WORD1_MODE))
|
||||||
|
sattr->ia_valid &= ~ATTR_MODE;
|
||||||
|
|
||||||
|
if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
|
||||||
|
*label = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
||||||
|
@ -2440,7 +2450,7 @@ static int _nfs4_do_open(struct inode *dir,
|
||||||
|
|
||||||
if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
|
if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
|
||||||
(opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
|
(opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
|
||||||
nfs4_exclusive_attrset(opendata, sattr);
|
nfs4_exclusive_attrset(opendata, sattr, &label);
|
||||||
|
|
||||||
nfs_fattr_init(opendata->o_res.f_attr);
|
nfs_fattr_init(opendata->o_res.f_attr);
|
||||||
status = nfs4_do_setattr(state->inode, cred,
|
status = nfs4_do_setattr(state->inode, cred,
|
||||||
|
|
|
@ -1001,7 +1001,8 @@ 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,
|
static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
||||||
const struct nfs4_label *label,
|
const struct nfs4_label *label,
|
||||||
const struct nfs_server *server)
|
const struct nfs_server *server,
|
||||||
|
bool excl_check)
|
||||||
{
|
{
|
||||||
char owner_name[IDMAP_NAMESZ];
|
char owner_name[IDMAP_NAMESZ];
|
||||||
char owner_group[IDMAP_NAMESZ];
|
char owner_group[IDMAP_NAMESZ];
|
||||||
|
@ -1067,6 +1068,17 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
||||||
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||||
len += 4;
|
len += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (excl_check) {
|
||||||
|
const u32 *excl_bmval = server->exclcreat_bitmask;
|
||||||
|
bmval[0] &= excl_bmval[0];
|
||||||
|
bmval[1] &= excl_bmval[1];
|
||||||
|
bmval[2] &= excl_bmval[2];
|
||||||
|
|
||||||
|
if (!(excl_bmval[2] & FATTR4_WORD2_SECURITY_LABEL))
|
||||||
|
label = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (label) {
|
if (label) {
|
||||||
len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
|
len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
|
||||||
bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
|
bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
|
||||||
|
@ -1170,7 +1182,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
|
||||||
}
|
}
|
||||||
|
|
||||||
encode_string(xdr, create->name->len, create->name->name);
|
encode_string(xdr, create->name->len, create->name->name);
|
||||||
encode_attrs(xdr, create->attrs, create->label, create->server);
|
encode_attrs(xdr, create->attrs, create->label, create->server, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
|
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
|
||||||
|
|
||||||
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
|
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
|
||||||
{
|
{
|
||||||
struct iattr dummy;
|
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
p = reserve_space(xdr, 4);
|
p = reserve_space(xdr, 4);
|
||||||
switch(arg->createmode) {
|
switch(arg->createmode) {
|
||||||
case NFS4_CREATE_UNCHECKED:
|
case NFS4_CREATE_UNCHECKED:
|
||||||
*p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
|
*p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
|
||||||
encode_attrs(xdr, arg->u.attrs, arg->label, arg->server);
|
encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false);
|
||||||
break;
|
break;
|
||||||
case NFS4_CREATE_GUARDED:
|
case NFS4_CREATE_GUARDED:
|
||||||
*p = cpu_to_be32(NFS4_CREATE_GUARDED);
|
*p = cpu_to_be32(NFS4_CREATE_GUARDED);
|
||||||
encode_attrs(xdr, arg->u.attrs, arg->label, arg->server);
|
encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false);
|
||||||
break;
|
break;
|
||||||
case NFS4_CREATE_EXCLUSIVE:
|
case NFS4_CREATE_EXCLUSIVE:
|
||||||
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
|
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
|
||||||
|
@ -1404,8 +1415,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
|
||||||
case NFS4_CREATE_EXCLUSIVE4_1:
|
case NFS4_CREATE_EXCLUSIVE4_1:
|
||||||
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
|
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
|
||||||
encode_nfs4_verifier(xdr, &arg->u.verifier);
|
encode_nfs4_verifier(xdr, &arg->u.verifier);
|
||||||
dummy.ia_valid = 0;
|
encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true);
|
||||||
encode_attrs(xdr, &dummy, arg->label, arg->server);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1661,7 +1671,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
|
||||||
{
|
{
|
||||||
encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
|
encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
|
||||||
encode_nfs4_stateid(xdr, &arg->stateid);
|
encode_nfs4_stateid(xdr, &arg->stateid);
|
||||||
encode_attrs(xdr, arg->iap, arg->label, server);
|
encode_attrs(xdr, arg->iap, arg->label, server, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
|
static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
|
||||||
|
|
|
@ -379,7 +379,7 @@ struct nfs_openargs {
|
||||||
struct stateowner_id id;
|
struct stateowner_id id;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
struct iattr * attrs; /* UNCHECKED, GUARDED */
|
struct iattr * attrs; /* UNCHECKED, GUARDED, EXCLUSIVE4_1 */
|
||||||
nfs4_verifier verifier; /* EXCLUSIVE */
|
nfs4_verifier verifier; /* EXCLUSIVE */
|
||||||
};
|
};
|
||||||
nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */
|
nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */
|
||||||
|
|
Loading…
Reference in New Issue