diff options
author | Oleg Drokin <green@linuxhacker.ru> | 2016-06-14 23:28:06 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2016-06-15 22:03:53 -0400 |
commit | 8c7245abda877d4689b3371db8ae2a4400d7d9ce (patch) | |
tree | 8818d6f70f48db5a18108dd65f15d4a833ca4e54 /fs | |
parent | 5cc1fb2a093e254b656c64ff24b0b76bed1d34d9 (diff) |
nfsd: Make init_open_stateid() a bit more whole
Move the state selection logic inside from the caller,
always making it return correct stp to use.
Signed-off-by: J . Bruce Fields <bfields@fieldses.org>
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4state.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 94854a06c9ad..70d0b9b33031 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -3480,13 +3480,14 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open, | |||
3480 | } | 3480 | } |
3481 | 3481 | ||
3482 | static struct nfs4_ol_stateid * | 3482 | static struct nfs4_ol_stateid * |
3483 | init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, | 3483 | init_open_stateid(struct nfs4_file *fp, struct nfsd4_open *open) |
3484 | struct nfsd4_open *open) | ||
3485 | { | 3484 | { |
3486 | 3485 | ||
3487 | struct nfs4_openowner *oo = open->op_openowner; | 3486 | struct nfs4_openowner *oo = open->op_openowner; |
3488 | struct nfs4_ol_stateid *retstp = NULL; | 3487 | struct nfs4_ol_stateid *retstp = NULL; |
3488 | struct nfs4_ol_stateid *stp; | ||
3489 | 3489 | ||
3490 | stp = open->op_stp; | ||
3490 | /* We are moving these outside of the spinlocks to avoid the warnings */ | 3491 | /* We are moving these outside of the spinlocks to avoid the warnings */ |
3491 | mutex_init(&stp->st_mutex); | 3492 | mutex_init(&stp->st_mutex); |
3492 | mutex_lock(&stp->st_mutex); | 3493 | mutex_lock(&stp->st_mutex); |
@@ -3497,6 +3498,8 @@ init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, | |||
3497 | retstp = nfsd4_find_existing_open(fp, open); | 3498 | retstp = nfsd4_find_existing_open(fp, open); |
3498 | if (retstp) | 3499 | if (retstp) |
3499 | goto out_unlock; | 3500 | goto out_unlock; |
3501 | |||
3502 | open->op_stp = NULL; | ||
3500 | atomic_inc(&stp->st_stid.sc_count); | 3503 | atomic_inc(&stp->st_stid.sc_count); |
3501 | stp->st_stid.sc_type = NFS4_OPEN_STID; | 3504 | stp->st_stid.sc_type = NFS4_OPEN_STID; |
3502 | INIT_LIST_HEAD(&stp->st_locks); | 3505 | INIT_LIST_HEAD(&stp->st_locks); |
@@ -3514,10 +3517,11 @@ out_unlock: | |||
3514 | spin_unlock(&oo->oo_owner.so_client->cl_lock); | 3517 | spin_unlock(&oo->oo_owner.so_client->cl_lock); |
3515 | if (retstp) { | 3518 | if (retstp) { |
3516 | mutex_lock(&retstp->st_mutex); | 3519 | mutex_lock(&retstp->st_mutex); |
3517 | /* Not that we need to, just for neatness */ | 3520 | /* To keep mutex tracking happy */ |
3518 | mutex_unlock(&stp->st_mutex); | 3521 | mutex_unlock(&stp->st_mutex); |
3522 | stp = retstp; | ||
3519 | } | 3523 | } |
3520 | return retstp; | 3524 | return stp; |
3521 | } | 3525 | } |
3522 | 3526 | ||
3523 | /* | 3527 | /* |
@@ -4313,7 +4317,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
4313 | struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; | 4317 | struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; |
4314 | struct nfs4_file *fp = NULL; | 4318 | struct nfs4_file *fp = NULL; |
4315 | struct nfs4_ol_stateid *stp = NULL; | 4319 | struct nfs4_ol_stateid *stp = NULL; |
4316 | struct nfs4_ol_stateid *swapstp = NULL; | ||
4317 | struct nfs4_delegation *dp = NULL; | 4320 | struct nfs4_delegation *dp = NULL; |
4318 | __be32 status; | 4321 | __be32 status; |
4319 | 4322 | ||
@@ -4350,16 +4353,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
4350 | goto out; | 4353 | goto out; |
4351 | } | 4354 | } |
4352 | } else { | 4355 | } else { |
4353 | stp = open->op_stp; | 4356 | /* stp is returned locked. */ |
4354 | open->op_stp = NULL; | 4357 | stp = init_open_stateid(fp, open); |
4355 | /* | 4358 | /* See if we lost the race to some other thread */ |
4356 | * init_open_stateid() either returns a locked stateid | 4359 | if (stp->st_access_bmap != 0) { |
4357 | * it found, or initializes and locks the new one we passed in | ||
4358 | */ | ||
4359 | swapstp = init_open_stateid(stp, fp, open); | ||
4360 | if (swapstp) { | ||
4361 | nfs4_put_stid(&stp->st_stid); | ||
4362 | stp = swapstp; | ||
4363 | status = nfs4_upgrade_open(rqstp, fp, current_fh, | 4360 | status = nfs4_upgrade_open(rqstp, fp, current_fh, |
4364 | stp, open); | 4361 | stp, open); |
4365 | if (status) { | 4362 | if (status) { |