Ejemplo n.º 1
0
/* Use dir_namev() to find the vnode of the directory containing the dir to be
 * removed. Then call the containing dir's rmdir v_op.  The rmdir v_op will
 * return an error if the dir to be removed does not exist or is not empty, so
 * you don't need to worry about that here. Return the value of the v_op,
 * or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        path has "." as its final component.
 *      o ENOTEMPTY
 *        path has ".." as its final component.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_rmdir(const char *path)
{
        if (strlen(path) > MAXPATHLEN)
        {
                dbg(DBG_PRINT,"(GRADING2B) Path length exceeding maximum path length\n");
                dbg(DBG_ERROR, "Path length exceeding maximum path length\n");
                return -ENAMETOOLONG;
        }

        size_t namelen;
        const char *name;
        vnode_t *res_vnode;


        int dir_value = dir_namev(path, &namelen, &name, NULL, &res_vnode);
        if (dir_value<0)
        {
                dbg(DBG_PRINT,"(GRADING2B) Error in calling dir_namev function\n");
                dbg(DBG_ERROR, "Error in calling dir_namev function\n");
                return dir_value; 
        }

        /*int result=lookup(res_vnode,name, namelen, &res_vnode);*/

        KASSERT(NULL != res_vnode->vn_ops->rmdir);
        dbg(DBG_PRINT,"\n(GRADING2A 3.d) res_vnode->vn_ops is not NULL");

      /*  if (result==-ENOTDIR)
        {
                dbg(DBG_ERROR, "\n A component used as a directory in path is not, in fact, a directory.");
                return -ENOTDIR;

        }*/

        if(strcmp(name,".")==0)
        {

                vput(res_vnode);
                dbg(DBG_PRINT,"(GRADING2B) do_rmdir(): path has '.' as final component\n");
                dbg(DBG_ERROR, "do_rmdir(): path has '.' as final component\n");
                return -EINVAL;
        }
        if(strcmp(name,"..")==0)
        {
                vput(res_vnode);
                dbg(DBG_PRINT,"(GRADING2B) do_rmdir(): path has '..' as final component\n");
                dbg(DBG_ERROR, "do_rmdir(): path has '..' as final component\n");
                return -ENOTEMPTY;
        }
        
        int res_val = res_vnode->vn_ops->rmdir(res_vnode,name,namelen);
        vput(res_vnode);
        return res_val;



        /*NOT_YET_IMPLEMENTED("VFS: do_rmdir");
        return -1;*/
}
Ejemplo n.º 2
0
/*
 * Same as do_rmdir, but for files.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EISDIR
 *        path refers to a directory.
 *      o ENOENT
 *        A component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_unlink(const char *path)
{

      if(strlen(path) > MAXPATHLEN)
     {
      dbg(DBG_PRINT,"(GRADING2B) do_unlink(): path name Provided is too long\n");
      dbg(DBG_ERROR, "do_unlink(): path name Provided is too long\n");
      return -ENAMETOOLONG;
     }

     if(strlen(path) <=0)
     {
      dbg(DBG_PRINT,"(GRADING2B) do_link(): given path name is not valid\n");
      dbg(DBG_ERROR, "do_link(): path name is not valid\n");
      return -EINVAL;
     }
        size_t namelen;
        const char *name;
        vnode_t *res_vnode;
        vnode_t *check_vnode;
        int ret_val =0;
        int val=0;
        int unlinking = 0;
        ret_val = dir_namev(path,&namelen,&name,NULL,&res_vnode);

        if(ret_val<0)
        {  
            dbg(DBG_PRINT,"(GRADING2B) Error while calling dir_namev function\n");   
            return ret_val;
        }
        

        val = lookup(res_vnode,name,namelen,&check_vnode);

        if(val<0)
        {   
            vput(res_vnode);
            dbg(DBG_PRINT,"(GRADING2B) Error while calling lookup function\n"); 
            return val;
        }

        if(S_ISDIR(check_vnode->vn_mode))
        {
          vput(res_vnode);
          vput(check_vnode);
          dbg(DBG_PRINT,"(GRADING2B) The given path is a directory\n");
          dbg(DBG_ERROR, "do_unlink(): path is directory\n");
          return -EISDIR;
        }

        KASSERT(NULL != res_vnode->vn_ops->unlink);
        dbg(DBG_PRINT, "(GRADING2A 3.e) do_unlink(): corresponding vn_ops no NULL\n");
        unlinking = res_vnode->vn_ops->unlink(res_vnode, name, namelen);
        vput(res_vnode);
        vput(check_vnode);
        return unlinking;
        /*NOT_YET_IMPLEMENTED("VFS: do_unlink");
        return -1;*/
}
Ejemplo n.º 3
0
/*
 * This routine creates a special file of the type specified by 'mode' at
 * the location specified by 'path'. 'mode' should be one of S_IFCHR or
 * S_IFBLK (you might note that mknod(2) normally allows one to create
 * regular files as well-- for simplicity this is not the case in Weenix).
 * 'devid', as you might expect, is the device identifier of the device
 * that the new special file should represent.
 *
 * You might use a combination of dir_namev, lookup, and the fs-specific
 * mknod (that is, the containing directory's 'mknod' vnode operation).
 * Return the result of the fs-specific mknod, or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        mode requested creation of something other than a device special
 *        file.
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int do_mknod(const char *path, int mode, unsigned devid) {
	/* NOT_YET_IMPLEMENTED("VFS: do_mknod"); */

	if (mode != S_IFCHR && mode != S_IFBLK) {
		dbg(DBG_ERROR, "1\n");
		return -EINVAL;
	}
	dbg(DBG_PRINT, "(GRADING2B)\n");
	size_t namelen = NULL;
	const char *name = NULL;
	vnode_t *base;
	vnode_t *res_vnode = NULL, *result = NULL;
	/*if (strlen(path) > MAXPATHLEN){
	 dbg(DBG_ERROR,"2\n");
	 return -ENAMETOOLONG;
	 }*/
	/* Base passed NULL since dir_namev can handle accordingly */
	int retdir_namev = dir_namev(path, &namelen, &name, NULL, &res_vnode);
	/*dbg(DBG_PRINT,"culprit is %s",path);*/
	/*
	 if (strlen(name) > NAME_LEN) {
	 dbg(DBG_ERROR,"3\n");
	 if (retdir_namev == 0) {
	 dbg(DBG_ERROR,"4\n");
	 vput(res_vnode);
	 }
	 return -ENAMETOOLONG;
	 }*/
	if (retdir_namev == 0) {
		dbg(DBG_PRINT, "(GRADING2B)\n");

		int retlookup = lookup(res_vnode, name, namelen, &result);

		if (result != NULL) {
			dbg(DBG_ERROR, "6\n");
			vput(result);
			return -EEXIST;
		} else if (result == NULL) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			KASSERT(NULL != (res_vnode)->vn_ops->mknod);
			dbg(DBG_PRINT, "(GRADING2A 3.b)\n");

			int ramfs_ret = (res_vnode)->vn_ops->mknod(res_vnode, name, namelen,
					mode, devid);
			/*lookup(res_vnode, name, namelen, &result);*/
			/*dbg(DBG_PRINT, "Created special file %s ref=%d\n", path,
			 result->vn_refcount);*/

			return ramfs_ret;
		}

		return retlookup;

	} /*else {
	 dbg(DBG_ERROR,"8\n");
	 return retdir_namev;
	 }*/
	/*dbg(DBG_ERROR,"9\n");*/
	return 0;
}
Ejemplo n.º 4
0
/*
 * Same as do_rmdir, but for files.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EISDIR
 *        path refers to a directory.
 *      o ENOENT
 *        A component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int do_unlink(const char *path) {
	/* NOT_YET_IMPLEMENTED("VFS: do_unlink"); */
	size_t namelen;
	const char *name;
	vnode_t *base;
	vnode_t *res_vnode, *result;
	dbg(DBG_PRINT, "(GRADING2B)\n");
	/*if (strlen(path) > MAXPATHLEN) {
	 dbg(DBG_ERROR, "2\n");
	 return -ENAMETOOLONG;
	 }*/
	/* Base passed NULL since dir_namev can handle accordingly */
	int retdir_namev = dir_namev(path, &namelen, &name, NULL, &res_vnode);
	/*if (strlen(name) > NAME_LEN) {
	 dbg(DBG_ERROR, "3\n");
	 if (retdir_namev == 0) {
	 dbg(DBG_ERROR, "4\n");
	 vput(res_vnode);
	 }
	 return -ENAMETOOLONG;
	 }*/
	/*dbg(DBG_ERROR, "name is %s\n", name);*/
	if (0 == retdir_namev) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		vput(res_vnode);
		int retlookup = lookup(res_vnode, name, namelen, &result);

		if (retlookup == 0) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			if (NULL != result) {
				dbg(DBG_PRINT, "(GRADING2B)\n");

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

				KASSERT(NULL != (res_vnode)->vn_ops->unlink);
				dbg(DBG_PRINT, "(GRADING2A 3.e)\n");

				int ret_unlink = (res_vnode)->vn_ops->unlink(res_vnode, name,
						namelen);

			}
		} else {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			return retlookup;
		}

	} /*else {
	 dbg(DBG_ERROR, "10\n");
	 return retdir_namev;
	 }*/

	dbg(DBG_PRINT, "(GRADING2B)\n");
	return 0;
}
Ejemplo 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.
 *      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;
}
Ejemplo n.º 6
0
/* Use dir_namev() to find the vnode of the dir we want to make the new
 * directory in.  Then use lookup() to make sure it doesn't already exist.
 * Finally call the dir's mkdir vn_ops. Return what it returns.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mkdir(const char *path)
{
  size_t len;
  const char *name;
  vnode_t *rest;
  struct vnode *result=NULL;
  int ent,dir_name_out,made;

  /*Alekhya: If the component of the path was too long*/
  /*Add a self check test for this*/
  /*  if(strlen(path)>MAXPATHLEN)
    {
      dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_mkdir) Name too long\n");
      return -ENAMETOOLONG;
      }*/
  
  /*Note: return error numbers in this function so can be used directly*/
  dir_name_out=dir_namev(path,&len,&name,NULL,&rest);
  if (strlen(name) > NAME_LEN) 
    {
       vput(rest);
        dbg(DBG_PRINT,"(GRADING2B) Part of Name too long(greater than NAME_LEN) (for LONGNAME test), return -ENAMETOOLONG\n");
        return -ENAMETOOLONG;
    }
  if(dir_name_out<0)
    {
         dbg(DBG_PRINT,"(GRADING2B) error returned from dir_namev, return error \n");
        return dir_name_out;
    }

  /*Alekhya: If the vnode itself does not exist, or the vnode does not refer to a directory*/
  if(rest==NULL || !(S_ISDIR(rest->vn_mode)))
    {
      vput(rest);
      dbg(DBG_PRINT,"(GRADING2B) It is not a directory return -ENOTDIR");
      return -ENOTDIR;
    }
  vput(rest);
  /*Alekhya: Calling lookup function to make sure the path does not already exist*/
  ent=lookup(rest,name,len,&result);

  if(ent==0)
    {
      vput(result);
      dbg(DBG_PRINT,"(GRADING2B) Path already exists as lookup return 0, return -EEXIST\n");
      return -EEXIST;
    }

   KASSERT(NULL != rest->vn_ops->mkdir);
   dbg(DBG_PRINT,"(GRADING2A 3.c) KASSERT(NULL != pointer to corresponding vnode->vn_ops->mkdir);");
  made=rest->vn_ops->mkdir(rest,name,len);
  /*vput(rest);*/
  return made;
  /*        NOT_YET_IMPLEMENTED("VFS: do_mkdir");
	    return -1;*/
}
/*
 * 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)
{
	if(*path == '\0')
	{
		KASSERT(*path == '\0');
		dbg(DBG_PRINT,"(GRADING2D 3.f): Path component empty!\n");
		return -EINVAL;
	}

	size_t namelen=0;
	const char *name=NULL;
	vnode_t *temp_vnode = NULL;
	vnode_t *res_vnode=NULL;

	KASSERT(path);
	KASSERT(buf);

	int namev_ret = dir_namev(path,&namelen,&name,NULL,&res_vnode);
	/*if(namev_ret<0){
		KASSERT(namev_ret<0);
		dbg(DBG_PRINT,"(GRADING2D 3.f): Path component has failed.\n");*/
                  /* this should take care of ENAMETOOLONG*/
	/*	return namev_ret;
	}*/

	/*if(res_vnode == NULL)*/   /*because dirnamev doesnt return ENOENT*/
	/*{
	  dbg(DBG_PRINT," Directory component in path does not exist\n");
	  return -ENOENT;
	}*/
	/*if(!S_ISDIR(res_vnode->vn_mode))
        {
          dbg(DBG_PRINT,"A component of the path prefix of path is not a directory.\n");
          vput(res_vnode);
          return -ENOTDIR;
        }*/
        
        /* All return codes taken care off */
        namev_ret =  lookup(res_vnode,name,namelen,&temp_vnode);
        
        if (namev_ret<0)
        {
          dbg(DBG_PRINT,"Lookup failed, name is not in directory\n");
          vput(res_vnode);
          return namev_ret;
        }

	KASSERT(res_vnode->vn_ops->stat);
	dbg(DBG_PRINT, "(GRADING2A 3.f): The stat function exists !!!.\n");
	int stat_ret=(res_vnode->vn_ops->stat)(temp_vnode,buf);
	vput(res_vnode);
	vput(temp_vnode);
	dbg(DBG_PRINT,"(GRADING2D 3.l): Successfully Found the vnode associated with the path");
	return stat_ret;
}
Ejemplo n.º 8
0
/* This returns in res_vnode the vnode requested by the other parameters.
 * It makes use of dir_namev and lookup to find the specified vnode (if it
 * exists).  flag is right out of the parameters to open(2); see
 * <weenix/fnctl.h>.  If the O_CREAT flag is specified, and the file does
 * not exist call create() in the parent directory vnode.
 *
 * Note: Increments vnode refcount on *res_vnode.
 */
int
open_namev(const char *pathname, int flag, vnode_t **res_vnode, vnode_t *base)
{
        /* VFS {{{ */
        int ret;

        const char *name;
        size_t namelen;

        vnode_t *dir;
        vnode_t *file = NULL;

        if ((ret = dir_namev(pathname, &namelen, &name, base, &dir)) < 0) {
                /* the directory itself doesn't exist */
                return ret;
        }

        /*kthread_cleanup_push(vput,dir);*/

        if ((ret = lookup(dir, name, namelen, &file)) == -ENOENT) {
                /* file doesn't exist.  create it if need be */
                if (flag & O_CREAT) {
                        int ret2;
                        KASSERT(NULL != dir->vn_ops->create);
                        /* We're making a file, check name length */
                        if (namelen >= NAME_LEN) {
                                vput(dir);
                                return -ENAMETOOLONG;
                        }
                        if ((ret2 = dir->vn_ops->create(dir, name, namelen, &file)) < 0) {
                                /* if we can't create it just give up */
                                /*kthread_cleanup_pop(1);*/
                                vput(dir);
                                return ret2;
                        } else {
                                /*kthread_cleanup_pop(1);*/
                                vput(dir);
                                *res_vnode = file;
                                return 0;
                        }
                } else {
                        /* otherwise return error. */
                        /*kthread_cleanup_pop(1);*/
                        vput(dir);
                        return ret;
                }
        } else {
                /* note that we may be in error here, it don't matter */
                *res_vnode = file;
                /*kthread_cleanup_pop(1);*/
                vput(dir);
                return ret;
        }
        /* VFS }}} */
        return 0;
}
Ejemplo n.º 9
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;*/
}
Ejemplo n.º 10
0
/* Use dir_namev() to find the vnode of the dir we want to make the new
 * directory in.  Then use lookup() to make sure it doesn't already exist.
 * Finally call the dir's mkdir vn_ops. Return what it returns.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int do_mkdir(const char *path) {
	/*NOT_YET_IMPLEMENTED("VFS: do_mkdir");*/

	dbg(DBG_PRINT, "(GRADING2B)\n");
	size_t namelen = 0;
	const char *name;
	vnode_t *base;
	vnode_t *res_vnode, *result;
	/*
	 if (strlen(path) > MAXPATHLEN){
	 dbg(DBG_ERROR,"1\n");
	 return -ENAMETOOLONG;
	 }*/
	/* Base passed NULL since dir_namev can handle accordingly */
	int retdir_namev = dir_namev(path, &namelen, &name, NULL, &res_vnode);

	if (strlen(name) > NAME_LEN) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		if (retdir_namev == 0) {
			dbg(DBG_PRINT, "(GRADING2B)\n");

		}
		return -ENAMETOOLONG;
	}
	if (retdir_namev == 0) {
		dbg(DBG_PRINT, "(GRADING2B)\n");

		int retlookup = lookup(res_vnode, name, namelen, &result);

		if (retlookup == 0) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			vput(result);
			vput(res_vnode);
			return -EEXIST;
		}
		if (retlookup == -ENOENT) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			KASSERT(NULL != (res_vnode)->vn_ops->mkdir);
			dbg(DBG_PRINT, "(GRADING2A 3.c)\n");

			int ramfs_ret = (res_vnode)->vn_ops->mkdir(res_vnode, name,
					namelen);
			vput(res_vnode);
			return ramfs_ret;
		}
		if (retlookup == -ENOTDIR) {
			vput(res_vnode);
			return -ENOTDIR;
		}

	} else {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return retdir_namev;
	}
	return 0;
}
Ejemplo n.º 11
0
/*
 * This routine creates a special file of the type specified by 'mode' at
 * the location specified by 'path'. 'mode' should be one of S_IFCHR or
 * S_IFBLK (you might note that mknod(2) normally allows one to create
 * regular files as well-- for simplicity this is not the case in Weenix).
 * 'devid', as you might expect, is the device identifier of the device
 * that the new special file should represent.
 *
 * You might use a combination of dir_namev, lookup, and the fs-specific
 * mknod (that is, the containing directory's 'mknod' vnode operation).
 * Return the result of the fs-specific mknod, or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        mode requested creation of something other than a device special
 *        file.
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mknod(const char *path, int mode, unsigned devid)
{


        if (mode !=S_IFBLK && mode !=S_IFCHR)
        {
                dbg(DBG_PRINT,"(GRADING2B) The special file is neither Block device nor character device\n");
                dbg(DBG_ERROR, "Mode specified is wrong\n");
                return -EINVAL;
        }
        if (strlen(path) > MAXPATHLEN)
        {
                dbg(DBG_PRINT,"(GRADING2B) Path length exceeds maximum path length that is allowed\n");
                dbg(DBG_ERROR, "Path length exceeding maximum path length\n");
                return -ENAMETOOLONG;
        }


        size_t namelen =0;
        const char *name = NULL;
        vnode_t *res_vnode = NULL;

        int dir_value = dir_namev(path, &namelen, &name, NULL, &res_vnode);
        if (dir_value<0)
        {
                 dbg(DBG_PRINT,"(GRADING2B) Error in acquiring the vnode, name and name length of the path specified\n");
                 dbg(DBG_ERROR, "Error in calling dir_namev function\n");
                 return dir_value; 
        }
        vput(res_vnode);
        int result=lookup(res_vnode,name, namelen, &res_vnode);

        KASSERT(NULL != res_vnode->vn_ops->mknod);
        dbg(DBG_PRINT,"(GRADING2A 3.b) res_vnode->vn_ops is not NULL\n");

        if (result==0)
        {
                dbg(DBG_PRINT,"(GRADING2B) The given path already exists\n");
                dbg(DBG_ERROR, "Path already exists\n");
                vput(res_vnode);
                return -EEXIST;
        }
        if (result == -ENOENT)
        {
                dbg(DBG_PRINT,"(GRADING2B) There is no entry for the particular file\n");
                dbg(DBG_PRINT, "No entry for that particular file\n");
                /*vput(res_vnode);*/
                int res = res_vnode->vn_ops->mknod(res_vnode,name,namelen,mode,devid);
                return res;
        }
        return 0;
        /*NOT_YET_IMPLEMENTED("VFS: do_mknod");
        return -1;*/
}
Ejemplo n.º 12
0
/* Use dir_namev() to find the vnode of the directory containing the dir to be
 * removed. Then call the containing dir's rmdir v_op.  The rmdir v_op will
 * return an error if the dir to be removed does not exist or is not empty, so
 * you don't need to worry about that here. Return the value of the v_op,
 * or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        path has "." as its final component.
 *      o ENOTEMPTY
 *        path has ".." as its final component.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int do_rmdir(const char *path) {
	/* NOT_YET_IMPLEMENTED("VFS: do_rmdir"); */
	size_t namelen;
	const char *name;
	vnode_t *base;
	vnode_t *res_vnode, *result;
	int tempLookup = 0;
	dbg(DBG_PRINT, "(GRADING2B)\n");
	/*
	 if (strlen(path) > MAXPATHLEN) {
	 dbg(DBG_ERROR, "1\n");
	 return -ENAMETOOLONG;
	 }*/
	/* Base passed NULL since dir_namev can handle accordingly */
	int retdir_namev = dir_namev(path, &namelen, &name, NULL, &res_vnode);
	if (retdir_namev != 0) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return retdir_namev;
	}
	if (name_match(".", name, namelen)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		vput(res_vnode);
		return -EINVAL;
	}
	if (name_match("..", name, namelen)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		vput(res_vnode);
		return -ENOTEMPTY;
	}
	if (strlen(name) > NAME_LEN) {
		dbg(DBG_ERROR, "5\n");
		vput(res_vnode);
		return -ENAMETOOLONG;
	}
	if (0 == retdir_namev) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		vput(res_vnode);
		tempLookup = lookup(res_vnode, name, namelen, &result);

		KASSERT(NULL != (res_vnode)->vn_ops->rmdir);
		dbg(DBG_PRINT, "(GRADING2A 3.d)\n");

		int ret_rmdir = (res_vnode)->vn_ops->rmdir(res_vnode, name, namelen);
		if (ret_rmdir == 0 && result != NULL) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			vput(result);

		} else if (tempLookup == 0 && result != NULL) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			vput(result);
		}
		return ret_rmdir;
	}
	return 0;
}
Ejemplo n.º 13
0
/*
 * Same as do_rmdir, but for files.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EISDIR
 *        path refers to a directory.
 *      o ENOENT
 *        A component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_unlink(const char *path)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_unlink");*/
        if (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        vnode_t *parent_vnode,*child_vnode;
        int child_retVal,parent_retVal;
        size_t namelen;
        const char *name;
    
        dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal) {
            return parent_retVal;
        }
    
        child_retVal = lookup(parent_vnode,name,namelen,&child_vnode);
        if (child_retVal){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return child_retVal;
        }
    
        if (S_ISDIR(child_vnode->vn_mode)){
            vput(parent_vnode);
            vput(child_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EISDIR;
        }
    
        KASSERT(NULL != parent_vnode->vn_ops->unlink);
        dbg(DBG_PRINT,"(GRADING2A 3.e)\n");
    
        vput(parent_vnode);
        vput(child_vnode);
    
        return parent_vnode->vn_ops->unlink(parent_vnode,name,namelen);

}
Ejemplo n.º 14
0
/*
 * Same as do_rmdir, but for files.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EISDIR
 *        path refers to a directory.
 *      o ENOENT
 *        A component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_unlink(const char *path)
{
 size_t len=0;
  const char *name=NULL;
  vnode_t *rest=NULL,*result=NULL;
  int dir_name_out,rem,ent;
 
  /*if(strlen(path)>MAXPATHLEN)
    {
      dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_unlink) Path greater than MAXPATHLEN, return -ENAMETOOLONG\n");
      return -ENAMETOOLONG;
      }*/
  
  dir_name_out=dir_namev(path,&len,&name,NULL,&rest);
  if(dir_name_out<0)
    {
        dbg(DBG_PRINT,"(GRADING2B) error returned from dir_namev, return error \n");
        return dir_name_out;
    }

  /*Alekhya: If the vnode itself does not exist, or the vnode does not refer to a directory*/
  if(rest==NULL || !(S_ISDIR(rest->vn_mode)))
    {
      vput(rest);
      dbg(DBG_PRINT,"(GRADING2C 1.f) It is not a directory, return -ENOTDIR");
      return -ENOTDIR;
    }

  ent=lookup(rest,name,len,&result);
  if(ent<0)
    {
        dbg(DBG_PRINT,"(GRADING2B)error returned from lookup(cannot find it) so dec ref count, return error \n");
        vput(rest);
      return ent;
    }
  if(S_ISDIR(result->vn_mode))
    {
      vput(rest);
      vput(result);
      dbg(DBG_PRINT,"(GRADING2B)Is a directory cannot link directory, decrease ref count, return -EISDIR\n");
      return -EISDIR;
    }
  /*Alekhya: If error free, call rmdir*/
  KASSERT(NULL != rest->vn_ops->unlink);
  dbg(DBG_PRINT,"(GRADING2A 3.e)(middle)KASSERT(NULL != /* pointer to corresponding vnode */->vn_ops->unlink);\n");
  rem=rest->vn_ops->unlink(rest,name,len);
  vput(rest);
  vput(result);
  return rem;
 
  /*       NOT_YET_IMPLEMENTED("VFS: do_unlink");
	   return -1;*/
}
Ejemplo n.º 15
0
/* Use dir_namev() to find the vnode of the directory containing the dir to be
 * removed. Then call the containing dir's rmdir v_op.  The rmdir v_op will
 * return an error if the dir to be removed does not exist or is not empty, so
 * you don't need to worry about that here. Return the value of the v_op,
 * or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        path has "." as its final component.
 *      o ENOTEMPTY
 *        path has ".." as its final component.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_rmdir(const char *path)
{
  size_t len=0;
  const char *name=NULL;
  vnode_t *rest=NULL;
  int dir_name_out,rem;
  
  /*Note: return error numbers in this function so can be used directly*/
  dir_name_out=dir_namev(path,&len,&name,NULL,&rest);
  /*Andy:path has "." as its final component. */
  if(dir_name_out<0)
      {
            dbg(DBG_PRINT,"(GRADING2B) error returned from dir_namev, return error \n");
          return dir_name_out;
      }
  if(strcmp(name,".")==0){
        dbg(DBG_PRINT,"(GRADING2B) name is . ,cannot remove, return -EINVAL\n");
      vput(rest);
	  return -EINVAL;
  }
  /*Andy:path has ".." as its final component. */
   if(strcmp(name,"..")==0){
        dbg(DBG_PRINT,"(GRADING2B) name is .. ,cannot remove, return -ENOTEMPTY\n");
       vput(rest);
     return -ENOTEMPTY;
   }
   /*Add a self check test for this*/
   /*if(strlen(path)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_rmdir) Path is greater than max path length, return -ENAMETOOLONG\n");
        vput(rest);
      return -ENAMETOOLONG;
      }*/
  
  /*Alekhya: The rest  of the errors are handled inside this function*/


  /*Alekhya: If the vnode itself does not exist, or the vnode does not refer to a directory*/
  if(rest==NULL || !(S_ISDIR(rest->vn_mode)))
    {
      vput(rest);
      dbg(DBG_PRINT,"(GRADING2B) It is not a directory can only remove directory, return -ENOTDIR");
      return -ENOTDIR;
    }
  /*Alekhya: If error free, call rmdir*/
  KASSERT(NULL != rest->vn_ops->rmdir);
  dbg(DBG_PRINT,"(GRADING2A 3.d)(middle)KASSERT(NULL != /* pointer to corresponding vnode */->vn_ops->rmdir);\n");
  rem=rest->vn_ops->rmdir(rest,name,len);
  vput(rest);
  return rem;
  /*      NOT_YET_IMPLEMENTED("VFS: do_rmdir");
	  return -1;*/
}
Ejemplo n.º 16
0
/* Use dir_namev() to find the vnode of the dir we want to make the new
 * directory in.  Then use lookup() to make sure it doesn't already exist.
 * Finally call the dir's mkdir vn_ops. Return what it returns.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      on ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mkdir(const char *path)
{
        if (strlen(path) > MAXPATHLEN)
        {
                dbg(DBG_PRINT,"(GRADING2B) path length exceeds the maximum path length limit\n");
                dbg(DBG_ERROR, "Path length exceeding maximum path length\n");
                return -ENAMETOOLONG;
        }

        size_t namelen;
        const char *name;
        vnode_t *res_vnode;

        int dir_value = dir_namev(path, &namelen, &name, NULL, &res_vnode);
        
        if (dir_value<0 )
        {
                dbg(DBG_PRINT,"(GRADING2B) Error in calling dir_namev function\n");
                dbg(DBG_ERROR, "Error in calling dir_namev function\n");
                return dir_value; 
        }
        vput(res_vnode);
        int result=lookup(res_vnode,name, namelen, &res_vnode);

        dbg(DBG_PRINT,"(GRADING2A 3.c) res_vnode->vn_ops is not NULL\n");

        if (result==-ENOTDIR)
        {
                dbg(DBG_PRINT,"(GRADING2B) A component used as a directory in path is not, in fact, a directory\n");
                dbg(DBG_ERROR, "A component used as a directory in path is not, in fact, a directory\n");
                return -ENOTDIR;
        }

        if (result==0)
        {
                dbg(DBG_PRINT,"(GRADING2B) Specified path already exists\n");
                dbg(DBG_ERROR, "Path already exists\n");
                vput(res_vnode);
                return -EEXIST;
        }
        if (result == -ENOENT)
        {
            KASSERT(NULL != res_vnode->vn_ops->mkdir);
                dbg(DBG_PRINT,"(GRADING2B) No entry for this file\n");
                dbg(DBG_PRINT,"No entry for that particular file\n");
                /*vput(res_vnode);*/
                return res_vnode->vn_ops->mkdir(res_vnode,name,namelen);
        }
        return 0;

        /*NOT_YET_IMPLEMENTED("VFS: do_mkdir");
        return -1;*/
}
Ejemplo n.º 17
0
/*
 * This routine creates a special file of the type specified by 'mode' at
 * the location specified by 'path'. 'mode' should be one of S_IFCHR or
 * S_IFBLK (you might note that mknod(2) normally allows one to create
 * regular files as well-- for simplicity this is not the case in Weenix).
 * 'devid', as you might expect, is the device identifier of the device
 * that the new special file should represent.
 *
 * You might use a combination of dir_namev, lookup, and the fs-specific
 * mknod (that is, the containing directory's 'mknod' vnode operation).
 * Return the result of the fs-specific mknod, or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        mode requested creation of something other than a device special
 *        file.
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mknod(const char *path, int mode, unsigned devid)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_mknod");*/
        if (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        if ((mode != S_IFCHR) && (mode != S_IFBLK)){
            return -EINVAL;
        }
    
        vnode_t *parent_vnode,*child_vnode;
        int parent_retVal,child_retVal;
        size_t namelen;
        const char *name;
    
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal){
            return parent_retVal;
        }
    
        child_retVal = lookup(parent_vnode,name,namelen,&child_vnode);
        if (!child_retVal){
            vput(parent_vnode);
            vput(child_vnode);
            return -EEXIST;
        }
        else {
            if (child_retVal == -ENOENT){
                if (!S_ISDIR(parent_vnode->vn_mode)){
                    vput(parent_vnode);
                    return -ENOTDIR;
                }
            
                KASSERT(NULL != parent_vnode->vn_ops->mknod);
                dbg(DBG_PRINT,"(GRADING2A 3.b)\n");
                vput(parent_vnode);
                return parent_vnode->vn_ops->mknod(parent_vnode,name,namelen,mode,devid);
            }
        }
    
        vput(parent_vnode);
        return child_retVal;
    
        /*Comment the code below if any of the above code is uncommented - AS*/
        /*dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        KASSERT(NULL != parent_vnode->vn_ops->mknod);
        lookup(parent_vnode,name,namelen,&child_vnode);
        dbg(DBG_PRINT,"(GRADING2A 3.b)\n");
        vput(parent_vnode);
        return parent_vnode->vn_ops->mknod(parent_vnode,name,namelen,mode,devid);*/
}
Ejemplo n.º 18
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");*/
        if (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        int child_retVal,parent_retVal;
        vnode_t *parent_vnode,*child_vnode;
        size_t namelen;
        const char *name;
    
        dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal){
            return parent_retVal;
        }
    
        child_retVal = lookup(parent_vnode,name,namelen,&child_vnode);
        if (child_retVal){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return child_retVal;
        }
    
        if (!S_ISDIR(child_vnode->vn_mode)){
            vput(parent_vnode);
            vput(child_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -ENOTDIR;
        }
    
        vput(parent_vnode);
        vput(curproc->p_cwd);
        curproc->p_cwd = child_vnode;
    
        return 0;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
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)
{

        if(strlen(path) > MAXPATHLEN)
        {
          dbg(DBG_PRINT,"(GRADING2B) A component in the path specified is too long\n");
          return -ENAMETOOLONG;
        }
        if(strlen(path) <= 0)
        {
          dbg(DBG_PRINT, "(GRADING2B) do_stat(): Path specified is not a valid path\n");
          return -EINVAL;
        }
        size_t namelen;
        const char *name;
        vnode_t *res_vnode;
        int ret_val =0;
        ret_val = dir_namev(path,&namelen,&name,NULL,&res_vnode);
        
        if(ret_val<0)
        {
            dbg(DBG_PRINT, "(GRADING2B) Error accessing dir_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(res_vnode);

        ret_val = lookup(res_vnode,name,namelen,&res_vnode);
        if(ret_val < 0)
        {
         dbg(DBG_PRINT, "(GRADING2B) Error in Lookup function\n");
         dbg(DBG_ERROR, "do_stat(): Error while returning from lookup()\n");
         return ret_val;
        }
        KASSERT(NULL != res_vnode->vn_ops->stat);
        dbg(DBG_PRINT, "(GRADING2A 3.f) do_stat(): function pointer to stat exists\n");
        vput(res_vnode);
        return res_vnode->vn_ops->stat(res_vnode,buf);
        
        /*NOT_YET_IMPLEMENTED("VFS: do_stat"); return -1;*/
}
Ejemplo n.º 21
0
/* This returns in res_vnode the vnode requested by the other parameters.
 * It makes use of dir_namev and lookup to find the specified vnode (if it
 * exists).  flag is right out of the parameters to open(2); see
 * <weenix/fcntl.h>.  If the O_CREAT flag is specified, and the file does
 * not exist call create() in the parent directory vnode.
 *
 * Note: Increments vnode refcount on *res_vnode.
 */
int
open_namev(const char *pathname, int flag, vnode_t **res_vnode, vnode_t *base)
{
		/* TODO: Kernel#2 open_namev done
        NOT_YET_IMPLEMENTED("VFS: open_namev done");
        */
	dbg(DBG_PRINT,"(GRADING2B)\n");
	size_t length;
	char *name;
	vnode_t *parentDir;
	int retval = dir_namev(pathname, &length, (const char**)&name, base, &parentDir);
	if(retval >= 0){
		dbg(DBG_PRINT,"(GRADING2B)\n");
		retval = lookup(parentDir, name, length, res_vnode);
		if(retval >= 0){/* found file, open successfully. */
			vput(parentDir);
			dbg(DBG_PRINT,"(GRADING2B)\n");
			return retval;
		}else{
			dbg(DBG_PRINT,"(GRADING2B)\n");
			if((retval == -ENOENT)){/* create file */
				dbg(DBG_PRINT,"(GRADING2B)\n");
				if(!(flag & O_CREAT)){
					dbg(DBG_PRINT,"(GRADING2B)\n");
					vput(parentDir);
					return -ENOENT;
				}
				if((retval == -ENOENT) && (flag & O_CREAT)){
					KASSERT(NULL != parentDir->vn_ops->create);
					dbg(DBG_PRINT,"(GRADING2A 2.c)\n");
					dbg(DBG_PRINT,"(GRADING2B)\n");
				}
				dbg(DBG_PRINT,"(GRADING2B)\n");
				retval = parentDir->vn_ops->create(parentDir, name, length, res_vnode);
				vput(parentDir);
				return retval;
			}else{/* failed */
				dbg(DBG_PRINT,"(GRADING2B)\n");
				vput(parentDir);
				return retval;
			}
		}
	}else{
		dbg(DBG_PRINT,"(GRADING2B)\n");
		return retval;
	}
}
Ejemplo n.º 22
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);
}
Ejemplo n.º 23
0
/* Use dir_namev() to find the vnode of the dir we want to make the new
 * directory in.  Then use lookup() to make sure it doesn't already exist.
 * Finally call the dir's mkdir vn_ops. Return what it returns.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mkdir(const char *path)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_mkdir");*/
        if (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        vnode_t *parent_vnode,*child_vnode;
        int parent_retVal,child_retVal;
        size_t namelen;
        const char *name;
    
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal) {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return parent_retVal;
        }
    
        child_retVal = lookup(parent_vnode,name,namelen,&child_vnode);
        if (!child_retVal){
            vput(parent_vnode);
            vput(child_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EEXIST;
        }
        else {
            if (child_retVal == -ENOENT){
                if (!S_ISDIR(parent_vnode->vn_mode)){
                    vput(parent_vnode);
                    return -ENOTDIR;
                }
            
                KASSERT(NULL != parent_vnode->vn_ops->mkdir);
                dbg(DBG_PRINT,"(GRADING2A 3.c)\n");
            
                vput(parent_vnode);
                return parent_vnode->vn_ops->mkdir(parent_vnode,name,namelen);
            }
        }
    
        dbg(DBG_PRINT,"(GRADING2B)\n");
        vput(parent_vnode);
        return child_retVal;
}
Ejemplo n.º 24
0
/* This returns in res_vnode the vnode requested by the other parameters.
 * It makes use of dir_namev and lookup to find the specified vnode (if it
 * exists).  flag is right out of the parameters to open(2); see
 * <weenix/fcntl.h>.  If the O_CREAT flag is specified, and the file does
 * not exist call create() in the parent directory vnode.
 *
 * Note: Increments vnode refcount on *res_vnode.
 */
int
open_namev(const char *pathname, int flag, vnode_t **res_vnode, vnode_t *base)
{
       /* NOT_YET_IMPLEMENTED("VFS: open_namev"); */
                
        const char *named = NULL;
        size_t len = 0;
        vnode_t *res_vnode1;
        int ret_val = dir_namev(pathname, &len,&named,base, &res_vnode1);
        
        if (ret_val != 0) 
        {
            dbg(DBG_ERROR, "dir not found\n");
                    dbg(DBG_PRINT,"(GRADING2B) dir not found \n");
            return ret_val;
        }
      
            int ret_val1 = lookup(res_vnode1,named,len,res_vnode);
            if (ret_val1 < 0) {
                              if (flag & O_CREAT) {

                               dbg(DBG_ERROR,"file not found but O_CREAT flag is on \n");
                    dbg(DBG_PRINT,"(GRADING2B) file not found but O_CREAT flag is on \n");
                            KASSERT(NULL != res_vnode1->vn_ops->create);
                            dbg(DBG_PRINT,"(GRADING2A 2.c) new file can be created\n");
                         
                            int ret_val2 = res_vnode1->vn_ops->create(res_vnode1,named,len,res_vnode);
                               if (ret_val2 < 0) {
                                    dbg(DBG_PRINT, "(GRADING2C) Cannot create the file\n");
                                    vput(res_vnode1);
                                    return ret_val2;
                                   }
                                    } else {
                                              dbg(DBG_PRINT, "(GRADING2B) Could not find the file  \n");
                                        vput(res_vnode1);
                                        return ret_val1;
                                    }    
                                }
                                  dbg(DBG_PRINT, "(GRADING2B) File with the given name alredy exists\n");
                                  vput(res_vnode1);  
                                  
                            return 0;  
}
Ejemplo n.º 25
0
/* Use dir_namev() to find the vnode of the directory containing the dir to be
 * removed. Then call the containing dir's rmdir v_op.  The rmdir v_op will
 * return an error if the dir to be removed does not exist or is not empty, so
 * you don't need to worry about that here. Return the value of the v_op,
 * or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        path has "." as its final component.
 *      o ENOTEMPTY
 *        path has ".." as its final component.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_rmdir(const char *path)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_rmdir");*/
        if (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        vnode_t *parent_vnode;
        int parent_retVal;
        size_t namelen;
        const char *name;
    
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal) {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return parent_retVal;
        }
    
        if (!strcmp(name,".")){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EINVAL;
        }
        if (!strcmp(name,"..")){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -ENOTEMPTY;
        }
    
        if (!S_ISDIR(parent_vnode->vn_mode)){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -ENOTDIR;
        }
    
        KASSERT(NULL != parent_vnode->vn_ops->rmdir);
        dbg(DBG_PRINT,"(GRADING2A 3.d)\n");
    
        vput(parent_vnode);
        return parent_vnode->vn_ops->rmdir(parent_vnode,name,namelen);
}
Ejemplo n.º 26
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 (strlen(path) > MAXPATHLEN){
            return -ENAMETOOLONG;
        }
    
        int parent_retVal,file_retVal,retVal;
        vnode_t *parent_vnode,*file_vnode;
        size_t namelen;
        const char *name;
    
        parent_retVal = dir_namev(path,&namelen,&name,NULL,&parent_vnode);
        if (parent_retVal){
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return parent_retVal;
        }
    
        file_retVal = lookup(parent_vnode,name,namelen,&file_vnode);
        if (file_retVal){
            vput(parent_vnode);
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return file_retVal;
        }
    
        dbg(DBG_PRINT,"(GRADING2A 3.f)\n");
        KASSERT(file_vnode->vn_ops->stat);
    
        retVal = file_vnode->vn_ops->stat(file_vnode,buf);
    
        vput(parent_vnode);
        vput(file_vnode);
    
        return retVal;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
/* Use dir_namev() to find the vnode of the directory containing the dir to be
 * removed. Then call the containing dir's rmdir v_op.  The rmdir v_op will
 * return an error if the dir to be removed does not exist or is not empty, so
 * you don't need to worry about that here. Return the value of the v_op,
 * or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        path has "." as its final component.
 *      o ENOTEMPTY
 *        path has ".." as its final component.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_rmdir(const char *path)
{
    /*NOT_YET_IMPLEMENTED("VFS: do_rmdir");
     return -1;*/
    if(strlen(path)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_rmkdir: ENAMETOOLONG. A component of path was too long.\n");
        return -ENAMETOOLONG;
    }
    if(path == NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_rmkdir: EINVAL. Mode requested creation of something other than a device special file.\n");
        return -EINVAL;
    }
    
    size_t namelen=0;
    const char *name=NULL;
    vnode_t *res_vnode;
    vnode_t *result;
    
    int i=dir_namev(path, &namelen,&name,NULL,&res_vnode);
    if(i<0)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        dbg(DBG_PRINT,"ERROR: do_rmkdir: Unable to resolve file path\n");
        return i;
    }
    if(strlen(name)>NAME_LEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT, "ERROR: do_rmkdir: A component of name was too long\n");
        vput(res_vnode);
        return -ENAMETOOLONG;
    }
    
    if(res_vnode==NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_rmkdir: A directory component in path does not exist.\n");
        return -ENOENT;
    }
    else
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        if(!S_ISDIR(res_vnode->vn_mode))
        {
            dbg(DBG_PRINT,"(GRADING2D)\n");

            dbg(DBG_PRINT,"ERROR: do_rmkdir:  A component used as a directory in path is not, in fact, a directory.\n");
            vput(res_vnode);
            return -ENOTDIR;
        }
    }
    
    if(strcmp(name,".")==0)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        dbg(DBG_PRINT,"ERROR: do_rmdir: Path has \'.\'as final component\n");
        vput(res_vnode);
        return -EINVAL;
    }
    if(strcmp(name,"..")==0)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        dbg(DBG_PRINT,"ERROR: do_rmdir: Path had \'..\' as final component\n");
        vput(res_vnode);
        return -ENOTEMPTY;
    }
    
    
    KASSERT(NULL!=res_vnode->vn_ops->rmdir);
    i=(res_vnode->vn_ops->rmdir)(res_vnode,name,namelen);
    vput(res_vnode);
    dbg(DBG_VFS,"Directory remove successful. Path=%s\n",path);
    return i;
}
Ejemplo n.º 29
0
/*
 * This routine creates a special file of the type specified by 'mode' at
 * the location specified by 'path'. 'mode' should be one of S_IFCHR or
 * S_IFBLK (you might note that mknod(2) normally allows one to create
 * regular files as well-- for simplicity this is not the case in Weenix).
 * 'devid', as you might expect, is the device identifier of the device
 * that the new special file should represent.
 *
 * You might use a combination of dir_namev, lookup, and the fs-specific
 * mknod (that is, the containing directory's 'mknod' vnode operation).
 * Return the result of the fs-specific mknod, or an error.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EINVAL
 *        mode requested creation of something other than a device special
 *        file.
 *      o EEXIST
 *        path already exists.
 *      o ENOENT
 *        A directory component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_mknod(const char *path, int mode, unsigned devid)
{
    /*NOT_YET_IMPLEMENTED("VFS: do_mknod");
     return -1;*/
    if(strlen(path)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_mknod: ENAMETOOLONG. A component of path was too long.\n");
        return -ENAMETOOLONG;
    }
    if(path == NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_mknod: EINVAL. Mode requested creation of something other than a device special file.\n");
        return -EINVAL;
    }
    if(mode!=S_IFCHR&&mode!=S_IFBLK)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_mknod: EINVAL. Invalid mode.Mode requested creation of something other than a device special file.\n");
        return -EINVAL;
    }
    size_t namelen=0;
    const char *name=NULL;
    vnode_t *res_vnode;
    vnode_t *result;
    int i=dir_namev(path, &namelen,&name,NULL,&res_vnode);
    if(i<0)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_mknod: Unable to resolve file path\n");
        return i;
    }
    if(strlen(name)>NAME_LEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT, "ERROR: do_mknod: A component of name was too long\n");
        vput(res_vnode);
        return -ENAMETOOLONG;
    }
    if(res_vnode==NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_mknod: A directory component in path does not exist.\n");
        return -ENOENT;
    }
    else
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        if(!S_ISDIR(res_vnode->vn_mode))
        {
            dbg(DBG_PRINT,"(GRADING2D)\n");

            dbg(DBG_PRINT,"ERROR: do_mknod:  A component used as a directory in path is not, in fact, a directory.\n");
            vput(res_vnode);
            return -ENOTDIR;
        }
    }
    
    if(name!=NULL)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");
        int j=lookup(res_vnode,name,namelen,&result);
        
        if(j==0)
        {
            dbg(DBG_PRINT,"(GRADING2D)\n");

            dbg(DBG_PRINT, "ERROR: do_mknod: Path already exists\n");
            vput(res_vnode);
            vput(result);
            return -EEXIST;
        }
    }
    vput(res_vnode);
    KASSERT(NULL!=res_vnode->vn_ops->mknod);
    dbg(DBG_PRINT,"(GRADING2A 3.b)\n");

    i=(res_vnode->vn_ops->mknod)(res_vnode,name,namelen,mode,devid);
    
    return i;
    
}
Ejemplo n.º 30
0
/*
 * Same as do_rmdir, but for files.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EISDIR
 *        path refers to a directory.
 *      o ENOENT
 *        A component in path does not exist.
 *      o ENOTDIR
 *        A component used as a directory in path is not, in fact, a directory.
 *      o ENAMETOOLONG
 *        A component of path was too long.
 */
int
do_unlink(const char *path)
{
    /*NOT_YET_IMPLEMENTED("VFS: do_unlink");
     return -1;*/
    if(strlen(path)>MAXPATHLEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: Path is too long\n");
        return -ENAMETOOLONG;
    }
    
    size_t namelen=0;
    const char *name=NULL;
    vnode_t *res_vnode;
    vnode_t *result;
    if(path == NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: missing operand\n");
        return -EINVAL;
    }
    int i=dir_namev(path, &namelen,&name,NULL,&res_vnode);
    if(i<0)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: Unable to resolve the path\n");
        return i;
    }
    if(res_vnode==NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: A component in path doesn't exist\n");
        return -ENOENT;
    }
    else
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        if(!S_ISDIR(res_vnode->vn_mode))
        {
            dbg(DBG_PRINT,"(GRADING2D)\n");

            dbg(DBG_PRINT,"ERROR: do_unlink: A component in the path is not directory\n");
            vput(res_vnode);
            return -ENOTDIR;
        }
    }
    if(strlen(name)>NAME_LEN)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT, "ERROR: do_unlink: A component of name was too long\n");
        vput(res_vnode);
        return -ENAMETOOLONG;
    }
    
    if(name!=NULL)
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        int j=lookup(res_vnode,name,namelen,&result);
        if(j!=0)
        {
            dbg(DBG_PRINT,"(GRADING2B)\n");

            dbg(DBG_PRINT,"ERROR: do_unlink: Lookup for final component in the path fails\n");
            vput(res_vnode);
            return j;
        }
    }
    if(result==NULL)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: Component in the path doesn't exist\n");
        vput(res_vnode);
        return -ENOENT;
    }
    
    if(S_ISDIR(result->vn_mode))
    {
        dbg(DBG_PRINT,"(GRADING2B)\n");

        dbg(DBG_PRINT,"ERROR: do_unlink: Path refers to a directory\n");
        vput(res_vnode);
        vput(result);
        return -EISDIR;
    }
    
    
    KASSERT(NULL!=res_vnode->vn_ops->unlink);
    dbg(DBG_PRINT,"(GRADING2A 3.e)\n");

    i=(res_vnode->vn_ops->unlink)(res_vnode,name,namelen);
    vput(res_vnode);
    vput(result);
    return i;
    
}