mode_t fp_umask; /* mask set by umask system call */
- struct vnode *fp_wd; /* working directory */
- struct vnode *fp_rd; /* root directory */
+ struct vnode *fp_wd; /* working directory; NULL during reboot */
+ struct vnode *fp_rd; /* root directory; NULL during reboot */
struct filp *fp_filp[OPEN_MAX];/* the file descriptor table */
/* Check for special control messages first. */
if ((call_nr & NOTIFY_MESSAGE)) {
- if (call_nr == PROC_EVENT)
+ if (call_nr == PROC_EVENT && who_e == PM_PROC_NR)
{
/* PM tries to get FS to do something */
service_pm();
}
- else if (call_nr == SYN_ALARM)
+ else if (call_nr == SYN_ALARM && who_e == CLOCK)
{
/* Alarm timer expired. Used only for select().
* Check it.
return(OK);
}
+void unmount_all(void)
+{
+ int i;
+ int found = 0, worked = 0, remain = 0;
+ /* Unmount all filesystems. File systems are mounted on other file systems,
+ * so you have to pull off the loose bits repeatedly to get it all undone.
+ */
+ for (i= 0; i < NR_SUPERS; i++) {
+ struct vmnt *vmp;
+ /* Unmount at least one. */
+ worked = remain = 0;
+ for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
+ if (vmp->m_dev != NO_DEV) {
+ found++;
+ CHECK_VREFS;
+ if(unmount(vmp->m_dev) == OK)
+ worked++;
+ else
+ remain++;
+ CHECK_VREFS;
+ }
+ }
+ }
+
+ printf("VFS: worked: %d remain: %d\n", worked, remain);
+}
+
/*===========================================================================*
* pm_reboot *
*===========================================================================*/
{
/* Perform the FS side of the reboot call. */
int i;
- struct vmnt *vmp;
do_sync();
* will tell us about it).
*/
for (i = 0; i < NR_PROCS; i++)
- if((m_in.endpt1 = fproc[i].fp_endpoint) != NONE)
- free_proc(&fproc[i], FP_EXITING);
+ if((m_in.endpt1 = fproc[i].fp_endpoint) != NONE) {
+ /* No FP_EXITING, just free the resources, otherwise
+ * consistency check for fp_endpoint (set to NONE) will
+ * fail if process wants to do something in the (short)
+ * future.
+ */
+ free_proc(&fproc[i], 0);
+ }
CHECK_VREFS;
- /* The root file system is mounted onto itself, which keeps it from being
- * unmounted. Pull an inode out of thin air and put the root on it.
- */
-
- /* Unmount all filesystems. File systems are mounted on other file systems,
- * so you have to pull off the loose bits repeatedly to get it all undone.
- */
- for (i= 0; i < NR_SUPERS; i++) {
- /* Unmount at least one. */
- for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
- if (vmp->m_dev != NO_DEV) {
- CHECK_VREFS;
- (void) unmount(vmp->m_dev);
- CHECK_VREFS;
- }
- }
- }
+ unmount_all();
CHECK_VREFS;
/* Increase the counters in the 'filp' table. */
cp = &fproc[childno];
fp = &fproc[parentno];
+
for (i = 0; i < OPEN_MAX; i++)
if (cp->fp_filp[i] != NIL_FILP) cp->fp_filp[i]->filp_count++;
cp->fp_execced = 0;
/* Record the fact that both root and working dir have another user. */
- dup_vnode(cp->fp_rd);
- dup_vnode(cp->fp_wd);
+ if(cp->fp_rd) dup_vnode(cp->fp_rd);
+ if(cp->fp_wd) dup_vnode(cp->fp_wd);
}
/*===========================================================================*
fp = exiter; /* get_filp() needs 'fp' */
+ if(fp->fp_endpoint == NONE) {
+ panic(__FILE__, "free_proc: already free", NO_NUM);
+ }
+
if (fp->fp_suspended == SUSPENDED) {
task = -fp->fp_task;
if (task == XPIPE || task == XPOPEN) susp_count--;
for (i = 0; i < OPEN_MAX; i++) {
(void) close_fd(fp, i);
}
-
- /* Release root and working directories. */
- put_vnode(fp->fp_rd);
- put_vnode(fp->fp_wd);
- fp->fp_rd = NIL_VNODE;
- fp->fp_wd = NIL_VNODE;
/* Check if any process is SUSPENDed on this driver.
* If a driver exits, unmap its entries in the dmap table.
*/
unsuspend_by_endpt(fp->fp_endpoint);
+ /* Release root and working directories. */
+ 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 (tfp->fp_pid == PID_FREE)
continue;
- if (tfp->fp_rd == NULL)
- panic("fs", "do_mount: null rootdir", i);
- if (tfp->fp_wd == NULL)
- panic("fs", "do_mount: null workdir", i);
-
- put_vnode(tfp->fp_rd);
- dup_vnode(root_node);
- tfp->fp_rd = root_node;
-
- put_vnode(tfp->fp_wd);
- dup_vnode(root_node);
- tfp->fp_wd = root_node;
+#define MAKEROOT(what) { \
+ put_vnode(what); \
+ dup_vnode(root_node); \
+ what = root_node; \
+ }
+
+ if(tfp->fp_rd) MAKEROOT(tfp->fp_rd);
+ if(tfp->fp_wd) MAKEROOT(tfp->fp_wd);
}
CHECK_VREFS;
for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++) {
if (vp->v_ref_count > 0 && vp->v_dev == dev) {
-#if 1
+#if 0
int i;
struct fproc *tfp;
- if(!(vp->v_inode_nr == 1 && vp->v_ref_count == 1)) {
printf("unmount: vnode 0x%x/%d in use %d times\n",
dev, vp->v_inode_nr, vp->v_ref_count);
- }
for (i= 0, tfp= fproc; i<NR_PROCS; i++, tfp++) {
int n;
if (tfp->fp_pid == PID_FREE)
printf("\tvnode %d: is a mount point\n",
vp->v_inode_nr);
}
-#if 0
+#if 1
if(vmp_i->m_root_node == vp) {
printf("\tvnode %d: is a root node\n",
vp->v_inode_nr);
struct node_details res;
char lastc[PATH_MAX+1];
+ if(!fp->fp_rd || !fp->fp_wd) {
+ printf("VFS: %d: no rd/wd\n", fp->fp_endpoint);
+ return ENOENT;
+ }
+
start_vp = (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
dup_vnode(start_vp);
*/
struct vnode *vp;
+ if(!fp->fp_rd || !fp->fp_wd) {
+ printf("VFS: lookup_vp %d: no rd/wd\n", fp->fp_endpoint);
+ return ENOENT;
+ }
+
vp= (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
return lookup_rel_vp(vp, flags, use_realuid, vpp);
*/
struct vnode *vp;
+ if(!fp->fp_rd || !fp->fp_wd) {
+ printf("VFS: lookup_lastdir %d: no rd/wd\n", fp->fp_endpoint);
+ return ENOENT;
+ }
+
vp= (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
return lookup_lastdir_rel(vp, use_realuid, vpp);
}
return ENOENT;
}
+ if(!fp->fp_rd || !fp->fp_wd) {
+ printf("VFS: lookup_rel %d: no rd/wd\n", fp->fp_endpoint);
+ return ENOENT;
+ }
+
fs_e = start_node->v_fs_e;
path_off = 0;
dir_ino = start_node->v_inode_nr;
struct filp *rfilp;
int r;
+ if(!fp->fp_wd || !fp->fp_rd) {
+ printf("VFS: do_fchdir: %d: no rd/wd\n",
+ fp->fp_endpoint);
+ return ENOENT;
+ }
+
/* Is the file descriptor valid? */
if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
int r;
register struct fproc *rfp;
+ if(!fp->fp_wd || !fp->fp_rd) {
+ printf("VFS: do_chdir: %d: no rd/wd\n",
+ fp->fp_endpoint);
+ return ENOENT;
+ }
+
if (who_e == PM_PROC_NR) {
int slot;
if(isokendpt(m_in.endpt1, &slot) != OK)
return EINVAL;
rfp = &fproc[slot];
+
+ if(!rfp->fp_wd || !rfp->fp_rd) {
+ printf("VFS: do_chdir: %d: no other rd/wd\n", fp->fp_endpoint);
+ return ENOENT;
+ }
put_vnode(fp->fp_rd);
dup_vnode(fp->fp_rd = rfp->fp_rd);
register int r;
if (!super_user) return(EPERM); /* only su may chroot() */
+
+ if(!fp->fp_wd || !fp->fp_rd) {
+ printf("VFS: do_chroot: %d: no rd/wd\n",
+ fp->fp_endpoint);
+ return ENOENT;
+ }
r = change(&fp->fp_rd, m_in.name, m_in.name_length);
return(r);
for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if (rfp->fp_pid == PID_FREE)
continue;
- REFVP(rfp->fp_rd);
- REFVP(rfp->fp_wd);
+ if(rfp->fp_rd) REFVP(rfp->fp_rd);
+ if(rfp->fp_wd) REFVP(rfp->fp_wd);
}
/* Count references from filedescriptors */