From febb4403ff9767d607d5db9e8fd8b7dc8e6ce2bf Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Thu, 27 Oct 2011 15:26:08 +0000 Subject: [PATCH] Reenable backcall detection --- servers/avfs/comm.c | 4 ++-- servers/avfs/dmap.c | 7 ++++++- servers/avfs/fproc.h | 11 ++++++----- servers/avfs/main.c | 28 ++++++++++++++++++++++++---- servers/avfs/mount.c | 10 ++++++++-- servers/avfs/vmnt.h | 2 +- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/servers/avfs/comm.c b/servers/avfs/comm.c index 8546622ac..b11b06e05 100644 --- a/servers/avfs/comm.c +++ b/servers/avfs/comm.c @@ -62,7 +62,7 @@ PUBLIC void fs_sendmore(struct vmnt *vmp) return; if (vmp->m_comm.c_cur_reqs >= vmp->m_comm.c_max_reqs)/*No room to send more*/ return; - if (vmp->m_flags & VMNT_BACKCALL) /* Hold off for now */ + if (vmp->m_flags & VMNT_CALLBACK) /* Hold off for now */ return; vmp->m_comm.c_req_queue = worker->w_next; /* Remove head */ @@ -88,7 +88,7 @@ PUBLIC int fs_sendrec(endpoint_t fs_e, message *reqmp) fp->fp_sendrec = reqmp; /* Where to store request and reply */ /* Find out whether we can send right away or have to enqueue */ - if ( !(vmp->m_flags & VMNT_BACKCALL) && + if ( !(vmp->m_flags & VMNT_CALLBACK) && vmp->m_comm.c_cur_reqs < vmp->m_comm.c_max_reqs) { /* There's still room to send more and no proc is queued */ r = sendmsg(vmp, fp); diff --git a/servers/avfs/dmap.c b/servers/avfs/dmap.c index d73aa1fac..687f0c2aa 100644 --- a/servers/avfs/dmap.c +++ b/servers/avfs/dmap.c @@ -96,7 +96,7 @@ int flags; /* device flags */ dp = &dmap[major]; /* Check if we're supposed to unmap it. */ - if(proc_nr_e == NONE) { + if (proc_nr_e == NONE) { dp->dmap_opcl = no_dev; dp->dmap_io = no_dev_io; dp->dmap_driver = NONE; @@ -106,8 +106,13 @@ int flags; /* device flags */ /* Check process number of new driver if it was alive before mapping */ if (! (flags & DRV_FORCED)) { + struct fproc *rfp; + if (isokendpt(proc_nr_e, &slot) != OK) return(EINVAL); + + rfp = &fproc[slot]; + rfp->fp_flags |= FP_SYS_PROC; /* Process is a driver */ } if (label != NULL) { diff --git a/servers/avfs/fproc.h b/servers/avfs/fproc.h index 465c8ed64..43f2012d2 100644 --- a/servers/avfs/fproc.h +++ b/servers/avfs/fproc.h @@ -58,11 +58,12 @@ EXTERN struct fproc { #define FP_SUSP_REOPEN 01 /* Process is suspended until the reopens are * completed (after the restart of a driver). */ -#define FP_REVIVED 02 /* Indicates process is being revived */ -#define FP_SESLDR 04 /* Set if process is session leader */ -#define FP_PENDING 010 /* Set if process has pending work */ -#define FP_EXITING 020 /* Set if process is exiting */ -#define FP_PM_PENDING 040 /* Set if process has pending PM request */ +#define FP_REVIVED 0002 /* Indicates process is being revived */ +#define FP_SESLDR 0004 /* Set if process is session leader */ +#define FP_PENDING 0010 /* Set if process has pending work */ +#define FP_EXITING 0020 /* Set if process is exiting */ +#define FP_PM_PENDING 0040 /* Set if process has pending PM request */ +#define FP_SYS_PROC 0100 /* Set if process is a driver or FS */ /* Field values. */ #define NOT_REVIVING 0xC0FFEEE /* process is not being revived */ diff --git a/servers/avfs/main.c b/servers/avfs/main.c index 135ab38d8..e07f66ef6 100644 --- a/servers/avfs/main.c +++ b/servers/avfs/main.c @@ -77,7 +77,7 @@ PUBLIC int main(void) /* SEF local startup. */ sef_local_startup(); - printf("Started AVFS\n"); + printf("Started AVFS: %d worker thread(s)\n", NR_WTHREADS); verbose = 0; /* This is the main loop that gets work, processes it, and sends replies. */ @@ -140,12 +140,16 @@ PRIVATE void handle_work(void *(*func)(void *arg)) { /* Handle asynchronous device replies and new system calls. If the originating * endpoint is an FS endpoint, take extra care not to get in deadlock. */ - struct vmnt *vmp; + struct vmnt *vmp = NULL; if ((vmp = find_vmnt(who_e)) != NULL) { - /* A back call or dev result from an FS endpoint */ + /* A call back or dev result from an FS endpoint */ - /* When an FS point has to make a callback in order to mount, force + /* Set call back flag. We assume that an FS does only one call back + * at a time */ + vmp->m_flags |= VMNT_CALLBACK; + + /* When an FS point has to make a call back in order to mount, force * its device to a "none device" so block reads/writes will be handled * by ROOT_FS_E. */ @@ -157,6 +161,7 @@ PRIVATE void handle_work(void *(*func)(void *arg)) if (deadlock_resolving) { /* Already trying to resolve a deadlock, can't * handle more, sorry */ + vmp->m_flags &= ~VMNT_CALLBACK; reply(who_e, EAGAIN); return; } @@ -208,6 +213,13 @@ PRIVATE void *do_async_dev_result(void *arg) deadlock_resolving = 0; } + if (fp != NULL && (fp->fp_flags & FP_SYS_PROC)) { + struct vmnt *vmp; + + if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL) + vmp->m_flags &= ~VMNT_CALLBACK; + } + thread_cleanup(NULL); return(NULL); } @@ -425,6 +437,14 @@ PRIVATE void *do_work(void *arg) /* Copy the results back to the user and send reply. */ if (error != SUSPEND) { + + if ((fp->fp_flags & FP_SYS_PROC)) { + struct vmnt *vmp; + + if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL) + vmp->m_flags &= ~VMNT_CALLBACK; + } + if (deadlock_resolving) { if (fp->fp_wtid == dl_worker.w_tid) deadlock_resolving = 0; diff --git a/servers/avfs/mount.c b/servers/avfs/mount.c index 656995732..362a2d4ec 100644 --- a/servers/avfs/mount.c +++ b/servers/avfs/mount.c @@ -167,8 +167,8 @@ int rdonly, char mount_label[LABEL_MAX] ) { int rdir, mdir; /* TRUE iff {root|mount} file is dir */ - int i, r = OK, found, isroot, mount_root, con_reqs; - struct fproc *tfp; + int i, r = OK, found, isroot, mount_root, con_reqs, slot; + struct fproc *tfp, *rfp; struct dmap *dp; struct vnode *root_node, *vp = NULL; struct vmnt *new_vmp, *parent_vmp; @@ -249,6 +249,12 @@ char mount_label[LABEL_MAX] ) lock_vnode(root_node, VNODE_OPCL); + /* Record process as a system process */ + if (isokendpt(fs_e, &slot) != OK) + return(EINVAL); + rfp = &fproc[slot]; + rfp->fp_flags |= FP_SYS_PROC; /* Process is an FS */ + /* Store some essential vmnt data first */ new_vmp->m_fs_e = fs_e; new_vmp->m_dev = dev; diff --git a/servers/avfs/vmnt.h b/servers/avfs/vmnt.h index 510502c01..14d00b3ab 100644 --- a/servers/avfs/vmnt.h +++ b/servers/avfs/vmnt.h @@ -14,7 +14,7 @@ EXTERN struct vmnt { /* vmnt flags */ #define VMNT_READONLY 01 /* Device mounted readonly */ -#define VMNT_BACKCALL 02 /* FS did back call */ +#define VMNT_CALLBACK 02 /* FS did back call */ #define VMNT_MOUNTING 04 /* Device is being mounted */ #define VMNT_FORCEROOTBSF 010 /* Force usage of none-device */