filedesc: fixup fdinit to lock fdp and preapare files conditinally
Not all consumers providing fdp to copy from want files. Perhaps these functions should be reorganized to better express the outcome. This fixes up panics after r273895 . Reported by: markj
This commit is contained in:
parent
14d4e1e250
commit
eb48fbd963
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=274482
@ -527,7 +527,7 @@ proc0_init(void *dummy __unused)
|
||||
siginit(&proc0);
|
||||
|
||||
/* Create the file descriptor table. */
|
||||
p->p_fd = fdinit(NULL);
|
||||
p->p_fd = fdinit(NULL, false);
|
||||
p->p_fdtol = NULL;
|
||||
|
||||
/* Create the limits structures. */
|
||||
|
@ -1797,7 +1797,7 @@ finstall(struct thread *td, struct file *fp, int *fd, int flags,
|
||||
* If fdp is not NULL, return with it shared locked.
|
||||
*/
|
||||
struct filedesc *
|
||||
fdinit(struct filedesc *fdp)
|
||||
fdinit(struct filedesc *fdp, bool prepfiles)
|
||||
{
|
||||
struct filedesc0 *newfdp0;
|
||||
struct filedesc *newfdp;
|
||||
@ -1818,7 +1818,7 @@ fdinit(struct filedesc *fdp)
|
||||
if (fdp == NULL)
|
||||
return (newfdp);
|
||||
|
||||
if (fdp->fd_lastfile >= newfdp->fd_nfiles)
|
||||
if (prepfiles && fdp->fd_lastfile >= newfdp->fd_nfiles)
|
||||
fdgrowtable(newfdp, fdp->fd_lastfile + 1);
|
||||
|
||||
FILEDESC_SLOCK(fdp);
|
||||
@ -1832,10 +1832,14 @@ fdinit(struct filedesc *fdp)
|
||||
if (newfdp->fd_jdir)
|
||||
VREF(newfdp->fd_jdir);
|
||||
|
||||
while (fdp->fd_lastfile >= newfdp->fd_nfiles) {
|
||||
if (!prepfiles) {
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
fdgrowtable(newfdp, fdp->fd_lastfile + 1);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
} else {
|
||||
while (fdp->fd_lastfile >= newfdp->fd_nfiles) {
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
fdgrowtable(newfdp, fdp->fd_lastfile + 1);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
}
|
||||
}
|
||||
|
||||
return (newfdp);
|
||||
@ -1914,7 +1918,7 @@ fdcopy(struct filedesc *fdp)
|
||||
|
||||
MPASS(fdp != NULL);
|
||||
|
||||
newfdp = fdinit(fdp);
|
||||
newfdp = fdinit(fdp, true);
|
||||
/* copy all passable descriptors (i.e. not kqueue) */
|
||||
newfdp->fd_freefile = -1;
|
||||
for (i = 0; i <= fdp->fd_lastfile; ++i) {
|
||||
|
@ -333,7 +333,7 @@ fork_norfproc(struct thread *td, int flags)
|
||||
*/
|
||||
if (flags & RFCFDG) {
|
||||
struct filedesc *fdtmp;
|
||||
fdtmp = fdinit(td->td_proc->p_fd);
|
||||
fdtmp = fdinit(td->td_proc->p_fd, false);
|
||||
fdescfree(td);
|
||||
p1->p_fd = fdtmp;
|
||||
}
|
||||
@ -418,7 +418,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
|
||||
* Copy filedesc.
|
||||
*/
|
||||
if (flags & RFCFDG) {
|
||||
fd = fdinit(p1->p_fd);
|
||||
fd = fdinit(p1->p_fd, false);
|
||||
fdtol = NULL;
|
||||
} else if (flags & RFFDG) {
|
||||
fd = fdcopy(p1->p_fd);
|
||||
|
Loading…
Reference in New Issue
Block a user