transid = rfp->fp_wtid + VFS_TRANSID;
rfp->fp_sendrec->m_type = TRNS_ADD_ID(rfp->fp_sendrec->m_type, transid);
+ rfp->fp_task = vmp->m_fs_e;
if ((r = asynsend3(vmp->m_fs_e, rfp->fp_sendrec, AMF_NOREPLY)) != OK) {
printf("VFS: sendmsg: error sending message. "
"FS_e: %d req_nr: %d err: %d\n", vmp->m_fs_e,
}
*rfp->fp_sendrec = m_in;
+ rfp->fp_task = NONE;
vmp->m_comm.c_cur_reqs--; /* We've got our reply, make room for others */
worker_signal(worker_get(rfp->fp_wtid));/* Continue this worker thread */
fp->fp_buffer, fp->fp_nbytes);
if (r != SUSPEND) /* Do we have results to report? */
- reply(who_e, r);
+ (void) reply(who_e, r);
unlock_filp(f);
*===========================================================================*/
PRIVATE void *do_work(void *arg)
{
- int error;
+ int error, i;
struct job my_job;
+ struct fproc *rfp;
+ struct vmnt *vmp;
my_job = *((struct job *) arg);
fp = my_job.j_fp;
/* Copy the results back to the user and send reply. */
if (error != SUSPEND) {
if (deadlock_resolving) {
- struct vmnt *vmp;
if ((vmp = find_vmnt(who_e)) != NULL)
vmp->m_flags &= ~VMNT_BACKCALL;
if (fp->fp_wtid == dl_worker.w_tid)
deadlock_resolving = 0;
}
- reply(who_e, error );
+ if (reply(who_e, error) != OK) {
+ if ((vmp = find_vmnt(who_e)) != NULL) {
+ for (i = 0; i < NR_PROCS; i++) {
+ rfp = &fproc[i];
+ if (rfp->fp_task == vmp->m_fs_e) {
+ /* We found a process waiting for a
+ * reply from non-responsive FS */
+ worker_stop(worker_get(rfp->fp_wtid));
+ }
+ }
+ }
+ }
}
thread_cleanup(fp);
/*===========================================================================*
* reply *
*===========================================================================*/
-PUBLIC void reply(whom, result)
+PUBLIC int reply(whom, result)
int whom; /* process to reply to */
int result; /* result of the call (usually OK or error #) */
{
r = sendnb(whom, &m_out);
if (r != OK) {
printf("VFS: couldn't send reply %d to %d: %d\n", result, whom, r);
- panic("Yikes %d", call_nr);
}
+ return(r);
}
/*===========================================================================*
break;
case PM_SETGROUPS:
- pm_setgroups(m_in.PM_PROC, m_in.PM_GROUP_NO, m_in.PM_GROUP_ADDR);
+ pm_setgroups(m_in.PM_PROC, m_in.PM_GROUP_NO,
+ (gid_t *) m_in.PM_GROUP_ADDR);
m_out.m_type = PM_SETGROUPS_REPLY;
m_out.PM_PROC = m_in.PM_PROC;
} else
r = EBUSY;
- if (vp != NULL)
+ if (vp != NULL) {
+ /* Quickly unlock to allow back calls (from e.g. FUSE) to
+ * relock */
unlock_vmnt(parent_vmp);
+ }
if (r != OK) {
if (vp != NULL) {
/* main.c */
_PROTOTYPE( int main, (void) );
-_PROTOTYPE( void reply, (int whom, int result) );
+_PROTOTYPE( int reply, (int whom, int result) );
_PROTOTYPE( void lock_proc, (struct fproc *rfp, int force_lock) );
_PROTOTYPE( void unlock_proc, (struct fproc *rfp) );
_PROTOTYPE( void *do_dummy, (void *arg) );
_PROTOTYPE( struct job *worker_getjob, (thread_t worker_tid) );
_PROTOTYPE( void worker_init, (struct worker_thread *worker) );
_PROTOTYPE( struct worker_thread *worker_self, (void) );
-_PROTOTYPE( void worker_start, (void *(*func)(void *arg)) );
_PROTOTYPE( void worker_signal, (struct worker_thread *worker) );
+_PROTOTYPE( void worker_start, (void *(*func)(void *arg)) );
+_PROTOTYPE( void worker_stop, (struct worker_thread *worker) );
_PROTOTYPE( void worker_wait, (void) );
_PROTOTYPE( void sys_worker_start, (void *(*func)(void *arg)) );
_PROTOTYPE( void dl_worker_start, (void *(*func)(void *arg)) );
*===========================================================================*/
PUBLIC void unlock_vnode(struct vnode *vp)
{
+#if LOCK_DEBUG
int i;
register struct vnode *rvp;
struct worker_thread *w;
+#endif
ASSERTVP(vp);
#if LOCK_DEBUG
worker_wake(worker);
}
+/*===========================================================================*
+ * worker_stop *
+ *===========================================================================*/
+PUBLIC void worker_stop(struct worker_thread *worker)
+{
+ ASSERTW(worker); /* Make sure we have a valid thread */
+ worker->w_job.j_m_in.m_type = -EIO;
+ worker_wake(worker);
+}
+
/*===========================================================================*
* worker_self *
*===========================================================================*/