}
/*===========================================================================*
- * do_rdlink *
+ * do_rdlink *
*===========================================================================*/
PUBLIC int do_rdlink()
{
lock_proc(fp, 0); /* This proc is busy */
+ if (verbose) {
+ printf("Doing call_nr = %d for %d\n", call_nr, who_e);
+ }
+
if (call_nr == MAPDRIVER) {
error = do_mapdriver();
} else if (call_nr == COMMON_GETSYSINFO) {
PUBLIC int do_sync()
{
struct vmnt *vmp;
+ int r = OK;
+
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
- lock_vmnt(vmp, VMNT_EXCL);
- if (vmp->m_dev != NO_DEV && vmp->m_fs_e != NONE)
+ if (vmp->m_dev != NO_DEV && vmp->m_fs_e != NONE &&
+ vmp->m_root_node != NULL) {
+ if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK)
+ break;
req_sync(vmp->m_fs_e);
- unlock_vmnt(vmp);
+ unlock_vmnt(vmp);
+ }
}
- return(OK);
+ return(r);
}
/*===========================================================================*
*===========================================================================*/
PUBLIC int do_fsync()
{
-/* Perform the fsync() system call. For now, don't be unnecessarily smart. */
+/* Perform the fsync() system call. */
struct filp *rfilp;
struct vmnt *vmp;
dev_t dev;
+ int r = OK;
if ((rfilp = get_filp(m_in.m1_i1, VNODE_READ)) == NULL) return(err_code);
dev = rfilp->filp_vno->v_dev;
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
- lock_vmnt(vmp, VMNT_EXCL);
- if (vmp->m_dev != NO_DEV && vmp->m_dev == dev && vmp->m_fs_e != NONE)
+ if (vmp->m_dev != NO_DEV && vmp->m_dev == dev &&
+ vmp->m_fs_e != NONE && vmp->m_root_node != NULL) {
+
+ if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK)
+ break;
req_sync(vmp->m_fs_e);
- unlock_vmnt(vmp);
+ unlock_vmnt(vmp);
+ }
}
unlock_filp(rfilp);
- return(OK);
+ return(r);
}
/*===========================================================================*
}
}
+ do_sync();
unmount_all();
}
FORWARD _PROTOTYPE( dev_t name_to_dev, (int allow_mountpt,
char path[PATH_MAX+1]) );
-FORWARD _PROTOTYPE( int is_nonedev, (dev_t dev) );
FORWARD _PROTOTYPE( dev_t find_free_nonedev, (void) );
FORWARD _PROTOTYPE( void update_bspec, (dev_t dev, endpoint_t fs_e,
int send_drv_e) );
return(err_code);
/* Do the actual job */
- return mount_fs(dev, fullpath, fs_e, rdonly, mount_label);
+ r = mount_fs(dev, fullpath, fs_e, rdonly, mount_label);
+ return(r);
}
assert(strlen(label) > 0);
}
- lock_bsf();
-
- /* Check whether there is a block special file open which uses the
- * same device (partition) */
- for (bspec = &vnode[0]; bspec < &vnode[NR_VNODES]; ++bspec) {
- if (bspec->v_ref_count > 0 && bspec->v_sdev == dev) {
- /* Found, flush and invalidate any blocks for this device. */
- req_flush(bspec->v_fs_e, dev);
- break;
- }
- }
-
/* Scan vmnt table to see if dev already mounted. If not, find a free slot.*/
found = FALSE;
for (i = 0; i < NR_MNTS; ++i) {
if (vmnt[i].m_dev == dev) found = TRUE;
}
if (found) {
- unlock_bsf();
return(EBUSY);
} else if ((new_vmp = get_free_vmnt()) == NULL) {
- unlock_bsf();
return(ENOMEM);
}
- lock_vmnt(new_vmp, VMNT_EXCL);
+ if ((r = lock_vmnt(new_vmp, VMNT_EXCL)) != OK) return(r);
isroot = (strcmp(mountpoint, "/") == 0);
mount_root = (isroot && have_root < 2); /* Root can be mounted twice:
} else
r = EBUSY;
+ if (vp != NULL)
+ unlock_vmnt(parent_vmp);
+
if (r != OK) {
if (vp != NULL) {
unlock_vnode(vp);
- unlock_vmnt(parent_vmp);
put_vnode(vp);
}
unlock_vmnt(new_vmp);
- unlock_bsf();
return(r);
}
}
if ((root_node = get_free_vnode()) == NULL || dev == 266) {
if (vp != NULL) {
unlock_vnode(vp);
- unlock_vmnt(parent_vmp);
put_vnode(vp);
}
unlock_vmnt(new_vmp);
- unlock_bsf();
return(err_code);
}
else new_vmp->m_flags &= ~VMNT_READONLY;
/* Tell FS which device to mount */
+ if (verbose)
+ printf("Tell FS %d to mount device %s %d\n", fs_e, label, dev);
if ((r = req_readsuper(fs_e, label, dev, rdonly, isroot, &res)) != OK) {
+ if (verbose) printf("Failed: %d\n", r);
if (vp != NULL) {
unlock_vnode(vp);
- unlock_vmnt(parent_vmp);
put_vnode(vp);
}
new_vmp->m_fs_e = NONE;
new_vmp->m_dev = NO_DEV;
unlock_vnode(root_node);
unlock_vmnt(new_vmp);
- unlock_bsf();
return(r);
}
+ if (verbose) printf("Ok done: r=%d\n", r);
/* Fill in root node's fields */
root_node->v_fs_e = res.fs_e;
root_node->v_vmnt = new_vmp;
root_node->v_dev = new_vmp->m_dev;
- if(mount_root) {
+ lock_bsf();
+
+ if (mount_root) {
/* Superblock and root node already read.
* Nothing else can go wrong. Perform the mount. */
new_vmp->m_root_node = root_node;
/* If error, return the super block and both inodes; release the vmnt. */
if (r != OK) {
unlock_vnode(vp);
- unlock_vmnt(parent_vmp);
unlock_vnode(root_node);
unlock_vmnt(new_vmp);
put_vnode(vp);
update_bspec(dev, fs_e, 0 /* Don't send new driver endpoint */);
unlock_vnode(vp);
- unlock_vmnt(parent_vmp);
unlock_vnode(root_node);
unlock_vmnt(new_vmp);
unlock_bsf();
lock_bsf();
- assert(lock_vmnt(vmp, VMNT_EXCL) == OK);
+ if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK) {
+ unlock_bsf();
+ return(r);
+ }
/* See if the mounted device is busy. Only 1 vnode using it should be
* open -- the root vnode -- and that inode only 1 time. */
/*===========================================================================*
* is_nonedev *
*===========================================================================*/
-PRIVATE int is_nonedev(dev_t dev)
+PUBLIC int is_nonedev(dev_t dev)
{
/* Return whether the given device is a "none" pseudo device.
*/
* we default to ROOT_FS. */
vp->v_bfs_e = ROOT_FS_E; /* By default */
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
- if (vmp->m_dev == vp->v_sdev)
+ if (vmp->m_dev == vp->v_sdev &&
+ !is_nonedev(vmp->m_dev))
vp->v_bfs_e = vmp->m_fs_e;
/* Get the driver endpoint of the block spec device */
char *cp;
char dir_entry[PATH_MAX+1];
struct vnode *start_dir, *res;
+ int r;
+
+ *resolve->l_vnode = NULL;
+ *resolve->l_vmp = NULL;
/* Is the path absolute or relative? Initialize 'start_dir' accordingly. */
start_dir = (resolve->l_path[0] == '/' ? rfp->fp_rd : rfp->fp_wd);
struct vmnt *vmp;
vmp = find_vmnt(start_dir->v_fs_e);
- if (lock_vmnt(vmp, resolve->l_vmnt_lock) != EBUSY)
+ r = lock_vmnt(vmp, resolve->l_vmnt_lock);
+ if (r == EDEADLK)
+ return(NULL);
+ else if (r == OK)
*resolve->l_vmp = vmp;
+
lock_vnode(start_dir, resolve->l_vnode_lock);
*resolve->l_vnode = start_dir;
dup_vnode(start_dir);
if ((r = lock_vmnt(vmpres, resolve->l_vmnt_lock)) != OK) {
if (r == EBUSY) /* vmnt already locked */
vmpres = NULL;
+ else
+ return(r);
}
*(resolve->l_vmp) = vmpres;
vmp = NULL;
} else if (r == EENTERMOUNT) {
/* Entering a new partition */
- dir_vp = 0;
+ dir_vp = NULL;
/* Start node is now the mounted partition's root node */
for (vmp = &vmnt[0]; vmp != &vmnt[NR_MNTS]; ++vmp) {
if (vmp->m_dev != NO_DEV && vmp->m_mounted_on) {
if ((r = lock_vmnt(vmpres, resolve->l_vmnt_lock)) != OK) {
if (r == EBUSY)
vmpres = NULL; /* Already locked */
+ else
+ return(r);
}
*(resolve->l_vmp) = vmpres;
struct vmnt *vmp;
struct node_details res;
+ /* Get a lock on PFS */
+ if ((vmp = find_vmnt(PFS_PROC_NR)) == NULL) panic("PFS gone");
+ if ((r = lock_vmnt(vmp, VMNT_WRITE)) != OK) return(r);
+
/* See if a free vnode is available */
if ((vp = get_free_vnode()) == NULL) return(err_code);
lock_vnode(vp, VNODE_OPCL);
- /* Get a lock on PFS */
- if ((vmp = find_vmnt(PFS_PROC_NR)) == NULL) panic("PFS gone");
- lock_vmnt(vmp, VMNT_WRITE);
-
/* Acquire two file descriptors. */
rfp = fp;
if ((r = get_fd(0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) {
if ((vmp = find_vmnt(map_to_fs_e)) == NULL)
panic("Can't map to unknown endpoint");
- if (lock_vmnt(vmp, VMNT_WRITE) == EBUSY)
- vmp = NULL; /* Already locked, do not unlock */
+ if ((r = lock_vmnt(vmp, VMNT_WRITE)) != OK) {
+ if (r == EBUSY)
+ vmp = NULL; /* Already locked, do not unlock */
+ else
+ return(r);
+
+ }
/* Create a temporary mapping of this inode to another FS. Read and write
* operations on data will be handled by that FS. The rest by the 'original'
_PROTOTYPE( int do_fsready, (void) );
_PROTOTYPE( int do_mount, (void) );
_PROTOTYPE( int do_umount, (void) );
+_PROTOTYPE( int is_nonedev, (dev_t dev) );
_PROTOTYPE( void mount_pfs, (void) );
_PROTOTYPE( int mount_fs, (dev_t dev, char fullpath[PATH_MAX+1],
endpoint_t fs_e, int rdonly,
} else if (block_spec) { /* Block special files. */
lock_bsf();
+ printf("Doing block read_write(%d) from dev %d/ep=%d\n",
+ rw_flag == READING,
+ vp->v_sdev, vp->v_bfs_e);
r = req_breadwrite(vp->v_bfs_e, who_e, vp->v_sdev, position,
m_in.nbytes, m_in.buffer, rw_flag, &res_pos, &res_cum_io);
if (r == OK) {
+ printf("OK res_cum_io = %d\n", res_cum_io);
position = res_pos;
cum_io += res_cum_io;
- }
+ } else
+ printf("Failed with %d\n", r);
unlock_bsf();
} else { /* Regular files */
initial_locktype = (locktype == VMNT_EXCL) ? VMNT_WRITE : locktype;
+ if (vmp->m_fs_e == who_e) return(EDEADLK);
+
r = tll_lock(&vmp->m_lock, initial_locktype);
if (r == EBUSY) return(r);