char *fp_buffer; /* place to save buffer if rd/wr can't finish*/
int fp_nbytes; /* place to save bytes if rd/wr can't finish */
int fp_cum_io_partial; /* partial byte count if rd/wr can't finish */
- char fp_suspended; /* set to indicate process hanging */
- char fp_revived; /* set to indicate process being revived */
+ int fp_suspended; /* set to indicate process hanging */
+ int fp_revived; /* set to indicate process being revived */
int fp_task; /* which task is proc suspended on */
endpoint_t fp_ioproc; /* proc no. in suspended-on i/o message */
*/
/* Field values. */
-#define NOT_SUSPENDED 0 /* process is not suspended on pipe or task */
-#define SUSPENDED 1 /* process is suspended on pipe or task */
-#define NOT_REVIVING 0 /* process is not being revived */
-#define REVIVING 1 /* process is being revived from suspension */
+/* fp_suspended is one of these. */
+#define NOT_SUSPENDED 0xC0FFEE /* process is not suspended on pipe or task */
+#define SUSPENDED 0xDEAD /* process is suspended on pipe or task */
+
+#define NOT_REVIVING 0xC0FFEEE /* process is not being revived */
+#define REVIVING 0xDEEAD /* process is being revived from suspension */
#define PID_FREE 0 /* process slot free */
/* Check is process number is acceptable - includes system processes. */
#define _MINIX 1 /* tell headers to include MINIX stuff */
#define _SYSTEM 1 /* tell headers that this is the kernel */
-#define VERBOSE 0 /* show messages during initialization? */
+#define DO_SANITYCHECKS 0
+
+#if DO_SANITYCHECKS
+#define SANITYCHECK do { \
+ if(!check_vrefs() || !check_pipe()) { \
+ printf("VFS:%s:%d: call_nr %d who_e %d\n", \
+ __FILE__, __LINE__, call_nr, who_e); \
+ panic(__FILE__, "sanity check failed", NO_NUM); \
+ } \
+} while(0)
+#else
+#define SANITYCHECK
+#endif
/* The following are so basic, all the *.c files get them automatically. */
#include <minix/config.h> /* MUST be first */
fs_init();
+ SANITYCHECK;
+
/* This is the main loop that gets work, processes it, and sends replies. */
while (TRUE) {
+ SANITYCHECK;
get_work(); /* sets who and call_nr */
if (who_e == PM_PROC_NR && call_nr != PROC_EVENT)
/* Device notifies us of an event. */
dev_status(&m_in);
}
-#if 0
- if (!check_vrefs())
- {
- printf("after call %d from %d/%d\n",
- call_nr, who_p, who_e);
- panic(__FILE__, "check_vrefs failed at line", __LINE__);
- }
-#endif
+ SANITYCHECK;
continue;
}
fp = &fproc[who_p]; /* pointer to proc table struct */
super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */
+#if DO_SANITYCHECKS
+ if(fp->fp_suspended != NOT_SUSPENDED) {
+ printf("VFS: requester %d call %d: not not suspended\n",
+ who_e, call_nr);
+ panic(__FILE__, "requester suspended", NO_NUM);
+ }
+#endif
+
/* Calls from VM. */
if(who_e == VM_PROC_NR) {
int caught = 1;
}
}
+ SANITYCHECK;
+
/* Other calls. */
switch(call_nr)
{
#if ENABLE_SYSCALL_STATS
calls_stats[call_nr]++;
#endif
+ SANITYCHECK;
error = (*call_vec[call_nr])();
+ SANITYCHECK;
}
/* Copy the results back to the user and send reply. */
if (error != SUSPEND) { reply(who_e, error); }
}
-#if 0
- if (!check_vrefs())
- {
- printf("after call %d from %d/%d\n", call_nr, who_p, who_e);
- panic(__FILE__, "check_vrefs failed at line", __LINE__);
- }
-#endif
-
-
+ SANITYCHECK;
}
return(OK); /* shouldn't come here */
}
rfp->fp_effgid = (gid_t) SYS_GID;
rfp->fp_umask = ~0;
rfp->fp_grant = GRANT_INVALID;
+ rfp->fp_suspended = NOT_SUSPENDED;
+ rfp->fp_revived = NOT_REVIVING;
} while (TRUE); /* continue until process NONE */
mess.m_type = OK; /* tell PM that we succeeded */
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
if (vmp->m_dev != NO_DEV) {
found++;
- CHECK_VREFS;
+ SANITYCHECK;
if(unmount(vmp->m_dev) == OK)
worked++;
else
remain++;
- CHECK_VREFS;
+ SANITYCHECK;
}
}
}
do_sync();
- CHECK_VREFS;
+ SANITYCHECK;
/* Do exit processing for all leftover processes and servers,
* but don't actually exit them (if they were really gone, PM
*/
free_proc(&fproc[i], 0);
}
- CHECK_VREFS;
+ SANITYCHECK;
unmount_all();
- CHECK_VREFS;
+ SANITYCHECK;
}
register struct vnode *vp;
dev_t dev;
+ SANITYCHECK;
+
fp = exiter; /* get_filp() needs 'fp' */
if(fp->fp_endpoint == NONE) {
}
if (fp->fp_suspended == SUSPENDED) {
+ SANITYCHECK;
task = -fp->fp_task;
- if (task == XPIPE || task == XPOPEN) susp_count--;
unpause(fp->fp_endpoint);
- fp->fp_suspended = NOT_SUSPENDED;
+ SANITYCHECK;
}
+ SANITYCHECK;
+
/* Loop on file descriptors, closing any that are open. */
for (i = 0; i < OPEN_MAX; i++) {
(void) close_fd(fp, i);
if(fp->fp_rd) { put_vnode(fp->fp_rd); fp->fp_rd = NIL_VNODE; }
if(fp->fp_wd) { put_vnode(fp->fp_wd); fp->fp_wd = NIL_VNODE; }
- CHECK_VREFS;
-
/* The rest of these actions is only done when processes actually
* exit.
*/
- if(!(flags & FP_EXITING))
+ if(!(flags & FP_EXITING)) {
+ SANITYCHECK;
return;
+ }
/* Invalidate endpoint number for error and sanity checks. */
fp->fp_endpoint = NONE;
/* Exit done. Mark slot as free. */
fp->fp_pid = PID_FREE;
+
+ SANITYCHECK;
}
/*===========================================================================*
{
endpoint_t fs_e;
- CHECK_VREFS;
+ SANITYCHECK;
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
char *label;
struct node_details res;
- CHECK_VREFS;
+ SANITYCHECK;
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
if(tfp->fp_wd) MAKEROOT(tfp->fp_wd);
}
- CHECK_VREFS;
+ SANITYCHECK;
return(OK);
}
printf("VFSmount: moving opened block spec to new FS_e: %d...\n", fs_e);
bspec->v_bfs_e = fs_e;
}
- CHECK_VREFS;
+ SANITYCHECK;
return(OK);
}
{
/* Perform the umount(name) system call. */
dev_t dev;
- CHECK_VREFS;
+ SANITYCHECK;
/* Only the super-user may do UMOUNT. */
if (!super_user) return(EPERM);
- CHECK_VREFS;
+ SANITYCHECK;
/* If 'name' is not for a block special file, return error. */
if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
- CHECK_VREFS;
+ SANITYCHECK;
if ( (dev = name_to_dev()) == NO_DEV) return(err_code);
- CHECK_VREFS;
+ SANITYCHECK;
return(unmount(dev));
}
int count, r;
int fs_e;
- CHECK_VREFS;
+ SANITYCHECK;
/* Find vmnt */
for (vmp_i = &vmnt[0]; vmp_i < &vmnt[NR_MNTS]; ++vmp_i) {
count += vp->v_ref_count;
}
}
- CHECK_VREFS;
+ SANITYCHECK;
if (count > 1) {
return(EBUSY); /* can't umount a busy file system */
}
- CHECK_VREFS;
+ SANITYCHECK;
vnode_clean_refs(vmp->m_root_node);
- CHECK_VREFS;
+ SANITYCHECK;
if (vmp->m_mounted_on) {
put_vnode(vmp->m_mounted_on);
vmp->m_dev = NO_DEV;
vmp->m_fs_e = NONE;
- CHECK_VREFS;
+ SANITYCHECK;
/* Is there a block special file that was handled by that partition? */
for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++) {
}
}
- CHECK_VREFS;
+ SANITYCHECK;
return(OK);
}
* The SUSPEND pseudo error should be returned after calling suspend().
*/
+#if DO_SANITYCHECKS
if (task == XPIPE)
panic(__FILE__, "suspend: called for XPIPE", NO_NUM);
+ if(fp->fp_suspended == SUSPENDED)
+ panic(__FILE__, "suspend: called for suspended process", NO_NUM);
+#endif
+
if (task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/
fp->fp_suspended = SUSPENDED;
assert(fp->fp_grant == GRANT_INVALID || !GRANT_VALID(fp->fp_grant));
* but they are needed for pipes, and it is not worth making the distinction.)
* The SUSPEND pseudo error should be returned after calling suspend().
*/
+#if DO_SANITYCHECKS
+ if(fp->fp_suspended == SUSPENDED)
+ panic(__FILE__, "pipe_suspend: called for suspended process", NO_NUM);
+#endif
susp_count++; /* #procs susp'ed on pipe*/
fp->fp_suspended = SUSPENDED;
struct filp *f;
dev_t dev;
message mess;
+ int wasreviving = 0;
if(isokendpt(proc_nr_e, &proc_nr_p) != OK) {
printf("VFS: ignoring unpause for bogus endpoint %d\n", proc_nr_e);
{
rfp->fp_revived = NOT_REVIVING;
reviving--;
+ wasreviving = 1;
}
+
switch (task) {
case XPIPE: /* process trying to read or write a pipe */
break;
}
rfp->fp_suspended = NOT_SUSPENDED;
+
+ if ((task == XPIPE || task == XPOPEN) && !wasreviving) {
+ susp_count--;
+ }
+
reply(proc_nr_e, status); /* signal interrupted call */
}
return 0;
}
+#if DO_SANITYCHECKS
+/*===========================================================================*
+ * check_pipe *
+ *===========================================================================*/
+PUBLIC int check_pipe(void)
+{
+ struct fproc *rfp;
+ int mycount = 0;
+ for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
+ if (rfp->fp_pid == PID_FREE)
+ continue;
+ if(rfp->fp_suspended != SUSPENDED &&
+ rfp->fp_suspended != NOT_SUSPENDED) {
+ printf("check_pipe: %d invalid suspended value 0x%x\n",
+ rfp->fp_endpoint, rfp->fp_suspended);
+ return 0;
+ }
+ if(rfp->fp_suspended == SUSPENDED && rfp->fp_revived != REVIVING && (-rfp->fp_task == XPIPE || -rfp->fp_task == XPOPEN)) {
+ mycount++;
+ }
+ }
+ if(mycount != susp_count) {
+ printf("check_pipe: mycount %d susp_count %d\n",
+ mycount, susp_count);
+ return 0;
+ }
-
+ return 1;
+}
+#endif
_PROTOTYPE( void unsuspend_by_endpt, (int) );
_PROTOTYPE( void select_reply1, (void) );
_PROTOTYPE( void select_reply2, (void) );
+#if DO_SANITYCHECKS
+_PROTOTYPE( int check_pipe, (void) );
+#endif
/* protect.c */
_PROTOTYPE( int do_access, (void) );
_PROTOTYPE( void dup_vnode, (struct vnode *vp) );
_PROTOTYPE( void put_vnode, (struct vnode *vp) );
_PROTOTYPE( void vnode_clean_refs, (struct vnode *vp) );
-#if 0
-_PROTOTYPE( struct vnode *get_vnode, (int fs_e, int inode_nr) );
-_PROTOTYPE( struct vnode *get_vnode_x, (int fs_e, int inode_nr) );
-_PROTOTYPE( void mark_vn, (struct vnode *vp, char *file, int line) );
-#endif
-#define CHECK_VREFS do { if(!check_vrefs()) { \
- printf("VFS:%s:%d: check_vrefs failed\n", __FILE__, __LINE__); \
- panic("VFS", "check_vrefs failed", NO_NUM);} } while(0)
+#if DO_SANITYCHECKS
_PROTOTYPE( int check_vrefs, (void) );
+#endif
/* write.c */
_PROTOTYPE( int do_write, (void) );
#define REFVP(v) { vp = (v); CHECKVN(v); vp->v_ref_check++; }
+#if DO_SANITYCHECKS
/*===========================================================================*
* check_vrefs *
*===========================================================================*/
}
return !bad;
}
+#endif
#define NO_SEEK 0 /* i_seek = NO_SEEK if last op was not SEEK */
#define ISEEK 1 /* i_seek = ISEEK if last op was SEEK */
-
-#define SANITYCHECK do { if(!check_vrefs()) { printf("VFS:%s:%d: vref check failed\n", __FILE__, __LINE__); util_stacktrace(); } } while(0)