Push Giant acquisition down into fo_stat() from most callers. Acquire
Giant conditional on debug.mpsafenet in the socket soo_stat() routine, unconditionally in vn_statfile() for VFS, and otherwise don't acquire Giant. Accept an unlocked read in kqueue_stat(), and cryptof_stat() is a no-op. Don't acquire Giant in fstat() system call. Note: in fdescfs, fo_stat() is called while holding Giant due to the VFS stack sitting on top, and therefore there will still be Giant recursion in this case.
This commit is contained in:
parent
0ab1b47fd4
commit
a6719c82b1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132554
@ -1005,9 +1005,7 @@ ofstat(td, uap)
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
mtx_lock(&Giant);
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
mtx_unlock(&Giant);
|
||||
if (error == 0) {
|
||||
cvtstat(&ub, &oub);
|
||||
error = copyout(&oub, uap->sb, sizeof(oub));
|
||||
@ -1042,9 +1040,7 @@ fstat(td, uap)
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
mtx_lock(&Giant);
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
mtx_unlock(&Giant);
|
||||
if (error == 0)
|
||||
error = copyout(&ub, uap->sb, sizeof(ub));
|
||||
fdrop(fp, td);
|
||||
@ -1077,9 +1073,7 @@ nfstat(td, uap)
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
mtx_lock(&Giant);
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
mtx_unlock(&Giant);
|
||||
if (error == 0) {
|
||||
cvtnstat(&ub, &nub);
|
||||
error = copyout(&nub, uap->sb, sizeof(nub));
|
||||
|
@ -889,6 +889,7 @@ kqueue_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
|
||||
{
|
||||
struct kqueue *kq;
|
||||
|
||||
/* Unlocked read. */
|
||||
kq = fp->f_data;
|
||||
bzero((void *)st, sizeof(*st));
|
||||
st->st_size = kq->kq_count;
|
||||
|
@ -225,9 +225,11 @@ soo_stat(fp, ub, active_cred, td)
|
||||
struct thread *td;
|
||||
{
|
||||
struct socket *so = fp->f_data;
|
||||
int error;
|
||||
|
||||
bzero((caddr_t)ub, sizeof (*ub));
|
||||
ub->st_mode = S_IFSOCK;
|
||||
NET_LOCK_GIANT();
|
||||
/*
|
||||
* If SBS_CANTRCVMORE is set, but there's still data left in the
|
||||
* receive buffer, the socket is still readable.
|
||||
@ -244,7 +246,9 @@ soo_stat(fp, ub, active_cred, td)
|
||||
ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl;
|
||||
ub->st_uid = so->so_cred->cr_uid;
|
||||
ub->st_gid = so->so_cred->cr_gid;
|
||||
return ((*so->so_proto->pr_usrreqs->pru_sense)(so, ub));
|
||||
error = (*so->so_proto->pr_usrreqs->pru_sense)(so, ub);
|
||||
NET_UNLOCK_GIANT();
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -622,9 +622,11 @@ vn_statfile(fp, sb, active_cred, td)
|
||||
struct vnode *vp = fp->f_vnode;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
error = vn_stat(vp, sb, active_cred, fp->f_cred, td);
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user