Commit 26fd9ac2 authored by Benjamin Coddington's avatar Benjamin Coddington Committed by Greg Kroah-Hartman

NFS4: Only set creation opendata if O_CREAT

[ Upstream commit 90910519 ]

We can end up in nfs4_opendata_alloc during task exit, in which case
current->fs has already been cleaned up.  This leads to a crash in
current_umask().

Fix this by only setting creation opendata if we are actually doing an open
with O_CREAT.  We can drop the check for NULL nfs4_open_createattrs, since
O_CREAT will never be set for the recovery path.
Suggested-by: default avatarTrond Myklebust <trondmy@hammerspace.com>
Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 7e5cb4da
...@@ -1234,10 +1234,20 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, ...@@ -1234,10 +1234,20 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
atomic_inc(&sp->so_count); atomic_inc(&sp->so_count);
p->o_arg.open_flags = flags; p->o_arg.open_flags = flags;
p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
p->o_arg.umask = current_umask();
p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim);
p->o_arg.share_access = nfs4_map_atomic_open_share(server, p->o_arg.share_access = nfs4_map_atomic_open_share(server,
fmode, flags); fmode, flags);
if (flags & O_CREAT) {
p->o_arg.umask = current_umask();
p->o_arg.label = nfs4_label_copy(p->a_label, label);
if (c->sattr != NULL && c->sattr->ia_valid != 0) {
p->o_arg.u.attrs = &p->attrs;
memcpy(&p->attrs, c->sattr, sizeof(p->attrs));
memcpy(p->o_arg.u.verifier.data, c->verf,
sizeof(p->o_arg.u.verifier.data));
}
}
/* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
* will return permission denied for all bits until close */ * will return permission denied for all bits until close */
if (!(flags & O_EXCL)) { if (!(flags & O_EXCL)) {
...@@ -1261,7 +1271,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, ...@@ -1261,7 +1271,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
p->o_arg.server = server; p->o_arg.server = server;
p->o_arg.bitmask = nfs4_bitmask(server, label); p->o_arg.bitmask = nfs4_bitmask(server, label);
p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
p->o_arg.label = nfs4_label_copy(p->a_label, label);
switch (p->o_arg.claim) { switch (p->o_arg.claim) {
case NFS4_OPEN_CLAIM_NULL: case NFS4_OPEN_CLAIM_NULL:
case NFS4_OPEN_CLAIM_DELEGATE_CUR: case NFS4_OPEN_CLAIM_DELEGATE_CUR:
...@@ -1274,13 +1283,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, ...@@ -1274,13 +1283,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
case NFS4_OPEN_CLAIM_DELEG_PREV_FH: case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
p->o_arg.fh = NFS_FH(d_inode(dentry)); p->o_arg.fh = NFS_FH(d_inode(dentry));
} }
if (c != NULL && c->sattr != NULL && c->sattr->ia_valid != 0) {
p->o_arg.u.attrs = &p->attrs;
memcpy(&p->attrs, c->sattr, sizeof(p->attrs));
memcpy(p->o_arg.u.verifier.data, c->verf,
sizeof(p->o_arg.u.verifier.data));
}
p->c_arg.fh = &p->o_res.fh; p->c_arg.fh = &p->o_res.fh;
p->c_arg.stateid = &p->o_res.stateid; p->c_arg.stateid = &p->o_res.stateid;
p->c_arg.seqid = p->o_arg.seqid; p->c_arg.seqid = p->o_arg.seqid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment