VFS: remove FP_BLOCKED_ON_DOPEN

These days, DEV_OPEN calls to character drivers block the calling
thread until completion or failure, and thus never return SUSPEND to
the caller. The same already applied to BDEV_OPEN calls to block
drivers. It has thus become impossible for a process to enter a state
of being blocked on a device open call.

There is currently no support for restarting device open calls to
restarted character drivers. This support was present in the _DOPEN
logic, but was already no longer triggering. In the future, this case
should be handled by the thread performing the open request.

Change-Id: I6cc1e7b4c9ed116c6ce160b315e6e060124dce00
This commit is contained in:
David van Moolenbroek 2013-08-30 13:00:44 +02:00 committed by Lionel Sambuc
parent 784cdd4d07
commit c7fbafe1ad
7 changed files with 5 additions and 84 deletions

View file

@ -203,7 +203,6 @@ static char *prrecv(struct pstat *ps)
case FSTATE_LOCK: blkstr = "flock"; break;
case FSTATE_POPEN: blkstr = "popen"; break;
case FSTATE_SELECT: blkstr = "select"; break;
case FSTATE_DOPEN: blkstr = "dopen"; break;
case FSTATE_TASK: blkstr = taskname(ps->ps_ftask); break;
default: blkstr = "??"; break;
}

View file

@ -35,7 +35,6 @@
#define FSTATE_LOCK 'L'
#define FSTATE_POPEN 'O'
#define FSTATE_SELECT 'S'
#define FSTATE_DOPEN 'D'
#define FSTATE_TASK 'T'
#define FSTATE_UNKNOWN '?'

View file

@ -136,7 +136,6 @@ static void pid_psinfo(int i)
case FP_BLOCKED_ON_LOCK: f_state = FSTATE_LOCK; break;
case FP_BLOCKED_ON_POPEN: f_state = FSTATE_POPEN; break;
case FP_BLOCKED_ON_SELECT: f_state = FSTATE_SELECT; break;
case FP_BLOCKED_ON_DOPEN: f_state = FSTATE_DOPEN; break;
case FP_BLOCKED_ON_OTHER: f_state = FSTATE_TASK; break;
default: f_state = FSTATE_UNKNOWN;
}

View file

@ -20,8 +20,7 @@
#define FP_BLOCKED_ON_LOCK 2 /* susp'd on lock */
#define FP_BLOCKED_ON_POPEN 3 /* susp'd on pipe open */
#define FP_BLOCKED_ON_SELECT 4 /* susp'd on select */
#define FP_BLOCKED_ON_DOPEN 5 /* susp'd on device open */
#define FP_BLOCKED_ON_OTHER 6 /* blocked on other process, check
#define FP_BLOCKED_ON_OTHER 5 /* blocked on other process, check
fp_task to find out */
/* test if the process is blocked on something */

View file

@ -928,30 +928,10 @@ void cdev_up(int maj)
{
/* A new character device driver has been mapped in.
*/
int needs_reopen, fd_nr;
int needs_reopen;
struct filp *rfilp;
struct fproc *rfp;
struct vnode *vp;
/* Look for processes that are suspended in an OPEN call. Set FP_SUSP_REOPEN
* to indicate that this process was suspended before the call to dev_up.
*/
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if(rfp->fp_pid == PID_FREE) continue;
if(rfp->fp_blocked_on != FP_BLOCKED_ON_DOPEN) continue;
fd_nr = scratch(rfp).file.fd_nr;
printf("VFS: dev_up: found process in FP_BLOCKED_ON_DOPEN, fd %d\n",
fd_nr);
rfilp = rfp->fp_filp[fd_nr];
vp = rfilp->filp_vno;
if (!vp) panic("VFS: cdev_up: no vp");
if (!S_ISCHR(vp->v_mode)) continue;
if (major(vp->v_sdev) != maj) continue;
rfp->fp_flags |= FP_SUSP_REOPEN;
}
needs_reopen= FALSE;
for (rfilp = filp; rfilp < &filp[NR_FILPS]; rfilp++) {
if (rfilp->filp_count < 1 || !(vp = rfilp->filp_vno)) continue;
@ -1017,7 +997,7 @@ void dev_reply(struct dmap *dp)
static void restart_reopen(maj)
int maj;
{
int n, r, minor_dev, major_dev, fd_nr;
int n, r, minor_dev, major_dev;
endpoint_t driver_e;
struct vnode *vp;
struct filp *rfilp;
@ -1074,34 +1054,6 @@ int maj;
reply(&m_out, rfp->fp_endpoint, ERESTART);
}
}
/* Look for processes that are suspened in an OPEN call */
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if (rfp->fp_pid == PID_FREE) continue;
if (rfp->fp_blocked_on == FP_BLOCKED_ON_DOPEN ||
!(rfp->fp_flags & FP_SUSP_REOPEN)) continue;
fd_nr = scratch(rfp).file.fd_nr;
printf("VFS: restart_reopen: process in FP_BLOCKED_ON_DOPEN fd=%d\n",
fd_nr);
rfilp = rfp->fp_filp[fd_nr];
if (!rfilp) {
/* Open failed, and automatic reopen was not requested */
rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
FD_CLR(fd_nr, &rfp->fp_filp_inuse);
reply(&m_out, rfp->fp_endpoint, EIO);
continue;
}
vp = rfilp->filp_vno;
if (!vp) panic("VFS: restart_reopen: no vp");
if (!S_ISCHR(vp->v_mode)) continue;
if (major(vp->v_sdev) != maj) continue;
rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
reply(&m_out, rfp->fp_endpoint, fd_nr);
}
}

View file

@ -160,9 +160,8 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode)
dev = (dev_t) vp->v_sdev;
/* TTY needs to know about the O_NOCTTY flag. */
r = dev_open(dev, who_e, bits | (oflags & O_NOCTTY));
if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN);
else vp = filp->filp_vno; /* Might be updated by
* dev_open/clone_opcl */
vp = filp->filp_vno; /* Might be updated by
* dev_open/clone_opcl */
break;
case S_IFBLK:

View file

@ -436,7 +436,6 @@ int count; /* max number of processes to release */
*/
if (rp->fp_blocked_on == FP_BLOCKED_ON_POPEN ||
rp->fp_blocked_on == FP_BLOCKED_ON_DOPEN ||
rp->fp_blocked_on == FP_BLOCKED_ON_LOCK ||
rp->fp_blocked_on == FP_BLOCKED_ON_OTHER) {
if (!FD_ISSET(scratch(rp).file.fd_nr,
@ -474,7 +473,6 @@ void revive(endpoint_t proc_e, int returned)
struct fproc *rfp;
int blocked_on;
int fd_nr, slot;
struct filp *fil_ptr;
if (proc_e == NONE || isokendpt(proc_e, &slot) != OK) return;
@ -492,26 +490,6 @@ void revive(endpoint_t proc_e, int returned)
/* Revive a process suspended on a pipe or lock. */
rfp->fp_flags |= FP_REVIVED;
reviving++; /* process was waiting on pipe or lock */
} else if (blocked_on == FP_BLOCKED_ON_DOPEN) {
rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
scratch(rfp).file.fd_nr = 0;
if (returned < 0) {
fil_ptr = rfp->fp_filp[fd_nr];
lock_filp(fil_ptr, VNODE_OPCL);
rfp->fp_filp[fd_nr] = NULL;
FD_CLR(fd_nr, &rfp->fp_filp_inuse);
if (fil_ptr->filp_count != 1) {
panic("VFS: revive: bad count in filp: %d",
fil_ptr->filp_count);
}
fil_ptr->filp_count = 0;
unlock_filp(fil_ptr);
put_vnode(fil_ptr->filp_vno);
fil_ptr->filp_vno = NULL;
replycode(proc_e, returned);
} else {
replycode(proc_e, fd_nr);
}
} else {
rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
scratch(rfp).file.fd_nr = 0;
@ -586,10 +564,6 @@ void unpause(endpoint_t proc_e)
case FP_BLOCKED_ON_POPEN: /* process trying to open a fifo */
break;
case FP_BLOCKED_ON_DOPEN:/* process trying to open a device */
/* Don't cancel OPEN. Just wait until the open completes. */
return;
case FP_BLOCKED_ON_OTHER:/* process trying to do device I/O (e.g. tty)*/
if (rfp->fp_flags & FP_SUSP_REOPEN) {
/* Process is suspended while waiting for a reopen.