diff options
author | Benjamin Coddington <bcodding@redhat.com> | 2019-06-07 06:37:30 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-06-21 14:43:25 -0400 |
commit | 909105199a682cb09c500acd443d34b182846c9c (patch) | |
tree | 3be6cbff83397bca6bf272bf6197ec99f4c928c8 /fs/nfs | |
parent | 9e0babf2c06c73cda2c0cd37a1653d823adb40ec (diff) |
NFS4: Only set creation opendata if O_CREAT
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: Trond Myklebust <trondmy@hammerspace.com>
Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e38f4af20950..6418cb6c079b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1256,10 +1256,20 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
1256 | atomic_inc(&sp->so_count); | 1256 | atomic_inc(&sp->so_count); |
1257 | p->o_arg.open_flags = flags; | 1257 | p->o_arg.open_flags = flags; |
1258 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); | 1258 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); |
1259 | p->o_arg.umask = current_umask(); | ||
1260 | p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); | 1259 | p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); |
1261 | p->o_arg.share_access = nfs4_map_atomic_open_share(server, | 1260 | p->o_arg.share_access = nfs4_map_atomic_open_share(server, |
1262 | fmode, flags); | 1261 | fmode, flags); |
1262 | if (flags & O_CREAT) { | ||
1263 | p->o_arg.umask = current_umask(); | ||
1264 | p->o_arg.label = nfs4_label_copy(p->a_label, label); | ||
1265 | if (c->sattr != NULL && c->sattr->ia_valid != 0) { | ||
1266 | p->o_arg.u.attrs = &p->attrs; | ||
1267 | memcpy(&p->attrs, c->sattr, sizeof(p->attrs)); | ||
1268 | |||
1269 | memcpy(p->o_arg.u.verifier.data, c->verf, | ||
1270 | sizeof(p->o_arg.u.verifier.data)); | ||
1271 | } | ||
1272 | } | ||
1263 | /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS | 1273 | /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS |
1264 | * will return permission denied for all bits until close */ | 1274 | * will return permission denied for all bits until close */ |
1265 | if (!(flags & O_EXCL)) { | 1275 | if (!(flags & O_EXCL)) { |
@@ -1283,7 +1293,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
1283 | p->o_arg.server = server; | 1293 | p->o_arg.server = server; |
1284 | p->o_arg.bitmask = nfs4_bitmask(server, label); | 1294 | p->o_arg.bitmask = nfs4_bitmask(server, label); |
1285 | p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; | 1295 | p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; |
1286 | p->o_arg.label = nfs4_label_copy(p->a_label, label); | ||
1287 | switch (p->o_arg.claim) { | 1296 | switch (p->o_arg.claim) { |
1288 | case NFS4_OPEN_CLAIM_NULL: | 1297 | case NFS4_OPEN_CLAIM_NULL: |
1289 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: | 1298 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: |
@@ -1296,13 +1305,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
1296 | case NFS4_OPEN_CLAIM_DELEG_PREV_FH: | 1305 | case NFS4_OPEN_CLAIM_DELEG_PREV_FH: |
1297 | p->o_arg.fh = NFS_FH(d_inode(dentry)); | 1306 | p->o_arg.fh = NFS_FH(d_inode(dentry)); |
1298 | } | 1307 | } |
1299 | if (c != NULL && c->sattr != NULL && c->sattr->ia_valid != 0) { | ||
1300 | p->o_arg.u.attrs = &p->attrs; | ||
1301 | memcpy(&p->attrs, c->sattr, sizeof(p->attrs)); | ||
1302 | |||
1303 | memcpy(p->o_arg.u.verifier.data, c->verf, | ||
1304 | sizeof(p->o_arg.u.verifier.data)); | ||
1305 | } | ||
1306 | p->c_arg.fh = &p->o_res.fh; | 1308 | p->c_arg.fh = &p->o_res.fh; |
1307 | p->c_arg.stateid = &p->o_res.stateid; | 1309 | p->c_arg.stateid = &p->o_res.stateid; |
1308 | p->c_arg.seqid = p->o_arg.seqid; | 1310 | p->c_arg.seqid = p->o_arg.seqid; |