Esempio n. 1
0
/*
 * Find the vnode associated with the path, and call the stat() vnode operation.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        A component of path does not exist.
 *      o ENOTDIR
 *        A component of the path prefix of path is not a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_stat(const char *path, struct stat *buf)
{
	vnode_t *tmp= NULL;
	int ret;
	if(buf == NULL || path==NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return -EINVAL;
    }
	if(strlen(path)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        return -ENAMETOOLONG;
    }
	if ((ret = open_namev(path, NULL, &tmp, NULL)) < 0)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        return ret;
    }
	ret = tmp->vn_ops->stat(tmp, buf);
    KASSERT(tmp->vn_ops->stat);
    dbg(DBG_PRINT, "(GRADING2A 3.f)\n");
	vput(tmp);
	return ret;
}
Esempio n. 2
0
/*
 * Find the vnode associated with the path, and call the stat() vnode operation.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        A component of path does not exist.
 *      o ENOTDIR
 *        A component of the path prefix of path is not a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_stat(const char *path, struct stat *buf)
{
    /* NOT_YET_IMPLEMENTED("VFS: do_stat"); */
    
    if (path == NULL) {
        return -EINVAL;
    }
    
    vnode_t *result;
    int ret;
    ret = open_namev(path, 0, &result, NULL);
    if (ret){
        return ret;
    }
    
    /* Corrected for kernel 3 */
    /* vput(result); */
    
    /* grading guideline required */
    KASSERT(result->vn_ops->stat);
    dbg(DBG_PRINT,"(GRADING2A 3.f) The corresponding vnode has stat function. \n");
    
    /* Corrected for kernel 3 */
    int retVal = result->vn_ops->stat(result, buf);
    vput(result);
    return retVal;
}
Esempio n. 3
0
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int
do_chdir(const char *path)
{
	int ret;
	vnode_t *tmp;
	if(path == NULL || strlen(path)<1)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return -EINVAL;
    }
	if(strlen(path)>MAXPATHLEN) return -ENAMETOOLONG;
	if ((ret=open_namev(path, 0, &tmp, NULL))<0)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        return ret;
    }
	if (!S_ISDIR(tmp->vn_mode))
	{
        dbg(DBG_PRINT,"(GRADING2B)\n");

		vput(tmp);
		return -ENOTDIR;
	}
	vput(curproc->p_cwd);
	curproc->p_cwd = tmp;
	return 0;
}
Esempio n. 4
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 *      o EISDIR
 *        from is a directory.
 */
int
do_link(const char *from, const char *to)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_link");
        return 0;*/
        if ((strlen(from) > MAXPATHLEN) || (strlen(to) > MAXPATHLEN)){
            return -ENAMETOOLONG;
        }
    
        vnode_t *from_vnode,*to_vnode,*to_vnodeFile;
        int from_retVal,to_retVal;
        size_t namelen;
        const char *name;
    
        from_retVal = open_namev(from,0,&from_vnode,NULL);
        if (from_retVal){
            return from_retVal;
        }
    
    
        if (S_ISDIR(from_vnode->vn_mode)){
            vput(from_vnode);
            return -EISDIR;
        }
    
        to_retVal = dir_namev(to,&namelen,&name,NULL,&to_vnode);
        if (to_retVal){
            vput(from_vnode);
            return to_retVal;
        }
    
    
        if (!S_ISDIR(to_vnode->vn_mode)){
            vput(from_vnode);
            vput(to_vnode);
            return -ENOTDIR;
        }
    
        to_retVal = lookup(to_vnode,name,namelen,&to_vnodeFile);
        if (!to_retVal){
            vput(from_vnode);
            vput(to_vnode);
            vput(to_vnodeFile);
            return -EEXIST;
        }
        else {
            if (to_retVal == -ENOENT){
                vput(from_vnode);
                vput(to_vnode);
                return from_vnode->vn_ops->link(from_vnode,to_vnode,name,namelen);
            }
        }
    
        vput(from_vnode);
        vput(to_vnode);
        return to_retVal;
}
Esempio n. 5
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 */
int
do_link(const char *from, const char *to)
{
  int err,err2,err3,ent;
  vnode_t *res_vnode,base,*res_vnode2,base2,*result;
  size_t len;
  const char *name;
  if(strlen(from)>NAME_LEN || strlen(to)>NAME_LEN)
    {
        dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_link) Path greater than MAXPATHLEN, return -ENAMETOOLONG\n");
        return -ENAMETOOLONG;
	}
  err=open_namev(from,0,&res_vnode,NULL);
  if(err<0)
    {
      /*vput(res_vnode);*/
        dbg(DBG_PRINT,"(GRADING2C 1.j) (vfs_syscall.c) (do_link) error returned from open_namev so cannot open to link, return error \n");
      return err;
    }
if(S_ISDIR(res_vnode->vn_mode))
    {
      vput(res_vnode);
      dbg(DBG_PRINT,"(GRADING2C 1.h) (vfs_syscall.c) (do_link) Link already exists, return -EEXIST \n");
      return -EISDIR;
      }

  
  err2=dir_namev(to,&len,&name,NULL,&res_vnode2);
  if(err2<0)
    {
       vput(res_vnode);
        dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_link) error returned from dir_namev so cannot open to link, return error \n");
        return err2;
	}
  
   ent=lookup(res_vnode2,name,len,&result);
  
  if(ent==0)
    {

      vput(res_vnode);
       dbg(DBG_PRINT,"(GRADING2C 1.i) (vfs_syscall.c) (do_link) file of new Link already exists, return -EEXIST and dec ref count \n");
        vput(res_vnode2);
	  vput(res_vnode);
	  
      return -EEXIST;
      }
  /*vput(res_vnode2);*/
  err3=res_vnode2->vn_ops->link(res_vnode,res_vnode2,name,len);
  dbg(DBG_PRINT,"(GRADING2C 1.h) (vfs_syscall.c) (do_link) Link created\n");
  vput(res_vnode2);
  vput(res_vnode);
  return err3;
  /*        NOT_YET_IMPLEMENTED("VFS: do_link");
	    return -1;*/
}
Esempio n. 6
0
int
do_chdir(const char *path)
{
	/* NOT_YET_IMPLEMENTED("VFS: do_chdir"); */

	/*GS: path should point to something */
	KASSERT(path);
    dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_chdir)\n");
	
    /*GS: Check if a path too long. */
	if(strlen(path) > MAXPATHLEN)
	{
		dbg(DBG_PRINT, "(GRADING2C 1.n) (vfs_syscall.c) (do_chdir) path too long, return -ENAMETOOLONG\n");
		return -ENAMETOOLONG;
	}

	/*GS: This returns in newcwd the vnode requested by the other parameters.
	 *    and ups the refcount to the new cwd*/
	vnode_t *newcwd = NULL;
	int retVal = open_namev(path, O_RDONLY, &newcwd, curproc->p_cwd);
	/* GS: NOTE! - need to confirm open_namev error values after implemented */
	if( retVal < 0 )
	{

		dbg(DBG_PRINT, "(GRADING2B) (vfs_syscall.c) (do_chdir) error open_namev, cannot open, return error\n");
		return retVal;
	}

	/*GS: check if the path does not exist.*/
	/*if( newcwd == NULL )
	{
		dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_chdir) path does not exist, return -ENOENT\n");
		return -ENOENT;
	}*/

	/*GS: Check if a component of path is not a directory.*/
	if (!S_ISDIR(newcwd->vn_mode))
	{
		/*GS: need to down the count back*/
		vput(newcwd);
		dbg(DBG_PRINT, "(GRADING2B) component of path is not a directory, return -ENOTDIR\n");
		return -ENOTDIR;
    }

	/*GS: Down the refcount to the old cwd - vput() */
	vput(curproc->p_cwd);
	/*GS: Make the named directory the current process's cwd */
	curproc->p_cwd = newcwd;
	vref(curproc->p_cwd);
	vput(newcwd);
	return 0;

}
Esempio n. 7
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 *      o EISDIR
 *        from is a directory.
 */
int do_link(const char *from, const char *to) {
	/*NOT_YET_IMPLEMENTED("VFS: do_link");*/
	vnode_t *from_vn, *to_result;
	size_t to_namelen;
	const char *to_name;
	vnode_t *to_vn;

	int to_retdir_namev, to_retlookup;

	open_namev(from, O_RDONLY, &from_vn, NULL);

	dbg(DBG_PRINT, "(GRADING3D 2)\n");
	/*if (ret_namev < 0) {
		dbg(DBG_ERROR, "2\n");
		return ret_namev;
	}*/

	if (S_ISDIR((from_vn)->vn_mode)) {
		dbg(DBG_PRINT, "(GRADING3D 2)\n");
		vput(from_vn);
		return -EISDIR;
	}

	to_retdir_namev = dir_namev(to, &to_namelen, &to_name, NULL, &to_vn);

	if (to_retdir_namev < 0) {
		dbg(DBG_PRINT, "(GRADING3D 2)\n");
		vput(from_vn);
		return to_retdir_namev;
	}

	/*if (to_vn->vn_ops->link == NULL) {
		dbg(DBG_ERROR, "5\n");
		return -ENOTDIR;
	}*/
	to_retlookup = lookup(to_vn, to_name, to_namelen, &to_result);
	if (to_retlookup == 0) {
		dbg(DBG_PRINT, "(GRADING3D 2)\n");
		vput(to_result);
		return -EEXIST;
	} else {
		dbg(DBG_PRINT, "(GRADING3D 2)\n");
		int to_retlink = to_vn->vn_ops->link(from_vn, to_vn, to_name, to_namelen);
		vput(to_vn);
		vput(from_vn);
		return to_retlink;
	}
	return -1;
}
Esempio n. 8
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 *      o EISDIR
 *        from is a directory.
 */
int
do_link(const char *from, const char *to)
{
/*NOT_YET_IMPLEMENTED("VFS: do_link");
     return -1;*/
	const char *name;
	size_t name_len;
	int ret;
	vnode_t *from_vnode,*to_p_vnode,*to_vnode;
	if(from == NULL || to == NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return -EINVAL;
    }
	if(strlen(from)>MAXPATHLEN || strlen(to)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return -ENAMETOOLONG;
    }
	if ((ret = open_namev(from,NULL,&from_vnode,NULL))<0)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        return ret;
    }
	vput(from_vnode);
	if ((ret = dir_namev(to,&name_len,&name,NULL,&to_p_vnode))<0)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return ret;
    }
	vput(to_p_vnode);
	if (S_ISDIR(from_vnode->vn_mode))
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

       return -EISDIR;
    }
	if ((ret = lookup(to_p_vnode,name,name_len,&to_vnode) )== 0)
	{
        dbg(DBG_PRINT,"(GRADING2D)\n");
		vput(to_vnode);
		return -EEXIST;
	}
	return to_p_vnode->vn_ops->link(from_vnode,to_p_vnode,name,name_len);
}
Esempio n. 9
0
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int do_chdir(const char *path) {
	/* NOT_YET_IMPLEMENTED("VFS: do_chdir"); */
	int retopen_namev=0;
	vnode_t *result;

	dbg(DBG_PRINT, "(GRADING2B)\n");
	/*int retdir_namev;*/
	/*if (strlen(path) > MAXPATHLEN){
	 dbg(DBG_ERROR, "1\n");
	 return -ENAMETOOLONG;
	 }*/

	/*retdir_namev =*/

	/*if (strlen(name) > NAME_LEN) {
	 dbg(DBG_ERROR, "2\n");
	 if (retdir_namev == 0) {
	 dbg(DBG_ERROR, "3\n");
	 vput(res_vnode);
	 }
	 return -ENAMETOOLONG;

	 }
	 if (retdir_namev != 0) {
	 dbg(DBG_ERROR, "4\n");
	 dbg(DBG_PRINT, "1chdir returns %d\n", retdir_namev);
	 return retdir_namev;
	 }*/
	retopen_namev = open_namev(path, O_RDONLY, &result, NULL);

	if (retopen_namev < 0) {
		return retopen_namev;
	}

	if (!S_ISDIR(result->vn_mode)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		vput(result);
		return -ENOTDIR;
	}

	vput(curproc->p_cwd);
	curproc->p_cwd = result;
	dbg(DBG_PRINT, "(GRADING2B)\n");
	return 0;

}
Esempio n. 10
0
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int
do_chdir(const char *path)
{

        if(strlen(path) > MAXPATHLEN)
        {
          dbg(DBG_PRINT,"(GRADING2B) one of the component in the path field is too long\n");
          dbg(DBG_PRINT,"do_chdir(): one of the component in the path field is too long\n");
          return -ENAMETOOLONG;
        } 
        if(strlen(path) <= 0)
        {
          dbg(DBG_PRINT,"(GRADING2B) Invalid path name\n");
          dbg(DBG_PRINT,"do_chdir(): Invalid path name\n");
          return -EINVAL;
        }

        size_t namelen;
        char *name;
        vnode_t *res_vnode;
        int ret_val =0;
        ret_val = open_namev(path,0,&res_vnode,NULL);

         if(ret_val<0)
         {
            dbg(DBG_PRINT,"(GRADING2B) Error while accessing open_namev\n");
            return ret_val;
         }

        if(!S_ISDIR(res_vnode->vn_mode))
        {
         vput(res_vnode);
         dbg(DBG_PRINT,"(GRADING2B) Given path is not a directory\n");
         return -ENOTDIR;
        }
       
        vput(curproc->p_cwd);
        curproc->p_cwd = res_vnode;
        
        return 0;

        /*NOT_YET_IMPLEMENTED("VFS: do_chdir");
        return -1;*/
}
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int
do_chdir(const char *path)
{
	size_t namelen=0;
	const char *name=NULL;
	vnode_t *base = NULL;
	vnode_t *res_vnode=NULL;

	KASSERT(path);

	int namev_ret = open_namev(path, 0, &res_vnode, NULL);

	if(namev_ret<0)
	{
		KASSERT(namev_ret<0);
		dbg(DBG_PRINT,"(GRADING2D 3.f): Path component has failed.\n");
		return namev_ret;
	}

	if(!S_ISDIR(res_vnode->vn_mode))
	{
		KASSERT(!S_ISDIR(res_vnode->vn_mode));
		dbg(DBG_PRINT, "(GRADING2D 3.b): The path is not to a directory.\n");
		vput(res_vnode);
		return -ENOTDIR;
	}

	KASSERT(res_vnode != NULL);

	/* Don't forget to down the refcount to the old cwd (vput()) and
	 * up the refcount to the new cwd (open_namev() or vget()).*/
	KASSERT(curproc != NULL);

	vput(curproc->p_cwd);
	curproc->p_cwd=res_vnode;

	/* Might need to increase the ref_count, but I think it should instead
	 * happen inside lookup which gets called by open_namev.*/ 
	/*vget(res_vnode->vn_fs,res_vnode->vn_vno);*/

	dbg(DBG_PRINT, "(GRADING2D 3.i): Successfully changed directory.\n");
	return 0;
}
Esempio n. 12
0
int
do_stat(const char *path, struct stat *buf)
{
    /* NOT_YET_IMPLEMENTED("VFS: do_stat");*/
	
	/*GS: path should point to something */
	KASSERT(path);
	
	/*GS: buf should point to something */
	KASSERT(buf);

	int retVal = 0;

	/*GS: check if strlen too long*/
    if( strlen(path) > MAXPATHLEN )
        {
    	dbg(DBG_PRINT, "(GRADING2C 1.l) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");
            return -ENAMETOOLONG;
	}

	vnode_t *vnode;

	/*GS: return the vnode of the associated path */
	retVal = open_namev(path, O_RDONLY, &vnode, NULL);
	if(retVal < 0)   /*GS: NOTE! need to check what the return values are once implemented*/
	{ 
	  /*GS: ENOTDIR and ENOENT should both get caught here*/
		dbg(DBG_PRINT, "(GRADING2B) (vfs_syscall.c) (do_stat) ENOTDIR or ENOENT\n");
		return retVal;
	}
	
    /*GS: stat() should point to something */
    KASSERT(NULL != vnode->vn_ops->stat);
    dbg(DBG_PRINT,"(GRADING2A 3.f) (middle) KASSERT(vnode->->vn_ops->stat)\n");

	/*GS: call the stat() vnode operation*/
	retVal = vnode->vn_ops->stat(vnode, buf);

	vput(vnode);

	return retVal;

}
Esempio n. 13
0
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int
do_chdir(const char *path)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_chdir");
        return -1;
        */
       /*dbg(DBG_PRINT,"Entering do_chdir ****************************************\n");
       */
       int retvar;
      /* size_t namelen;
      const char *name;
       vnode_t *res_vnode;
        retvar = dir_namev(path,&namelen,&name,NULL,&res_vnode);

       */
       /*dbg(DBG_PRINT,"(GRADING2C V41)\n");
       */
       vnode_t *res_vnode;
       retvar = open_namev(path,000,&res_vnode,NULL);
        if (retvar < 0)
        {
          /*vput(res_vnode);
          */
          dbg(DBG_PRINT,"(GRADING2C)\n");
          /*dbg(DBG_PRINT,"retvar %d Leaving do_chdir ****************************************\n",retvar);
          */
          return retvar;
        }
        if(!S_ISDIR(res_vnode->vn_mode))
        {
          vput(res_vnode);
          dbg(DBG_PRINT,"(GRADING2C)\n");
          return -ENOTDIR;
        }
        vput(curproc->p_cwd);
        curproc->p_cwd = res_vnode;
        dbg(DBG_PRINT,"(GRADING2C)\n");
        /*dbg(DBG_PRINT,"Leaving do_chdir ****************************************\n");
      */
        return 0;
}
Esempio n. 14
0
/*
 * Find the vnode associated with the path, and call the stat() vnode operation.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        A component of path does not exist.
 *      o ENOTDIR
 *        A component of the path prefix of path is not a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int do_stat(const char *path, struct stat *buf) {
	/* NOT_YET_IMPLEMENTED("VFS: do_stat"); */
	vnode_t *result;
	int retopen_namev=0;
	/*size_t *namelen = (size_t) kalloc(sizeof(size_t));
	 const char **name = (char) kalloc(sizeof(char));
	 vnode_t **res_vnode = (vnode_t) kalloc(sizeof(vnode_t)); */
	/*if (strlen(path) > MAXPATHLEN) {
	 dbg(DBG_ERROR, "2\n");
	 return ENAMETOOLONG;
	 }*/
	/* Base passed NULL since dir_nameve can handle acccordingly */

	/*if (retdir_namev != 0) {
	 dbg(DBG_ERROR, "3\n");
	 return retdir_namev;
	 }
	 if (strlen(name) > NAME_LEN) {
	 dbg(DBG_ERROR, "4\n");
	 vput(res_vnode);
	 return -ENAMETOOLONG;
	 }*/

	if (path == NULL || buf == NULL || strlen(path) == 0) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return -EINVAL;
	}

	retopen_namev = open_namev(path, O_RDONLY, &result, NULL);

	if (retopen_namev < 0) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return retopen_namev;
	}

	retopen_namev = result->vn_ops->stat(result, buf);
	vput(result);
	return retopen_namev;

}
Esempio n. 15
0
/* Make the named directory the current process's cwd (current working
 * directory).  Don't forget to down the refcount to the old cwd (vput()) and
 * up the refcount to the new cwd (open_namev() or vget()). Return 0 on
 * success.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o ENOENT
 *        path does not exist.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 *      o ENOTDIR
 *        A component of path is not a directory.
 */
int
do_chdir(const char *path)
{
    /* NOT_YET_IMPLEMENTED("VFS: do_chdir"); */
    
    int ret = 0;
    int flag = 0; /* Should this be 0 */
    vnode_t *dir;
    
    vnode_t *temp = curproc->p_cwd;
    ret = open_namev(path, flag, &dir, NULL);
    if (ret == -ENOENT){
        return -ENOENT;
    }
    if (ret == -ENOTDIR){
        return -ENOTDIR;
    }
    /* ERROR!!! A component of filename was too long.*/
    if (ret == -ENAMETOOLONG){
        return -ENAMETOOLONG;
    }
    if (ret) {
        return ret;
    }
    
    if (dir->vn_mode != S_IFDIR) {
        vput(dir);
        return -ENOTDIR;
    }
    
    /*Since the change_dir has been successful, vput the old cwd.*/
    vput(temp);
    
    curproc->p_cwd = dir;
    
    return 0;
}
Esempio n. 16
0
int
do_open(const char *filename, int oflags)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_open");*/
	if (oflags!=O_RDONLY && oflags!=O_WRONLY && oflags!=O_RDWR && oflags!=O_APPEND && oflags!= (O_RDONLY | O_CREAT) 
		&& oflags != (O_RDWR | O_CREAT) && oflags != (O_RDWR | O_APPEND))
	{
		return -EINVAL;
	}
	int fd = get_empty_fd(curproc);
	if( fd == -EMFILE){
		return -EMFILE;
	}
	file_t *f = fget(-1);
	if( f == NULL){
		return -ENOMEM;
	}
	curproc->p_files[fd] = f;
	/*Set file_t->f_mode to OR of FMODE_(READ|WRITE|APPEND) based on
         * oflags, which can be O_RDONLY, O_WRONLY or O_RDWR, possibly OR'd with
         * O_APPEND.
	*/
	/*FIXME check the logic below*/	
	if(oflags == O_RDONLY){
		f->f_mode = FMODE_READ;
	}else if(oflags == O_WRONLY){
		f->f_mode =  FMODE_WRITE;
	}else if(oflags == O_RDWR){
		f->f_mode = FMODE_READ | FMODE_WRITE;
	}else if(oflags == O_APPEND){
		f->f_mode = FMODE_WRITE | FMODE_APPEND;
	}else if(oflags == (O_RDONLY | O_CREAT)){
		f->f_mode = FMODE_READ;
	}else if(oflags == (O_RDWR | O_CREAT) ){
		f->f_mode = FMODE_READ | FMODE_WRITE;
	}else if(oflags == (O_RDWR | O_APPEND) ){
		f->f_mode = FMODE_READ | FMODE_WRITE | FMODE_APPEND;
	}

	vnode_t *pVnode;
	int s = open_namev(filename, oflags, &pVnode, NULL);
	if(s != 0){
		curproc->p_files[fd] = NULL;	
                fput(f);
		return s;
	}
        if(S_ISDIR(pVnode->vn_mode) && ((oflags & O_WRONLY) || (oflags & O_RDWR)) ){
		curproc->p_files[fd] = NULL;
		vput(pVnode);
                fput(f);
		return -EISDIR;
        }
	if(S_ISBLK(pVnode->vn_mode)){
	        if(!(pVnode->vn_bdev = blockdev_lookup(pVnode->vn_devid))){
			curproc->p_files[fd] = NULL;
			fput(f);
			vput(pVnode);
			return -ENXIO;
		}
	}
	if(S_ISCHR(pVnode->vn_mode)){
	        if(!(pVnode->vn_cdev = bytedev_lookup(pVnode->vn_devid))){
			curproc->p_files[fd] = NULL;
			fput(f);
			vput(pVnode);
			return -ENXIO;
		}
	}
	f->f_pos=0;
	f->f_vnode = pVnode;
        return fd;
}
Esempio n. 17
0
int
do_open(const char *filename, int oflags)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_open");*/
        
        /* Check validity of oflags */
        int flag_write_only = oflags & O_WRONLY;
        int flag_readwrite = oflags & O_RDWR;
        int flag_append = oflags & O_APPEND;
        int flag_create = oflags & O_CREAT;
        
        /* oflags is Read_Only and also trying to write/append/create 
        if( !oflags && ( flag_write_only || flag_readwrite || flag_append || flag_create) ) {
			
			dbg(DBG_PRINT, "Add self test dbg here (GRADING1C 7)\n");
            
			return(-EINVAL);
		}*/
        
        /* Trying to read from write_only */
        if( flag_write_only && flag_readwrite ) {
			
			dbg(DBG_PRINT, "(GRADING2B)\n");
			
			return(-EINVAL);
		}
        
        int file_mode = 0;
        
        if( oflags == 0 ) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			file_mode = file_mode | FMODE_READ;
		}
		
		if( flag_write_only ) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			file_mode = file_mode | FMODE_WRITE;
		}
		
		if( flag_readwrite ) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			file_mode = file_mode | FMODE_READ | FMODE_WRITE;
		}
		
		if( flag_append ) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			file_mode = file_mode | FMODE_APPEND;
		}
		
		vnode_t *new_vnode;
		
		int namev_ret = open_namev(filename, oflags, &new_vnode , NULL);
        
        if( namev_ret ) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			return namev_ret;
		}
        
        int next_fd;
        
        next_fd = get_empty_fd(curproc);
        
        /*if ( next_fd == -EMFILE ) {
            vput(new_vnode);
			return -EMFILE;
		}*/
        
        curproc->p_files[next_fd] = fget(-1);
        curproc->p_files[next_fd]->f_mode = file_mode;
		
		if( S_ISDIR(new_vnode->vn_mode) && (flag_write_only || flag_readwrite) ) {
			
			dbg(DBG_PRINT, "(GRADING2B)\n");
			
			fput(curproc->p_files[next_fd]);
			
			curproc->p_files[next_fd] = NULL;
            
            vput(new_vnode);
			
			return(-EISDIR);
			
		}
		
		if( S_ISCHR(new_vnode->vn_mode) && !(new_vnode->vn_cdev) ) {
			
			dbg(DBG_PRINT, "(GRADING2B)\n");
			
			fput( curproc->p_files[next_fd] );
			
			curproc->p_files[next_fd] = NULL;
			
			vput(new_vnode);
			
			return(-ENXIO);
		}
			
		if( S_ISBLK(new_vnode->vn_mode) && !(new_vnode->vn_bdev) ) {
			
			dbg(DBG_PRINT, "(GRADING2B)\n");
			
			fput( curproc->p_files[next_fd] );
			
			curproc->p_files[next_fd] = NULL;
			
			vput(new_vnode);
			
			return(-ENXIO);
		}
        
        curproc->p_files[next_fd]->f_vnode = new_vnode;
        curproc->p_files[next_fd]->f_pos = 0;
        
        return next_fd;
}
Esempio n. 18
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 */
int
do_link(const char *from, const char *to)
{
    /* NOT_YET_IMPLEMENTED("VFS: do_link"); */
    
    /*      o open_namev(from)*/
    int ret = 0;
    vnode_t *from_vnode = NULL;
    vnode_t *to_vnode = NULL;
    size_t namelen;
    const char *name;
    
    int flag = 0; /* Not modifying the file, so flag should be 0? */
    ret = open_namev(from, flag, &from_vnode, NULL);
    if (ret == -ENOENT){
        return -ENOENT;
    }
    if (ret == -ENOTDIR){
        return -ENOTDIR;
    }
    /* ERROR!!! A component of filename was too long.*/
    if (ret == -ENAMETOOLONG){
        return -ENAMETOOLONG;
    }
    
    /* In case there are other errors */
    if (ret) {
        return ret;
    }
    /* Remember to vput the vnodes returned from open_namev and dir_namev.*/
    /* Corrected for kernel 3 */
    /* vput(from_vnode); */
    
    /* The textbook page 30 says hard link can not be made to directory */
    if (from_vnode->vn_mode == S_IFDIR) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        
        return -EISDIR;
    }
    
    /*      o dir_namev(to)*/
    ret = dir_namev(to, &namelen, &name, NULL, &to_vnode);
    if (ret == -ENOENT) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        
        return -ENOENT;
    }
    if (ret == -ENOTDIR) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        
        return -ENOTDIR;
    }
    /* ERROR!!! A component of filename was too long.*/
    if (ret == -ENAMETOOLONG) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        
        return -ENAMETOOLONG;
    }
    /* In case there are other errors */
    if (ret) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        
        return ret;
    }
    
    /* Remember to vput the vnodes returned from open_namev and dir_namev.*/
    /* Corrected for kernel 3 */
    /* vput(to_vnode); */
    
    /*o EEXIST
    *     to already exists.
    * do lookup to check if to already exists */
    vnode_t *testNode;
    ret = lookup(to_vnode, name, namelen, &testNode);
    
    if (ret == 0) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        vput(to_vnode);
        
        vput(testNode);
        return -EEXIST;
    } else if (ret == -ENOTDIR) {
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        vput(to_vnode);
        
        return -ENOTDIR;
    } else {
        /*      o call the destination dir's (to) link vn_ops.*/
        ret = to_vnode->vn_ops->link(from_vnode, to_vnode, name, namelen);
        
        /* Corrected for kernel 3 */
        vput(from_vnode);
        vput(to_vnode);
        
        /*      o return the result of link, or an error*/
        return ret;
    }
}
Esempio n. 19
0
int
do_open(const char *filename, int oflags)
{
	vnode_t *res_vnode;
	int status_flag = 0, access_flag = 0, fd = 0, errno = 0;

	dbg(DBG_PRINT | DBG_VFS,"Kernel2:SysMsg:  begin do_open(), filename =%s\n",filename);

	/*Error cases*/
	if ( strlen(filename) > MAXPATHLEN )
	{
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - The component of the Filename too long\n",filename);
		return -ENAMETOOLONG;
	}
	
	if ( strlen(filename) < 1 )
	{
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - Invalid file as length is less than 1 \n",filename);
		return -EINVAL;
	}

	/*set up the access and status flags*/
	status_flag = oflags & 0x700;	/*O_CREAT,O_TRUNC,O_APPEND*/
	access_flag = oflags & 0x003;	/*O_RDONLY,O_WRONLY,O_RDWR*/	

	if ( access_flag != O_RDONLY && access_flag != O_WRONLY && access_flag != O_RDWR )
	{
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - Invalid file\n",filename);
		return -EINVAL;
	}
	
	/* get empty file descriptor, open file,O_CREAT handled in open_namev */
	fd = get_empty_fd(curproc);
	
	if ( fd < 0 )
	{
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - Maximum number of files open\n",filename);
		return -EMFILE;
	}

	curproc->p_files[fd] = fget(-1);
	
	if ( curproc->p_files[fd] == NULL )
	{
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - Insufficient Kernel memory\n",filename);
		return -ENOMEM;
	}

        errno = open_namev(filename,status_flag,&res_vnode,NULL);
	if ( errno < 0 )
	{
		fput(curproc->p_files[fd]);
		return errno;
	}

	/* Check error for opening a dir for write*/
	if ( S_ISDIR(res_vnode->vn_mode) && (access_flag == O_RDWR || access_flag == O_WRONLY))
	{
		fput(curproc->p_files[fd]);
		vput(res_vnode);
		
		dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg:  in  do_open(), filename =%s - The pathname is a directory or the access requested requires writing\n",filename);
		return -EISDIR;
	}

	/* Make O_TRUNC behavior default */
	if ( errno == 0 && (status_flag & O_APPEND) != O_APPEND && access_flag == O_WRONLY)
	{
		vput(res_vnode);
		errno = do_unlink(filename);
		if ( errno < 0 )
		{
			fput(curproc->p_files[fd]);
			return errno;
		}
        	errno = open_namev(filename,O_CREAT,&res_vnode,NULL);
		if ( errno < 0 )
		{
			fput(curproc->p_files[fd]);
			return errno;
		}
	}

	curproc->p_files[fd]->f_vnode = res_vnode;
	
	/*Handle file O_APPEND or O_TRUNC*/
	switch ( status_flag )
	{
		case O_APPEND : 
			curproc->p_files[fd]->f_mode = FMODE_APPEND;
			break;
		case O_APPEND | O_CREAT : 
			curproc->p_files[fd]->f_mode = FMODE_APPEND;
			break;
		default	      : 
			curproc->p_files[fd]->f_mode = 0;
			curproc->p_files[fd]->f_pos = 0;
			break;
	}

	/*Handle file access*/
	switch ( access_flag )
	{
		case O_RDONLY : 
			curproc->p_files[fd]->f_mode |= FMODE_READ;
			break;
		case O_WRONLY : 
			curproc->p_files[fd]->f_mode |= FMODE_WRITE;
			break;
		case O_RDWR   : 
			curproc->p_files[fd]->f_mode |= FMODE_WRITE | FMODE_READ;
			break;
	}

	dbg(DBG_PRINT | DBG_VFS,"Kernel2:SysMsg:  begin do_open(), return fd \n");
        return fd;
}
Esempio n. 20
0
File: open.c Progetto: Aliced3645/os
int
do_open(const char *filename, int oflags)
{
        /* check invalid combinations */
        int wr = oflags & O_WRONLY;
        int rdwr = oflags & O_RDWR;
        int rd = 0;
        if( (wr == 0) && (rdwr == 0)){
            rd = 1;
        }
        int append = oflags & O_APPEND;
        int trunc = oflags &O_TRUNC;
        int creat = oflags & O_CREAT;

        if( (wr != 0) && (rdwr != 0) ){
            return -EINVAL;
        }
        
        /* 1.  Get the next empty file descriptor */
        int fd = get_empty_fd(curproc);
        if(fd == -EMFILE){
            return -EMFILE;
        }

        /* 2. Call fget to get a fresh file_t */
        file_t* file = fget(-1);
        if(file == NULL){
            /* not sure for this error */
            return -ENOMEM;
        }
        /* 3. Save the file_t in curproc's file descriptor table */
        curproc -> p_files[fd] = file;

        /* 4. Set file_t->f_mode to OR of FMODE_(READ|WRITE|APPEND) based on
         *    oflags, which can be O_RDONLY, O_WRONLY or O_RDWR, possibly OR'd with
         *    O_APPEND.
         */
        int mode = -1;

        if( (wr != 0) ||(rd != 0) || (rdwr != 0)){
            if(rd != 0){
                mode = FMODE_READ;
            }
            else if(wr != 0){
                mode = FMODE_WRITE;
            }
            else if(rdwr != 0){
                mode = FMODE_READ | FMODE_WRITE;
            }
            /* last check append */
            if( append != 0){
                mode |= FMODE_APPEND;
            }
        }

        if(mode == -1){
            /*  invalid combination */
            curproc -> p_files[fd] = NULL;
            fput(file);
            return -EINVAL;
        }

        file -> f_mode = mode;

        /* 5. Use open_namev() to get the vnode for the file_t. */
        vnode_t* res_vnode = NULL;
        vnode_t* base = curproc -> p_cwd;
        int res = open_namev(filename, oflags, &res_vnode, base);
        if(res < 0){
            curproc -> p_files[fd] = NULL;
            if(res_vnode)
                vput(res_vnode);
            fput(file);
            return res;/* including errors: ENAMETOOLONG, ENOTDIR, ENOENT */
        }

        if( ((res_vnode -> vn_mode & S_IFDIR) != 0) && (mode != FMODE_READ)){
            curproc -> p_files[fd] = NULL;
            vput(res_vnode);
            fput(file);
            return -EISDIR;
        }
        
        /* 6. Fill in the fields of the file_t */
        file->f_vnode = res_vnode;
        file->f_pos = 0;

        /* 7. return new fd */
        return fd;
        
}
Esempio n. 21
0
int
do_open(const char *filename, int oflags)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_open");*/
		dbg(DBG_PRINT, "Entering do_open()....%s\n", filename);
        int fd = get_empty_fd(curproc);
        if(fd == -EMFILE)
        {
        	dbg(DBG_PRINT, "Exiting do_open()....\n");
        	return fd;
        }

        if((oflags & O_RDONLY) != O_RDONLY && (oflags & O_WRONLY) != O_WRONLY && (oflags & O_RDWR) != O_RDWR)
        {
        	dbg(DBG_PRINT,"None of the access modes(O_RDONLY, O_WRONLY, O_RDWR) set......\n");
        	dbg(DBG_PRINT, "Exiting do_open()....\n");
        	return -EINVAL;
        }

        if((oflags & O_RDWR) == O_RDWR && (oflags & O_WRONLY) == O_WRONLY)
        {
        	dbg(DBG_PRINT, "Invalid flags set.........\n");
        	dbg(DBG_PRINT, "Exiting do_open()....\n");
        	return -EINVAL;
        }

        if((oflags & O_TRUNC) == O_TRUNC)
        {
        	if((oflags & O_RDWR) != O_RDWR && (oflags & O_WRONLY) != O_WRONLY)
        	{
        		dbg(DBG_PRINT, "O_TRUNC set but none of the write flags are set...\n");
        		dbg(DBG_PRINT, "Exiting do_open()....\n");
        		return -EINVAL;
        	}
        }

        if((oflags & O_APPEND) == O_APPEND)
        {
        	if((oflags & O_RDWR) != O_RDWR && (oflags & O_WRONLY) != O_WRONLY)
        	{
        		dbg(DBG_PRINT, "O_APPEND set but none of the write flags are set...........\n");
        		dbg(DBG_PRINT, "Exiting do_open()....\n");
        		return -EINVAL;
        	}
        }

        int count = 0;

        /*const char *p = filename;*/

        if(strlen(filename) > MAXPATHLEN) return -ENAMETOOLONG;

        file_t *sft = fget(-1);
        if(sft == NULL) return ENOMEM; /* not sure ..........................*/

        curproc->p_files[fd] = sft;

        if((oflags & O_WRONLY) == O_WRONLY)
        {
        	sft->f_mode = FMODE_WRITE;
        }

        else if((oflags & O_RDWR) == O_RDWR)
        {
            sft->f_mode = FMODE_WRITE | FMODE_READ;
        }

        else
        {
          	sft->f_mode = FMODE_READ;
        }

        if((oflags & O_APPEND) == O_APPEND)
        {
        	sft->f_mode |= FMODE_APPEND;
        }

        vnode_t *res_vnode;

        /*vfs_is_in_use(vfs_root_vn->vn_fs);*/
        int openv_ret = open_namev(filename, oflags, &res_vnode, NULL);
        if(openv_ret < 0)
        {
        	/*dbg(DBG_PRINT, "do_open()\n", openv_ret);*/
        	fput(sft);  /*Not Sure................................*/
        	if(openv_ret == -ENOENT && (oflags & O_CREAT) != O_CREAT)
        	{
        		dbg(DBG_PRINT, "Exiting do_open()....\n");
        		return -ENOENT;
        	}
        	else
        	{
        		dbg(DBG_PRINT, "Exiting do_open()....\n");
        		return openv_ret;
        	}
        }

        if(S_ISDIR(res_vnode->vn_mode) && ((oflags & O_WRONLY) == O_WRONLY || (oflags & O_RDWR) == O_RDWR))
        {
        	dbg(DBG_PRINT, "Exiting from do_open()\n");
        	fput(sft);
        	vput(res_vnode);
        	return -EISDIR;
        }

        sft->f_pos = 0;
        sft->f_vnode = res_vnode;
        /*sft->f_refcount += 1;*/

        if((oflags & O_TRUNC) == O_TRUNC)
        {
        	sft->f_vnode->vn_len = 0;

        }

        if(S_ISCHR(sft->f_vnode->vn_mode))
        {
        	if(sft->f_vnode->vn_cdev == NULL)
        	{
        		dbg(DBG_PRINT, "Exiting do_open()....\n");
        		/*vput(res_vnode);*/
        		return -ENXIO;
        	}
        }

        if(S_ISBLK(sft->f_vnode->vn_mode))
        {
            if(sft->f_vnode->vn_bdev == NULL)
            {
            	dbg(DBG_PRINT, "Exiting do_open()....\n");
            	/*vput(res_vnode);*/
                return -ENXIO;
            }
        }
        dbg(DBG_PRINT, "Exiting do_open() normally....\n");
        return fd;
}
Esempio n. 22
0
File: open.c Progetto: vikay/kernel2
int
do_open(const char *filename, int oflags)
{
	int status;	
	file_t *f;	
	int fd = get_empty_fd(curproc);
	if(fd!=EMFILE)
	{
		/* can fail if memory not allocated */
		f = fget(-1); 
		if(f==NULL)
			return -ENOMEM;
		curproc->p_files[fd] = f;

		if(oflags & O_RDONLY)		
			f->f_mode = FMODE_READ;
		else if(oflags & O_WRONLY)		
			f->f_mode = FMODE_WRITE;
		else if(oflags & O_RDWR)		
			f->f_mode = FMODE_READ | FMODE_WRITE;
		else if(oflags & (O_WRONLY|O_APPEND))		
			f->f_mode = FMODE_WRITE|FMODE_APPEND;
		else if(oflags & (O_RDWR|O_APPEND))		
			f->f_mode = FMODE_READ|FMODE_WRITE|FMODE_APPEND;
		else
			return -EINVAL; /* not sure if other combinations should be handled */
		if(S_ISDIR(f->f_vnode->vn_mode) && (O_WRONLY | O_RDWR))
		{
			curproc->p_files[fd] = NULL;
			fput(f);			
			return -EISDIR;
		}
		if( S_ISCHR(f->f_vnode->vn_mode) || S_ISBLK(f->f_vnode->vn_mode))
		{
			curproc->p_files[fd] = NULL;
			fput(f);			
			return -ENXIO;
		}
		
		

		/* returns int */
		status = open_namev(filename, oflags, (vnode_t **)(&(f->f_vnode)), NULL); 
		if(status<0)
		{
			curproc->p_files[fd] = NULL;
			fput(f);			
			return status;
		}
		/* can return error codes*/
		status = do_lseek(fd,0,0); /* 3rd argument SEEK_SET = 0 is not defined, not sure to do this as lseek.h not included */
		if(status<0)
		{
			curproc->p_files[fd] = NULL;
			fput(f);			
			return status;
		}
		return fd;
	}
	else
		return -EMFILE;
	/*NOT_YET_IMPLEMENTED("VFS: do_open");
        return -1;*/
}
Esempio n. 23
0
/* To link:
 *      o open_namev(from)
 *      o dir_namev(to)
 *      o call the destination dir's (to) link vn_ops.
 *      o return the result of link, or an error
 *
 * Remember to vput the vnodes returned from open_namev and dir_namev.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        to already exists.
 *      o ENOENT
 *        A directory component in from or to does not exist.
 *      o ENOTDIR
 *        A component used as a directory in from or to is not, in fact, a
 *        directory.
 *      o ENAMETOOLONG
 *        A component of from or to was too long.
 *      o EISDIR
 *        from is a directory.
 */
int
do_link(const char *from, const char *to)
{

     if((strlen(from) > MAXPATHLEN) || (strlen(to) > MAXPATHLEN))
     {
      dbg(DBG_PRINT,"(GRADING2B) A component of from or to is too long\n");
      dbg(DBG_ERROR, "do_link(): A component of from or to is too long\n");
      return -ENAMETOOLONG;
     }

     if((strlen(from)) <= 0 || (strlen(to) <=0))
     {
      dbg(DBG_PRINT,"(GRADING2B) A component of from or to is not valid\n");
      dbg(DBG_ERROR, "do_link(): A component of from or to is not valid\n");
      return -EINVAL;
     }

        size_t namelen;
        int dir_val;
        int open_val;
        const char *name;
        int res=0;
        int res_val =0;
        int val=0;
        vnode_t *old_vnode;
        vnode_t *res_vnode;   /*old_vnode (from), res_vnode(to)*/
        open_val= open_namev(from,0,&old_vnode,NULL);

        if(open_val < 0)
        {
          dbg(DBG_PRINT,"(GRADING2B) open_namev failed\n");
          return open_val;
        }

        res_val = dir_namev(to,&namelen,&name,NULL,&res_vnode);

        if(res_val < 0)
        {
         vput(old_vnode);
         dbg(DBG_PRINT,"(GRADING2B) Error calling dir_namev\n");
         dbg(DBG_ERROR, "do_link(): dir_namev failed\n");
         return res_val;
        }

        vput(old_vnode);

        if(res_vnode->vn_ops->link == NULL)
        {

          dbg(DBG_PRINT,"(GRADING2B) open_namev failed\n");
          return -ENOTDIR;
        }

        else if(lookup(res_vnode,name,namelen, &res_vnode) == 0)
        {
        dbg(DBG_PRINT,"(GRADING2B) given path already exists\n");
        vput(res_vnode);
        return -EEXIST;
        }

        else
        {
         dbg(DBG_PRINT,"(GRADING2B) calling link function\n");
         res = res_vnode->vn_ops->link(old_vnode,res_vnode,name,strlen(name)); 
         vput(res_vnode);
         return res; 
         
        }
               
        /*NOT_YET_IMPLEMENTED("VFS: do_link");*/
        return -1;
}
Esempio n. 24
0
int
do_open(const char *filename, int oflags)
{
        /* VFS {{{ */
        int fd;
        file_t *f;
        vnode_t *file_vnode;
        int ret;

        if ((oflags & O_WRONLY) && (oflags & O_RDWR)) {
                return -EINVAL;
        }

        if ((fd = get_empty_fd(curproc)) < 0) {
                return fd;
        }

        if ((f = fget(-1)) == NULL) {
                return -ENOMEM;
        }

        curproc->p_files[fd] = f;

        dbg(DBG_VFS, "open on %s, file at %p\n", filename, curproc->p_files[fd]);

        switch (oflags & 0x3) {
                case O_RDONLY:
                        f->f_mode = FMODE_READ;
                        break;
                case O_WRONLY:
                        f->f_mode = FMODE_WRITE;
                        break;
                case O_RDWR:
                        f->f_mode = FMODE_READ | FMODE_WRITE;
                        break;
                default:
                        /*kthread_cleanup_pop(1);*/
                        nukefd(fd);
                        return -EINVAL;
        }

        if ((ret = open_namev(filename, oflags, &file_vnode, NULL)) < 0) {
                /*kthread_cleanup_pop(1);*/
                nukefd(fd);
                return ret;
        }

        if (((oflags & O_WRONLY) || (oflags & O_RDWR)) && S_ISDIR(file_vnode->vn_mode)) {
                /*kthread_cleanup_pop(1);*/
                nukefd(fd);
                vput(file_vnode);
                return -EISDIR;
        }

        if (S_ISBLK(file_vnode->vn_mode) && (!file_vnode->vn_bdev)) {
                /*kthread_cleanup_pop(1);*/
                nukefd(fd);
                vput(file_vnode);
                return -ENXIO;
        }

        if (S_ISCHR(file_vnode->vn_mode) && (!file_vnode->vn_cdev)) {
                /*kthread_cleanup_pop(1);*/
                nukefd(fd);
                vput(file_vnode);
                return -ENXIO;
        }

        f->f_vnode = file_vnode;
        dbg(DBG_VFS, " vnode at %p\n", file_vnode);
        if (oflags & O_APPEND) {
                f->f_mode |= FMODE_APPEND;
        }

        /*kthread_cleanup_pop(0);*/
        return fd;
        /* VFS }}} */
        return -1;
}
Esempio n. 25
0
int
do_open(const char *filename, int oflags)
{
    dbg(DBG_VFS, "calling do_open on %s\n", filename);
    /* step 1: get next empty file descriptor */
    int fd = get_empty_fd(curproc);

    /* error case 2 */
    if (fd == -EMFILE){
        return -EMFILE;
    }

    /* step 2: Call fget to get a fresh file_t */
    file_t *f = fget(-1);

    /* error case 3 */
    if (f == NULL){
        return -ENOMEM;
    }

    KASSERT(f != NULL);
    KASSERT(f->f_refcount == 1);

    /* step 3: Save file_t in curproc's file descriptor table */
    KASSERT(curproc->p_files[fd] == NULL);
    curproc->p_files[fd] = f;

    /* step 4: Set the file_t->f-mode */
    f->f_mode = 0;

    if (oflags & O_APPEND){
        f->f_mode = FMODE_APPEND;
    }

    if ((oflags & O_WRONLY) && !(oflags & O_RDWR)){
        f->f_mode |= FMODE_WRITE;
    } else if ((oflags & O_RDWR) && !(oflags & O_WRONLY)){
        f->f_mode |= FMODE_READ | FMODE_WRITE;
    } else if (oflags == O_RDONLY || oflags == (O_RDONLY | O_CREAT)
            || oflags == (O_RDONLY | O_APPEND)
            || oflags == (O_RDONLY | O_CREAT | O_APPEND)){
        f->f_mode |= FMODE_READ;
    } else {
        dbg(DBG_VFS, "oflags not valid\n");
        fput(f);
        curproc->p_files[fd] = NULL;
        return -EINVAL;
    }

    /* make sure we have a valid mode */
    KASSERT(f->f_mode == FMODE_READ
            || f->f_mode == FMODE_WRITE
            || f->f_mode == (FMODE_READ | FMODE_WRITE)
            || f->f_mode == (FMODE_WRITE | FMODE_APPEND)
            || f->f_mode == (FMODE_READ | FMODE_WRITE | FMODE_APPEND));

    /* step 5: use open_namev to get the vnode for the file_t */
    int open_result = open_namev(filename, oflags, &f->f_vnode, NULL);

    if (open_result < 0){
        curproc->p_files[fd] = NULL;
        fput(f);
        return open_result;
    }

    dbg(DBG_VFS, "found the vnode with id %d. Current refcount is %d\n",
            f->f_vnode->vn_vno, f->f_vnode->vn_mmobj.mmo_refcount);

    /* step 6: fill in the fields of the file_t */
    /* no need to call vref, since open_namev() took care of that*/
    f->f_pos = 0;
    f->f_refcount = 1;

    /* step 7: return new fd */
    return fd;
}