Make AVFS resilient against failing back calls

This commit is contained in:
Thomas Veerman 2011-09-06 10:11:18 +00:00
parent 8a266a478e
commit 7db039347a
6 changed files with 41 additions and 10 deletions

View File

@ -24,6 +24,7 @@ struct fproc *rfp;
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,

View File

@ -257,6 +257,7 @@ PRIVATE void *do_fs_reply(struct job *job)
}
*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 */
@ -342,7 +343,7 @@ PRIVATE void *do_pending_pipe(void *arg)
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);
@ -376,8 +377,10 @@ PUBLIC void *do_dummy(void *arg)
*===========================================================================*/
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;
@ -422,14 +425,24 @@ PRIVATE void *do_work(void *arg)
/* 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);
@ -751,7 +764,7 @@ PRIVATE void get_work()
/*===========================================================================*
* 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 #) */
{
@ -762,8 +775,8 @@ 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);
}
/*===========================================================================*
@ -895,7 +908,8 @@ PRIVATE void service_pm()
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;

View File

@ -222,8 +222,11 @@ char mount_label[LABEL_MAX] )
} 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) {

View File

@ -116,7 +116,7 @@ _PROTOTYPE( void lock_revive, (void) );
/* 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) );
@ -366,8 +366,9 @@ _PROTOTYPE( struct worker_thread *worker_get, (thread_t worker_tid) );
_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)) );

View File

@ -177,9 +177,11 @@ PUBLIC int lock_vnode(struct vnode *vp, tll_access_t locktype)
*===========================================================================*/
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

View File

@ -286,6 +286,16 @@ PUBLIC void worker_signal(struct worker_thread *worker)
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 *
*===========================================================================*/