Make AVFS resilient against failing back calls
This commit is contained in:
parent
8a266a478e
commit
7db039347a
@ -24,6 +24,7 @@ struct fproc *rfp;
|
|||||||
|
|
||||||
transid = rfp->fp_wtid + VFS_TRANSID;
|
transid = rfp->fp_wtid + VFS_TRANSID;
|
||||||
rfp->fp_sendrec->m_type = TRNS_ADD_ID(rfp->fp_sendrec->m_type, 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) {
|
if ((r = asynsend3(vmp->m_fs_e, rfp->fp_sendrec, AMF_NOREPLY)) != OK) {
|
||||||
printf("VFS: sendmsg: error sending message. "
|
printf("VFS: sendmsg: error sending message. "
|
||||||
"FS_e: %d req_nr: %d err: %d\n", vmp->m_fs_e,
|
"FS_e: %d req_nr: %d err: %d\n", vmp->m_fs_e,
|
||||||
|
@ -257,6 +257,7 @@ PRIVATE void *do_fs_reply(struct job *job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*rfp->fp_sendrec = m_in;
|
*rfp->fp_sendrec = m_in;
|
||||||
|
rfp->fp_task = NONE;
|
||||||
vmp->m_comm.c_cur_reqs--; /* We've got our reply, make room for others */
|
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 */
|
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);
|
fp->fp_buffer, fp->fp_nbytes);
|
||||||
|
|
||||||
if (r != SUSPEND) /* Do we have results to report? */
|
if (r != SUSPEND) /* Do we have results to report? */
|
||||||
reply(who_e, r);
|
(void) reply(who_e, r);
|
||||||
|
|
||||||
unlock_filp(f);
|
unlock_filp(f);
|
||||||
|
|
||||||
@ -376,8 +377,10 @@ PUBLIC void *do_dummy(void *arg)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void *do_work(void *arg)
|
PRIVATE void *do_work(void *arg)
|
||||||
{
|
{
|
||||||
int error;
|
int error, i;
|
||||||
struct job my_job;
|
struct job my_job;
|
||||||
|
struct fproc *rfp;
|
||||||
|
struct vmnt *vmp;
|
||||||
|
|
||||||
my_job = *((struct job *) arg);
|
my_job = *((struct job *) arg);
|
||||||
fp = my_job.j_fp;
|
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. */
|
/* Copy the results back to the user and send reply. */
|
||||||
if (error != SUSPEND) {
|
if (error != SUSPEND) {
|
||||||
if (deadlock_resolving) {
|
if (deadlock_resolving) {
|
||||||
struct vmnt *vmp;
|
|
||||||
if ((vmp = find_vmnt(who_e)) != NULL)
|
if ((vmp = find_vmnt(who_e)) != NULL)
|
||||||
vmp->m_flags &= ~VMNT_BACKCALL;
|
vmp->m_flags &= ~VMNT_BACKCALL;
|
||||||
|
|
||||||
if (fp->fp_wtid == dl_worker.w_tid)
|
if (fp->fp_wtid == dl_worker.w_tid)
|
||||||
deadlock_resolving = 0;
|
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);
|
thread_cleanup(fp);
|
||||||
@ -751,7 +764,7 @@ PRIVATE void get_work()
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* reply *
|
* reply *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void reply(whom, result)
|
PUBLIC int reply(whom, result)
|
||||||
int whom; /* process to reply to */
|
int whom; /* process to reply to */
|
||||||
int result; /* result of the call (usually OK or error #) */
|
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);
|
r = sendnb(whom, &m_out);
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
printf("VFS: couldn't send reply %d to %d: %d\n", result, whom, r);
|
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;
|
break;
|
||||||
case PM_SETGROUPS:
|
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.m_type = PM_SETGROUPS_REPLY;
|
||||||
m_out.PM_PROC = m_in.PM_PROC;
|
m_out.PM_PROC = m_in.PM_PROC;
|
||||||
|
@ -222,8 +222,11 @@ char mount_label[LABEL_MAX] )
|
|||||||
} else
|
} else
|
||||||
r = EBUSY;
|
r = EBUSY;
|
||||||
|
|
||||||
if (vp != NULL)
|
if (vp != NULL) {
|
||||||
|
/* Quickly unlock to allow back calls (from e.g. FUSE) to
|
||||||
|
* relock */
|
||||||
unlock_vmnt(parent_vmp);
|
unlock_vmnt(parent_vmp);
|
||||||
|
}
|
||||||
|
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
if (vp != NULL) {
|
if (vp != NULL) {
|
||||||
|
@ -116,7 +116,7 @@ _PROTOTYPE( void lock_revive, (void) );
|
|||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
_PROTOTYPE( int main, (void) );
|
_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 lock_proc, (struct fproc *rfp, int force_lock) );
|
||||||
_PROTOTYPE( void unlock_proc, (struct fproc *rfp) );
|
_PROTOTYPE( void unlock_proc, (struct fproc *rfp) );
|
||||||
_PROTOTYPE( void *do_dummy, (void *arg) );
|
_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( struct job *worker_getjob, (thread_t worker_tid) );
|
||||||
_PROTOTYPE( void worker_init, (struct worker_thread *worker) );
|
_PROTOTYPE( void worker_init, (struct worker_thread *worker) );
|
||||||
_PROTOTYPE( struct worker_thread *worker_self, (void) );
|
_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_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 worker_wait, (void) );
|
||||||
_PROTOTYPE( void sys_worker_start, (void *(*func)(void *arg)) );
|
_PROTOTYPE( void sys_worker_start, (void *(*func)(void *arg)) );
|
||||||
_PROTOTYPE( void dl_worker_start, (void *(*func)(void *arg)) );
|
_PROTOTYPE( void dl_worker_start, (void *(*func)(void *arg)) );
|
||||||
|
@ -177,9 +177,11 @@ PUBLIC int lock_vnode(struct vnode *vp, tll_access_t locktype)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void unlock_vnode(struct vnode *vp)
|
PUBLIC void unlock_vnode(struct vnode *vp)
|
||||||
{
|
{
|
||||||
|
#if LOCK_DEBUG
|
||||||
int i;
|
int i;
|
||||||
register struct vnode *rvp;
|
register struct vnode *rvp;
|
||||||
struct worker_thread *w;
|
struct worker_thread *w;
|
||||||
|
#endif
|
||||||
ASSERTVP(vp);
|
ASSERTVP(vp);
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
|
@ -286,6 +286,16 @@ PUBLIC void worker_signal(struct worker_thread *worker)
|
|||||||
worker_wake(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 *
|
* worker_self *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user