kernel/fs/mount.c
/*
 * Mount()
 *
 * TODO: Add a struct statfs parameter to control cacheability/maximum size etc of a mount
 */
Mount()
TODO: Add a struct statfs parameter to control cacheability/maximum size etc of a mount
Mount () TODO : Add a struct statfs parameter to control cacheability / maximum size etc of a mount
int Mount(char *_path, uint32_t flags, struct stat *_stat) {
  struct Lookup lookup;
  struct stat stat;
  struct Process *current;
  int fd = -1;
  int error = -ENOTSUP;
  struct VNode *vnode_covered = NULL;
  struct VNode *server_vnode = NULL;
  struct VNode *client_vnode = NULL;
  struct Filp *filp = NULL;
  struct SuperBlock *sb = NULL;
  current = GetCurrentProcess();
  if (CopyIn(&stat, _stat, sizeof stat) != 0) {
    return -EFAULT;
  }
  if (root_vnode == NULL) {
    return MountRoot(flags, &stat);
  }
  if ((error = Lookup(_path, 0, &lookup)) != 0) {
    return error;
  }
  vnode_covered = lookup.vnode;
  if (vnode_covered == NULL) {
    error = -ENOENT;
    goto exit;
  }
  sb = AllocSuperBlock();
  if (sb == NULL) {
    error = -ENOMEM;
    goto exit;
  }
  DNamePurgeVNode(vnode_covered);
  if (vnode_covered->vnode_covered != NULL) {
    error = -EEXIST;
    goto exit;
  }
  server_vnode = VNodeNew(sb, -1);
  if (server_vnode == NULL) {
    error = -ENOMEM;
    goto exit;
  }
  client_vnode = VNodeNew(sb, 0);
  if (client_vnode == NULL) {
    error = -ENOMEM;
    goto exit;
  }
  InitRendez(&sb->rendez);
  InitMsgPort(&sb->msgport, server_vnode);
  sb->server_vnode = server_vnode; 
  sb->root = client_vnode;         
  sb->flags = flags;
  sb->reference_cnt = 2;
  sb->busy = FALSE;
  client_vnode->flags = V_VALID | V_ROOT;
  client_vnode->reference_cnt = 1;
  client_vnode->uid = stat.st_uid;
  client_vnode->gid = stat.st_gid;
  client_vnode->mode = stat.st_mode;
  client_vnode->size = stat.st_size;
  server_vnode->flags = V_VALID;
  server_vnode->reference_cnt = 1;
  server_vnode->uid = current->uid;
  server_vnode->gid = current->gid;
  server_vnode->mode = 0777 | _IFPORT;
  server_vnode->size = 0;
  fd = AllocHandle();
  if (fd < 0) {
    error = -ENOMEM;
    goto exit;
  }
  if (vnode_covered == root_vnode) {
    client_vnode->vnode_covered = NULL;
    root_vnode = client_vnode;
  } else {
    client_vnode->vnode_covered = vnode_covered;
    vnode_covered->vnode_mounted_here = client_vnode;
  }
  WakeupPolls(vnode_covered, POLLPRI, POLLPRI);
  WakeupPolls(client_vnode, POLLPRI, POLLPRI);
  filp = GetFilp(fd);
  filp->vnode = server_vnode;
  filp->offset = 0;
  VNodeIncRef(vnode_covered);
  VNodeIncRef(client_vnode);
  VNodeIncRef(server_vnode);
  VNodeUnlock(vnode_covered);
  VNodeUnlock(server_vnode);
  VNodeUnlock(client_vnode);
  return fd;
exit:
  VNodePut(server_vnode); 
  FreeHandle(fd);
  VNodePut(lookup.vnode);
  VNodeFree(client_vnode);
  VNodeFree(server_vnode);
  FreeSuperBlock(sb);
  VNodePut(vnode_covered);
  return error;
}
int Mount ( char * _path , uint32_t flags , struct stat * _stat ) { struct Lookup lookup ; struct stat stat ; struct Process * current ; int fd = -1 ; int error = - ENOTSUP ; struct VNode * vnode_covered = NULL ; struct VNode * server_vnode = NULL ; struct VNode * client_vnode = NULL ; struct Filp * filp = NULL ; struct SuperBlock * sb = NULL ; current = GetCurrentProcess ( ) ; if ( CopyIn ( & stat , _stat , sizeof stat ) != 0 ) { return - EFAULT ; } if ( root_vnode == NULL ) { return MountRoot ( flags , & stat ) ; } if ( ( error = Lookup ( _path , 0 , & lookup ) ) != 0 ) { return error ; } vnode_covered = lookup . vnode ; if ( vnode_covered == NULL ) { error = - ENOENT ; goto exit ; } sb = AllocSuperBlock ( ) ; if ( sb == NULL ) { error = - ENOMEM ; goto exit ; } DNamePurgeVNode ( vnode_covered ) ; if ( vnode_covered -> vnode_covered != NULL ) { error = - EEXIST ; goto exit ; } server_vnode = VNodeNew ( sb , -1 ) ; if ( server_vnode == NULL ) { error = - ENOMEM ; goto exit ; } client_vnode = VNodeNew ( sb , 0 ) ; if ( client_vnode == NULL ) { error = - ENOMEM ; goto exit ; } InitRendez ( & sb -> rendez ) ; InitMsgPort ( & sb -> msgport , server_vnode ) ; sb -> server_vnode = server_vnode ; sb -> root = client_vnode ; sb -> flags = flags ; sb -> reference_cnt = 2 ; sb -> busy = FALSE ; client_vnode -> flags = V_VALID | V_ROOT ; client_vnode -> reference_cnt = 1 ; client_vnode -> uid = stat . st_uid ; client_vnode -> gid = stat . st_gid ; client_vnode -> mode = stat . st_mode ; client_vnode -> size = stat . st_size ; server_vnode -> flags = V_VALID ; server_vnode -> reference_cnt = 1 ; server_vnode -> uid = current -> uid ; server_vnode -> gid = current -> gid ; server_vnode -> mode = 0777 | _IFPORT ; server_vnode -> size = 0 ; fd = AllocHandle ( ) ; if ( fd < 0 ) { error = - ENOMEM ; goto exit ; } if ( vnode_covered == root_vnode ) { client_vnode -> vnode_covered = NULL ; root_vnode = client_vnode ; } else { client_vnode -> vnode_covered = vnode_covered ; vnode_covered -> vnode_mounted_here = client_vnode ; } WakeupPolls ( vnode_covered , POLLPRI , POLLPRI ) ; WakeupPolls ( client_vnode , POLLPRI , POLLPRI ) ; filp = GetFilp ( fd ) ; filp -> vnode = server_vnode ; filp -> offset = 0 ; VNodeIncRef ( vnode_covered ) ; VNodeIncRef ( client_vnode ) ; VNodeIncRef ( server_vnode ) ; VNodeUnlock ( vnode_covered ) ; VNodeUnlock ( server_vnode ) ; VNodeUnlock ( client_vnode ) ; return fd ; exit : VNodePut ( server_vnode ) ; FreeHandle ( fd ) ; VNodePut ( lookup . vnode ) ; VNodeFree ( client_vnode ) ; VNodeFree ( server_vnode ) ; FreeSuperBlock ( sb ) ; VNodePut ( vnode_covered ) ; return error ; }
Mount()
 TODO: Add a struct statfs parameter to control cacheability/maximum size etc of a mount
Mount () TODO : Add a struct statfs parameter to control cacheability / maximum size etc of a mount
// TODO: Check if root == NULL and this is first Mount("/") // TODO: Check stat.st_mode against vnode.mode  TYPE. // What about permissions, keep covered permissions ?   // TODO: Set Client VNODE to some parameter of stat // FIXME: Needed? // FIXME: Needed? // TODO: initialize rest of fields // TODO:  Check for root earlier, don't allow remount? // FIXME: Not a PUT?  Removed below?