fd: stop looping in pwd_hold

We don't expect to fail acquiring the reference unless running into a corner
case. Just in case ensure forward progress by taking the lock.

Reviewed by:	kib, markj
Differential Revision: https://reviews.freebsd.org/D25616
This commit is contained in:
Mateusz Guzik 2020-07-11 21:57:03 +00:00
parent 463b8ebdcb
commit 373278a7f6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=363112

View File

@ -3347,13 +3347,17 @@ pwd_hold(struct thread *td)
fdp = td->td_proc->p_fd;
smr_enter(pwd_smr);
for (;;) {
pwd = smr_entered_load(&fdp->fd_pwd, pwd_smr);
MPASS(pwd != NULL);
if (refcount_acquire_if_not_zero(&pwd->pwd_refcount))
break;
pwd = smr_entered_load(&fdp->fd_pwd, pwd_smr);
MPASS(pwd != NULL);
if (__predict_true(refcount_acquire_if_not_zero(&pwd->pwd_refcount))) {
smr_exit(pwd_smr);
return (pwd);
}
smr_exit(pwd_smr);
FILEDESC_SLOCK(fdp);
pwd = pwd_hold_filedesc(fdp);
MPASS(pwd != NULL);
FILEDESC_SUNLOCK(fdp);
return (pwd);
}