Example #1
0
static int write_sparse(int f,char *buf,size_t len)
{
	size_t l1=0, l2=0;
	int ret;

	for (l1=0;l1<len && buf[l1]==0;l1++) ;
	for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;

	last_byte = buf[len-1];

	if (l1 == len || l2 > 0)
		last_sparse=1;

	if (l1 > 0) {
		do_lseek(f,l1,SEEK_CUR);  
	}

	if (l1 == len) 
		return len;

	ret = write(f, buf + l1, len - (l1+l2));
	if (ret == -1 || ret == 0)
		return ret;
	else if (ret != (int) (len - (l1+l2))) 
		return (l1+ret);

	if (l2 > 0)
		do_lseek(f,l2,SEEK_CUR);
	
	return len;
}
Example #2
0
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int
do_write(int fd, const void *buf, size_t nbytes)
{
  file_t *temp;
  int bytes_write,errno;
  temp=fget(fd);
  /*Alekhya: Check if it is a valid file pointer*/
  if(temp==NULL)
    {

      dbg(DBG_PRINT,"(GRADING2B) Not a valid file descriptor, return -EBADF \n");
      return -EBADF;
    }

  /*Alekhya: Check if mode is write*/
  if((temp->f_mode & FMODE_WRITE)!=FMODE_WRITE)
    {
      fput(temp);
      dbg(DBG_PRINT,"(GRADING2B) Not for write, return -EBADF\n");
      return -EBADF;
    }
 
  /*Alekhya: If mode is append, push the pointer to the end of the file*/

  if((temp->f_mode & FMODE_APPEND)==FMODE_APPEND)
    {
        /*Im not sure what the offset is supposed to be*/
        dbg(DBG_PRINT,"(GRADING2B) The mode is append mode, changing it, updating f_pos\n");
      (void)do_lseek(fd,0,SEEK_END);/*take care as to change value of f_pos inside the do_lseek function itself*/
    } 
 
  /*Alekhya: calling its virtual write*/
  bytes_write=temp->f_vnode->vn_ops->write(temp->f_vnode,temp->f_pos,buf,nbytes);
  
  /*Not sure how to test this part, so removing it*/
  /*if(bytes_write<0)
    {
             dbg(DBG_PRINT,"(GRADING2C) (vfs_syscall.c) (do_write) Nothing has been written to file\n");
        fput(temp);
      return bytes_write;
      }*/
  KASSERT((S_ISCHR(temp->f_vnode->vn_mode)) || (S_ISBLK(temp->f_vnode->vn_mode)) || ((S_ISREG(temp->f_vnode->vn_mode)) && (temp->f_pos <= temp->f_vnode->vn_len)));

  dbg(DBG_PRINT,"(GRADING2A 3.a) (middle) if (/* write is successful */) KASSERT((S_ISCHR(f->f_vnode->vn_mode))||(S_ISBLK(f->f_vnode->vn_mode)) ||((S_ISREG(f->f_vnode->vn_mode)) && (f->f_pos <= f->f_vnode->vn_len)))");
  (void)do_lseek(fd,bytes_write,SEEK_CUR);
  fput(temp);
  return bytes_write;

/*      NOT_YET_IMPLEMENTED("VFS: do_write");*/
        
}
Example #3
0
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int do_write(int fd, const void *buf, size_t nbytes) {
	/* NOT_YET_IMPLEMENTED("VFS: do_write");*/
	if (fd < 0 || fd >= NFILES) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return -EBADF;
	}
	file_t* file = fget(fd);

	if (file == NULL) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return -EBADF;
	}

	if (!(file->f_mode & FMODE_WRITE) && !(file->f_mode & FMODE_APPEND)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		fput(file);
		return -EBADF;
	}

	int bytes;

	if (file->f_mode & FMODE_APPEND) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		do_lseek(fd, 0, SEEK_END);
		bytes = file->f_vnode->vn_ops->write(file->f_vnode, file->f_pos, buf,
				nbytes);
		if (0 != bytes) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			KASSERT(
					(S_ISCHR(file->f_vnode->vn_mode)) || (S_ISBLK(file->f_vnode->vn_mode)) || ((S_ISREG(file->f_vnode->vn_mode)) && (file->f_pos <= file->f_vnode->vn_len)));
			dbg(DBG_PRINT, "(GRADING2A 3.a)\n");
		}
		do_lseek(fd, bytes, SEEK_CUR);
		fput(file);
	} else if (file->f_mode & FMODE_WRITE) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		bytes = file->f_vnode->vn_ops->write(file->f_vnode, file->f_pos, buf,
				nbytes);
		if (0 != bytes) {
			dbg(DBG_PRINT, "(GRADING2B)\n");
			KASSERT(
					(S_ISCHR(file->f_vnode->vn_mode)) || (S_ISBLK(file->f_vnode->vn_mode)) || ((S_ISREG(file->f_vnode->vn_mode)) && (file->f_pos <= file->f_vnode->vn_len)));
			dbg(DBG_PRINT, "(GRADING2A 3.a)\n");
		}
		do_lseek(fd, bytes, SEEK_CUR);
		fput(file);
	}
	dbg(DBG_PRINT, "(GRADING2B)\n");
	return bytes;

}
Example #4
0
/* To read a file:
 *      o fget(fd)
 *      o call its virtual read fs_op
 *      o update f_pos
 *      o fput() it
 *      o return the number of bytes read, or an error
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for reading.
 *      o EISDIR
 *        fd refers to a directory.
 *
 * In all cases, be sure you do not leak file refcounts by returning before
 * you fput() a file that you fget()'ed.
 */
int do_read(int fd, void *buf, size_t nbytes) {
	/*NOT_YET_IMPLEMENTED("VFS: do_read");*/
	if (fd < 0 || fd >= NFILES) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return -EBADF;
	}
	file_t* file = fget(fd);

	if (file == NULL) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		return -EBADF;
	}

	if (!(file->f_mode & FMODE_READ)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		fput(file);
		return -EBADF;
	}

	if (S_ISDIR(file->f_vnode->vn_mode)) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		fput(file);
		return -EISDIR;
	}

	int bytes = file->f_vnode->vn_ops->read(file->f_vnode, file->f_pos, buf,
			nbytes);
	if (bytes == (int) nbytes) {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		do_lseek(fd, bytes, SEEK_CUR);
	} /*else if (bytes < 0) {
	 dbg(DBG_ERROR, "5\n");
	 fput(file);
	 return bytes;
	 } */else {
		dbg(DBG_PRINT, "(GRADING2B)\n");
		do_lseek(fd, 0, SEEK_END);
	}
	/*
	 if(bytes==nbytes){
	 do_lseek(fd,bytes,SEEK_CUR);
	 }
	 if(nbytes>bytes){
	 bytes=0;
	 }
	 */
	dbg(DBG_PRINT, "(GRADING2B)\n");
	fput(file);
	return bytes;
}
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int
do_write(int fd, const void *buf, size_t nbytes)
{
        file_t *return_file;
        unsigned int write_return;
        /*NOT_YET_IMPLEMENTED("VFS: do_write");*/
        if (fd < 0) {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EBADF;
        }
        else
        {
            return_file = fget(fd);
            if(return_file == NULL) {
                dbg(DBG_PRINT,"(GRADING2B)\n");
                return -EBADF;
            }
            
            else if(!(return_file->f_mode & FMODE_WRITE)&&!(return_file->f_mode & FMODE_APPEND))
            {
                dbg(DBG_PRINT,"(GRADING2B)\n");
                fput(return_file);
                return -EBADF;
            }
            if(S_ISDIR(return_file->f_vnode->vn_mode))
            {
                fput(return_file);
                return -EISDIR;
            }
            else if(return_file->f_mode & FMODE_APPEND){
                dbg(DBG_PRINT,"(GRADING2B)\n");
                do_lseek(fd,0,SEEK_END);
            }
        
            write_return = return_file->f_vnode->vn_ops->write(return_file->f_vnode,return_file->f_pos,buf,nbytes);
            dbg(DBG_PRINT,"(GRADING2B)\n");
        
            if(write_return == nbytes)
            {
                KASSERT((S_ISCHR(return_file->f_vnode->vn_mode)) || (S_ISBLK(return_file->f_vnode->vn_mode)) ||
                        ((S_ISREG(return_file->f_vnode->vn_mode)) && (return_file->f_pos <= return_file->f_vnode->vn_len)));
                dbg(DBG_PRINT, "(GRADING2A 3.a)\n");
            }
            do_lseek(fd,write_return,SEEK_CUR);
        
            fput(return_file);
        
            return write_return;
        }
}
/* Write a sparse file, specifically one that has FILE_CONTENT starting at byte
 * 50000 and no other data.  The size will be 50000+CONTENT_LEN, but only one
 * block is allocated to the file.
 */
int faber_sparse_test(kshell_t *ksh, int argc, char **argv) {
        KASSERT(NULL != ksh);
        KASSERT(NULL != argv);

	int f = -1;	/* file descriptor */
	int rv = 0;	/* Return value */

	/* Open the file, and create it if not present */
	if ( (f = do_open("/sparse", O_WRONLY | O_CREAT)) < 0) {
	    kprintf(ksh, "Couldn't open /sparse\n");
	    return -1;
	}

	/* Seek out 50000 bytes (the seek pointer is in the VFS layer, so the
	 * s5fs layer will just see a write at byte 50000 later) */
	if ( (rv = do_lseek(f, 50000, SEEK_END)) != 50000 ) {
	    do_close(f);
	    kprintf(ksh, "seek failed %d\n", rv);
	    return -1;
	}

	/* Write the visible bytes.  Here's where the first memory/disk block
	 * is allocated. */
	if ( do_write(f, FILE_CONTENT, CONTENT_LEN) != CONTENT_LEN) {
	    do_close(f);
	    kprintf(ksh, "File write failed?\n");
	    return -1;
	}

	/* Close up and go home */
	do_close(f);
	kprintf(ksh, "Created sparse file \"/sparse\"\n");
	return 0;
}
Example #7
0
static int write_sparse(int f, char *buf, int len)
{
	int l1 = 0, l2 = 0;
	int ret;

	for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
	for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}

	sparse_seek += l1;

	if (l1 == len)
		return len;

	if (sparse_seek)
		do_lseek(f, sparse_seek, SEEK_CUR);
	sparse_seek = l2;

	while ((ret = fadv_write(f, buf + l1, len - (l1+l2))) <= 0) {
		if (ret < 0 && errno == EINTR)
			continue;
		sparse_seek = 0;
		return ret;
	}

	if (ret != (int)(len - (l1+l2))) {
		sparse_seek = 0;
		return l1+ret;
	}

	return len;
}
Example #8
0
int sparse_end(int f, OFF_T size)
{
	int ret;

	if (!sparse_seek)
		return 0;

#ifdef HAVE_FTRUNCATE
	ret = do_ftruncate(f, size);
#else
	if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
		ret = -1;
	else {
		do {
			ret = write(f, "", 1);
		} while (ret < 0 && errno == EINTR);

		ret = ret <= 0 ? -1 : 0;
	}
#endif

	sparse_seek = 0;

	return ret;
}
Example #9
0
static uint32_t nand_dev_read_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
{
    uint32_t len = total_len;
    size_t read_len = dev->erase_size;
    int eof = 0;

    NAND_UPDATE_READ_THRESHOLD(total_len);

    do_lseek(dev->fd, addr, SEEK_SET);
    while(len > 0) {
        if(read_len < dev->erase_size) {
            memset(dev->data, 0xff, dev->erase_size);
            read_len = dev->erase_size;
            eof = 1;
        }
        if(len < read_len)
            read_len = len;
        if(!eof) {
            read_len = do_read(dev->fd, dev->data, read_len);
        }
#ifdef TARGET_I386
        if (kvm_enabled())
            cpu_synchronize_state(cpu_single_env, 0);
#endif
        cpu_memory_rw_debug(cpu_single_env, data, dev->data, read_len, 1);
        data += read_len;
        len -= read_len;
    }
    return total_len;
}
Example #10
0
static int write_sparse(int f, char *buf, int len)
{
    int l1 = 0, l2 = 0;
    int ret;

    for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
    for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}

    /* XXX Riddle me this: why does this function SLOW DOWN when I
     * remove the following (unneeded) line?? Core Duo weirdness? */
    last_byte = buf[len-1];

    sparse_seek += l1;

    if (l1 == len)
        return len;

    if (sparse_seek)
        do_lseek(f, sparse_seek, SEEK_CUR);
    sparse_seek = l2;

    while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
        if (ret < 0 && errno == EINTR)
            continue;
        return ret;
    }

    if (ret != (int)(len - (l1+l2)))
        return l1+ret;

    return len;
}
Example #11
0
static uint32_t nand_dev_write_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
{
    uint32_t len = total_len;
    size_t write_len = dev->erase_size;
    int ret;

    NAND_UPDATE_WRITE_THRESHOLD(total_len);

    do_lseek(dev->fd, addr, SEEK_SET);
    while(len > 0) {
        if(len < write_len)
            write_len = len;
#ifdef TARGET_I386
        if (kvm_enabled())
                cpu_synchronize_state(cpu_single_env, 0);
#endif
        cpu_memory_rw_debug(cpu_single_env, data, dev->data, write_len, 0);
        ret = do_write(dev->fd, dev->data, write_len);
        if(ret < write_len) {
            XLOG("nand_dev_write_file, write failed: %s\n", strerror(errno));
            break;
        }
        data += write_len;
        len -= write_len;
    }
    return total_len - len;
}
Example #12
0
static uint32_t nand_dev_erase_file(nand_dev *dev, uint64_t addr, uint32_t total_len)
{
    uint32_t len = total_len;
    size_t write_len = dev->erase_size;
    int ret;

#if !defined(ANDROID_QCOW)
    do_lseek(dev->fd, addr, SEEK_SET);
#endif

    memset(dev->data, 0xff, dev->erase_size);
    while(len > 0) {
        if(len < write_len)
            write_len = len;
#if defined(ANDROID_QCOW)
        ret = bdrv_pwrite(dev->bdrv, addr, dev->data, write_len);
#else
        ret = do_write(dev->fd, dev->data, write_len);
#endif
        if(ret < write_len) {
            XLOG( "nand_dev_write_file, write failed: %s\n", strerror(errno));
            break;
        }
        len -= write_len;
        addr += write_len;
    }
    return total_len - len;
}
Example #13
0
/* Note that the offset is just the caller letting us know where
 * the current file position is in the file. The use_seek arg tells
 * us that we should seek over matching data instead of writing it. */
static int write_sparse(int f, int use_seek, OFF_T offset, const char *buf, int len)
{
	int l1 = 0, l2 = 0;
	int ret;

	for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
	for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}

	sparse_seek += l1;

	if (l1 == len)
		return len;

	if (sparse_seek) {
		if (sparse_past_write >= preallocated_len) {
			if (do_lseek(f, sparse_seek, SEEK_CUR) < 0)
				return -1;
		} else if (do_punch_hole(f, sparse_past_write, sparse_seek) < 0) {
			sparse_seek = 0;
			return -1;
		}
	}
	sparse_seek = l2;
	sparse_past_write = offset + len - l2;

	if (use_seek) {
		/* The in-place data already matches. */
		if (do_lseek(f, len - (l1+l2), SEEK_CUR) < 0)
			return -1;
		return len;
	}

	while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
		if (ret < 0 && errno == EINTR)
			continue;
		sparse_seek = 0;
		return ret;
	}

	if (ret != (int)(len - (l1+l2))) {
		sparse_seek = 0;
		return l1+ret;
	}

	return len;
}
/* To read a file:
 *      o fget(fd)
 *      o call its virtual read fs_op
 *      o update f_pos
 *      o fput() it
 *      o return the number of bytes read, or an error
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for reading.
 *      o EISDIR
 *        fd refers to a directory.
 *
 * In all cases, be sure you do not leak file refcounts by returning before
 * you fput() a file that you fget()'ed.
 */
int
do_read(int fd, void *buf, size_t nbytes)
{
        file_t *return_file;
        unsigned int read_return;
        /*NOT_YET_IMPLEMENTED("VFS: do_read");*/
        if (fd < 0){
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EBADF;
        }
        else
        {
            return_file = fget(fd);
            if(return_file == NULL){
                dbg(DBG_PRINT,"(GRADING2B)\n");
                return -EBADF;
            }
            else if (!(return_file->f_mode & FMODE_READ))
            {
                dbg(DBG_PRINT,"(GRADING2B)\n");
                fput(return_file);
                return -EBADF;
            }
            else if(S_ISDIR(return_file->f_vnode->vn_mode))
            {
                dbg(DBG_PRINT,"(GRADING2B)\n");
                fput(return_file);
                return -EISDIR;
            }
            dbg(DBG_PRINT,"(GRADING2B)\n");
            read_return = return_file->f_vnode->vn_ops->read(return_file->f_vnode,return_file->f_pos,buf,nbytes);
        
            if(read_return == nbytes){
                dbg(DBG_PRINT,"(GRADING2B)\n");
                do_lseek(fd,nbytes,SEEK_CUR);
            }
            else{
                dbg(DBG_PRINT,"(GRADING2B)\n");
                do_lseek(fd,0,SEEK_END);
            }
        
            fput(return_file);
            return read_return;
        }
}
Example #15
0
int sparse_end(int f)
{
	if (last_sparse) {
		do_lseek(f,-1,SEEK_CUR);
		return (write(f,&last_byte,1) == 1 ? 0 : -1);
	}
	last_sparse = 0;
	return 0;
}
Example #16
0
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int
do_write(int fd, const void *buf, size_t nbytes)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_write");
        */

        int writebytes;
        /*dbg(DBG_PRINT,"Entering do_write ****************************************\n");
        */
        file_t *f = fget(fd);
        if (NULL == f)
        {
          /*dbg(DBG_PRINT,"EBADF Leaving do_write ****************************************\n");
          */
          dbg(DBG_PRINT,"(GRADING2C)\n");
          return -EBADF;
        }
       if ((f->f_mode & FMODE_WRITE) == FMODE_WRITE)
       {
         dbg(DBG_PRINT,"(GRADING2C)\n");

           if ((f->f_mode & FMODE_APPEND) == FMODE_APPEND)
           {
             dbg(DBG_PRINT,"(GRADING2C)\n");
             do_lseek(fd,0,SEEK_END);
           }
           writebytes = f->f_vnode->vn_ops->write(f->f_vnode,f->f_pos,buf,nbytes);
           if(writebytes >= 0){

           KASSERT((S_ISCHR(f->f_vnode->vn_mode)) || (S_ISBLK(f->f_vnode->vn_mode)) || ((S_ISREG(f->f_vnode->vn_mode)) && (f->f_pos <= f->f_vnode->vn_len)));
           dbg(DBG_PRINT,"\n(GRADING2A 3.a)\n");

           f->f_pos = f->f_pos + (off_t)writebytes;
           }



           fput(f);

           /*dbg(DBG_PRINT,"Leaving do_write ****************************************\n");
           */
           return writebytes;

       }
       else
       {

                fput(f);
                /*dbg(DBG_PRINT,"EBADF Leaving do_write ****************************************\n");
                */
                dbg(DBG_PRINT,"(GRADING2C)\n");
                return -EBADF;

       }

}
Example #17
0
/**
 * Copies the current contents of a disk image into the snapshot file.
 *
 * TODO optimize this using some kind of copy-on-write mechanism for
 *      unchanged disk sections.
 */
static void  nand_dev_save_disk_state(QEMUFile *f, nand_dev *dev)
{
#ifndef ANDROID_QCOW
    int buf_size = NAND_DEV_SAVE_DISK_BUF_SIZE;
    uint8_t buffer[NAND_DEV_SAVE_DISK_BUF_SIZE] = {0};
    int ret;
    uint64_t total_copied = 0;

    /* Size of file to restore, hence size of data block following.
     * TODO Work out whether to use lseek64 here. */

    ret = do_lseek(dev->fd, 0, SEEK_END);
    if (ret < 0) {
        XLOG("%s EOF seek failed: %s\n", __FUNCTION__, strerror(errno));
        qemu_file_set_error(f);
        return;
    }
    const uint64_t total_size = ret;
    qemu_put_be64(f, total_size);

    /* copy all data from the stream to the stored image */
    ret = do_lseek(dev->fd, 0, SEEK_SET);
    if (ret < 0) {
        XLOG("%s seek failed: %s\n", __FUNCTION__, strerror(errno));
        qemu_file_set_error(f);
        return;
    }
    do {
        ret = do_read(dev->fd, buffer, buf_size);
        if (ret < 0) {
            XLOG("%s read failed: %s\n", __FUNCTION__, strerror(errno));
            qemu_file_set_error(f);
            return;
        }
        qemu_put_buffer(f, buffer, ret);

        total_copied += ret;
    }
    while (ret == buf_size && total_copied < dev->max_size);

    /* TODO Maybe check that we've written total_size bytes */
#endif
}
Example #18
0
/**
 * Overwrites the contents of the disk image managed by this device with the
 * contents as they were at the point the snapshot was made.
 */
static int  nand_dev_load_disk_state(QEMUFile *f, nand_dev *dev)
{
#ifndef ANDROID_QCOW
    int buf_size = NAND_DEV_SAVE_DISK_BUF_SIZE;
    uint8_t buffer[NAND_DEV_SAVE_DISK_BUF_SIZE] = {0};
    int ret;

    /* File size for restore and truncate */
    uint64_t total_size = qemu_get_be64(f);
    if (total_size > dev->max_size) {
        XLOG("%s, restore failed: size required (%lld) exceeds device limit (%lld)\n",
             __FUNCTION__, total_size, dev->max_size);
        return -EIO;
    }

    /* overwrite disk contents with snapshot contents */
    uint64_t next_offset = 0;
    ret = do_lseek(dev->fd, 0, SEEK_SET);
    if (ret < 0) {
        XLOG("%s seek failed: %s\n", __FUNCTION__, strerror(errno));
        return -EIO;
    }
    while (next_offset < total_size) {
        /* snapshot buffer may not be an exact multiple of buf_size
         * if necessary, adjust buffer size for last copy operation */
        if (total_size - next_offset < buf_size) {
            buf_size = total_size - next_offset;
        }

        ret = qemu_get_buffer(f, buffer, buf_size);
        if (ret != buf_size) {
            XLOG("%s read failed: expected %d bytes but got %d\n",
                 __FUNCTION__, buf_size, ret);
            return -EIO;
        }
        ret = do_write(dev->fd, buffer, buf_size);
        if (ret != buf_size) {
            XLOG("%s, write failed: %s\n", __FUNCTION__, strerror(errno));
            return -EIO;
        }

        next_offset += buf_size;
    }

    ret = do_ftruncate(dev->fd, total_size);
    if (ret < 0) {
        XLOG("%s ftruncate failed: %s\n", __FUNCTION__, strerror(errno));
        return -EIO;
    }
#endif

    return 0;
}
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int
do_write(int fd, const void *buf, size_t nbytes)
{
	 if(fd>=NFILES||fd<0||curproc->p_files[fd]==NULL){
		dbg(DBG_PRINT, "fd is not a valid file descriptor or is not open for reading\n");
		return -EBADF;
	}
        file_t *reqFile;
        reqFile=fget(fd);  
        
        if(reqFile==NULL || reqFile->f_mode==1)   /* f_mode=1 means only read access, no write and no append also! */
        {
        	dbg(DBG_PRINT, "fd is not a valid file descriptor or is not open for reading\n");
          if(reqFile!=NULL) { fput(reqFile); }
          return -EBADF;
        }

        /*if(S_ISDIR(reqFile->f_vnode->vn_mode))   
        {
        dbg(DBG_PRINT, "fd is not a valid file descriptor or is not open for reading\n");
          fput(reqFile);  
          return -EISDIR;
        }*/
        
        /*if (reqFile->f_mode & O_APPEND)*/   /* We need to append buf to end of the file */
        if(reqFile->f_mode == (FMODE_WRITE|FMODE_READ|FMODE_APPEND) )
        {
           int lseekReturnCode = do_lseek(fd,0,SEEK_END);
	   /*if(lseekReturnCode < 0)
           {
             return lseekReturnCode; 
           }*/
        }

	int bytesWritten= reqFile->f_vnode->vn_ops->write( reqFile->f_vnode, reqFile->f_pos, buf, nbytes );

        /*if(bytesWritten<0)
        {
          dbg(DBG_PRINT," Bytes read less than zero.\n"); 
          fput(reqFile);
          return bytesWritten;
        }*/

        reqFile->f_pos+=bytesWritten;
        KASSERT( (S_ISCHR(reqFile->f_vnode->vn_mode)) ||
                                         (S_ISBLK(reqFile->f_vnode->vn_mode)) ||
                                         ((S_ISREG(reqFile->f_vnode->vn_mode)) && (reqFile->f_pos <= reqFile->f_vnode->vn_len)) );
        dbg(DBG_PRINT, "(GRADING2A 3.a): Succesfully wrote to file\n");
        
        fput(reqFile);
        return bytesWritten;
}
Example #20
0
int sparse_end(int f)
{
    int ret;

    if (!sparse_seek)
        return 0;

    do_lseek(f, sparse_seek-1, SEEK_CUR);
    sparse_seek = 0;

    do {
        ret = write(f, "", 1);
    } while (ret < 0 && errno == EINTR);

    return ret <= 0 ? -1 : 0;
}
Example #21
0
static int sys_lseek(lseek_args_t *args)
{
    lseek_args_t            kargs;
    int                     err;
    
    if ((err = copy_from_user(&kargs, args, sizeof(lseek_args_t))) < 0) {
        curthr->kt_errno = -err;
        return -1;
    }
    
    err = do_lseek(kargs.fd, kargs.offset, kargs.whence);
    
    if (err < 0) {
        curthr->kt_errno = -err;
        return -1;
    } else return err;
}
Example #22
0
/* Very similar to do_read.  Check f_mode to be sure the file is writable.  If
 * f_mode & FMODE_APPEND, do_lseek() to the end of the file, call the write
 * fs_op, and fput the file.  As always, be mindful of refcount leaks.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for writing.
 */
int
do_write(int fd, const void *buf, size_t nbytes)
{
        file_t *f;
        int bytes_written = 0;
        f=fget(fd);
        if(f == NULL || curproc->p_files[fd] == NULL)
        {
          dbg(DBG_PRINT,"(GRADING2B) given file descriptor is not valid\n");
          dbg(DBG_ERROR,"do_write(): fd is not a valid file descriptor\n");
          return -EBADF;
        }

        if((f->f_mode & FMODE_WRITE) == FMODE_WRITE)
        {
                dbg(DBG_PRINT,"(GRADING2B) The given file has write permission\n");

            if( (f->f_mode & FMODE_APPEND) == FMODE_APPEND)
        {
                dbg(DBG_PRINT,"(GRADING2B) data can be appended to the file\n");
            int pos = f->f_pos;
        f->f_pos = do_lseek(fd,0,SEEK_END); 
        } 
        bytes_written=f->f_vnode->vn_ops->write(f->f_vnode,f->f_pos,buf,nbytes);      
        }

        else
        {
        fput(f);
        dbg(DBG_PRINT,"(GRADING2B) The given file is not open for writing\n");
        dbg(DBG_ERROR,"do_write(): fd is not open for writing.\n");
        return -EBADF;
        }

        if(bytes_written > 0)
        {
        KASSERT((S_ISCHR(f->f_vnode->vn_mode)) || (S_ISBLK(f->f_vnode->vn_mode)) ||((S_ISREG(f->f_vnode->vn_mode)) && (f->f_pos <= f->f_vnode->vn_len)));
        dbg(DBG_PRINT,"(GRADING2A 3.a) A character special CHR or block BLK or REG write is successful \n");
        f->f_pos = f->f_pos + bytes_written;
        }
        fput(f);
        return bytes_written;
        /*NOT_YET_IMPLEMENTED("VFS: do_write");*/
        
}
Example #23
0
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
	struct file *file;

	if (fd > NR_OPEN || !(file = (CURRENT_TASK() )->file[fd]))
		return -EBADF;

	switch (cmd) {
		case F_DUPFD:
			return dupfd(fd, arg);
		case F_SEEKSET:
		case F_SEEKCUR:
		case F_SEEKEND:
			return do_lseek(file, arg, cmd);
		default:
			return -EIO;
	}
}
Example #24
0
static uint32_t nand_dev_erase_file(nand_dev *dev, uint64_t addr, uint32_t total_len)
{
    uint32_t len = total_len;
    size_t write_len = dev->erase_size;
    int ret;

    do_lseek(dev->fd, addr, SEEK_SET);
    memset(dev->data, 0xff, dev->erase_size);
    while(len > 0) {
        if(len < write_len)
            write_len = len;
        ret = do_write(dev->fd, dev->data, write_len);
        if(ret < write_len) {
            XLOG( "nand_dev_write_file, write failed: %s\n", strerror(errno));
            break;
        }
        len -= write_len;
    }
    return total_len - len;
}
Example #25
0
/* To read a file:
 *      o fget(fd)
 *      o call its virtual read fs_op
 *      o update f_pos
 *      o fput() it
 *      o return the number of bytes read, or an error
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        fd is not a valid file descriptor or is not open for reading.
 *      o EISDIR
 *        fd refers to a directory.
 *
 * In all cases, be sure you do not leak file refcounts by returning before
 * you fput() a file that you fget()'ed.
 */
int
do_read(int fd, void *buf, size_t nbytes)
{
  file_t *temp;
  temp=fget(fd);
  int bytes_read;
  /*Alekhya: Check if points to valid location*/
  if(temp==NULL)
    {
      dbg(DBG_PRINT,"(GRADING2B) the file descriptor does not exist EBADF error\n");
      return -EBADF;
    }

  /*Akekhya: Check if in read mode*/
  if((temp->f_mode & FMODE_READ)!=FMODE_READ)
    {
      fput(temp);
      dbg(DBG_PRINT,"(GRADING2B) The file mode is Not read return -EBADF \n");
      return -EBADF;
    }

  /*Alekhya: Check if directory*/
  /*not sure if this is how its checked*/
  if(S_ISDIR(temp->f_vnode->vn_mode))
    {
      fput(temp);
      dbg(DBG_PRINT,"(GRADING2B)  The file Is a directory, Cannot read from directory\n");
      return -EISDIR;
    }
  
  /*Alekhya: Calling its virtual read*/
  bytes_read=temp->f_vnode->vn_ops->read(temp->f_vnode,temp->f_pos,buf,nbytes);
  /*Alekhya: update f_pos: which is the current position in the file.Type: off_t*/
  do_lseek(fd,bytes_read,SEEK_CUR);/*Not sure if this is what they mean by updating it*/
  
  fput(temp);
  /* NOT_YET_IMPLEMENTED("VFS: do_read");*/
  
  /*Alekhya: returning the number of bytes read*/
  return bytes_read;
}
Example #26
0
/* Loads the program header tables from from the ELF file specified by
 * the open file descriptor fd. header should point to the header information
 * for that ELF file. pht is a buffer of size size. It must be large enough
 * to hold the program header tables (whose size can be determined from
 * the ELF header).
 *
 * Returns 0 on success or -errno on error. */
static int _elf32_load_phtable(int fd, Elf32_Ehdr *header, char *pht, size_t size)
{
        int err = 0;
        size_t phtsize = header->e_phentsize * header->e_phnum;
        KASSERT(phtsize <= size);
        if (0 > (err = do_lseek(fd, header->e_phoff, SEEK_SET))) {
                goto done;
        }
        if (0 > (err = do_read(fd, pht, phtsize))) {
                goto done;
        }
        KASSERT(err <= (int)phtsize);
        if (err < (int)phtsize) {
                err = -ENOEXEC;
                goto done;
        }

        err = 0;
done:
        return err;
}
/* Call the readdir fs_op on the given fd, filling in the given dirent_t*.
 * If the readdir fs_op is successful, it will return a positive value which
 * is the number of bytes copied to the dirent_t.  You need to increment the
 * file_t's f_pos by this amount.  As always, be aware of refcounts, check
 * the return value of the fget and the virtual function, and be sure the
 * virtual function exists (is not null) before calling it.
 *
 * Return either 0 or sizeof(dirent_t), or -errno.
 *
 * Error cases you must handle for this function at the VFS level:
 *      o EBADF
 *        Invalid file descriptor fd.
 *      o ENOTDIR
 *        File descriptor does not refer to a directory.
 */
int
do_getdent(int fd, struct dirent *dirp)
{
        /*TOCHECK: TODO: not considered when readdir returns -ve */
        file_t *file;
        int ret_val;
        if (fd < 0) {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EBADF;
        }
        file = fget(fd);
        if (file == NULL) {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            return -EBADF;
        }
        if(S_ISDIR(file->f_vnode->vn_mode))
        {
            ret_val = file->f_vnode->vn_ops->readdir(file->f_vnode,file->f_pos,dirp);
            if (ret_val <= 0)
            {
                dbg(DBG_PRINT,"(GRADING2B)\n");
                fput(file);
                return ret_val;
            }
        
            dbg(DBG_PRINT,"(GRADING2B)\n");
            do_lseek(fd,ret_val,SEEK_CUR);
            fput(file);
            return sizeof(*dirp);
        }
        else
        {
            dbg(DBG_PRINT,"(GRADING2B)\n");
            fput(file);
            return -ENOTDIR;
        }
    
        /*NOT_YET_IMPLEMENTED("VFS: do_getdent");*/
}
Example #28
0
void nand_add_dev(const char *arg)
{
    uint64_t dev_size = 0;
    const char *next_arg;
    const char *value;
    size_t arg_len, value_len;
    nand_dev *new_devs, *dev;
    char *devname = NULL;
    size_t devname_len = 0;
    char *initfilename = NULL;
    char *rwfilename = NULL;
    int initfd = -1;
    int rwfd = -1;
    int read_only = 0;
    int pad;
    ssize_t read_size;
    uint32_t page_size = 2048;
    uint32_t extra_size = 64;
    uint32_t erase_pages = 64;

    VERBOSE_PRINT(init, "%s: %s", __FUNCTION__, arg);

    while(arg) {
        next_arg = strchr(arg, ',');
        value = strchr(arg, '=');
        if(next_arg != NULL) {
            arg_len = next_arg - arg;
            next_arg++;
            if(value >= next_arg)
                value = NULL;
        }
        else
            arg_len = strlen(arg);
        if(value != NULL) {
            size_t new_arg_len = value - arg;
            value_len = arg_len - new_arg_len - 1;
            arg_len = new_arg_len;
            value++;
        }
        else
            value_len = 0;

        if(devname == NULL) {
            if(value != NULL)
                goto bad_arg_and_value;
            devname_len = arg_len;
            devname = malloc(arg_len+1);
            if(devname == NULL)
                goto out_of_memory;
            memcpy(devname, arg, arg_len);
            devname[arg_len] = 0;
        }
        else if(value == NULL) {
            if(arg_match("readonly", arg, arg_len)) {
                read_only = 1;
            }
            else {
                XLOG("bad arg: %.*s\n", arg_len, arg);
                exit(1);
            }
        }
        else {
            if(arg_match("size", arg, arg_len)) {
                char *ep;
                dev_size = strtoull(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("pagesize", arg, arg_len)) {
                char *ep;
                page_size = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("extrasize", arg, arg_len)) {
                char *ep;
                extra_size = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("erasepages", arg, arg_len)) {
                char *ep;
                erase_pages = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("initfile", arg, arg_len)) {
                initfilename = malloc(value_len + 1);
                if(initfilename == NULL)
                    goto out_of_memory;
                memcpy(initfilename, value, value_len);
                initfilename[value_len] = '\0';
            }
            else if(arg_match("file", arg, arg_len)) {
                rwfilename = malloc(value_len + 1);
                if(rwfilename == NULL)
                    goto out_of_memory;
                memcpy(rwfilename, value, value_len);
                rwfilename[value_len] = '\0';
            }
            else {
                goto bad_arg_and_value;
            }
        }

        arg = next_arg;
    }

    if (rwfilename == NULL) {
        /* we create a temporary file to store everything */
        TempFile*    tmp = tempfile_create();

        if (tmp == NULL) {
            XLOG("could not create temp file for %.*s NAND disk image: %s\n",
                  devname_len, devname, strerror(errno));
            exit(1);
        }
        rwfilename = (char*) tempfile_path(tmp);
        if (VERBOSE_CHECK(init))
            dprint( "mapping '%.*s' NAND image to %s", devname_len, devname, rwfilename);
    }

    if(rwfilename) {
        if (initfilename) {
            /* Overwrite with content of the 'initfilename'. */
            if (read_only) {
                /* Cannot be readonly when initializing the device from another file. */
                XLOG("incompatible read only option is requested while initializing %.*s from %s\n",
                     devname_len, devname, initfilename);
                exit(1);
            }
            rwfd = open(rwfilename, O_BINARY | O_TRUNC | O_RDWR);
        } else {
            rwfd = open(rwfilename, O_BINARY | (read_only ? O_RDONLY : O_RDWR));
        }
        if(rwfd < 0) {
            XLOG("could not open file %s, %s\n", rwfilename, strerror(errno));
            exit(1);
        }
        /* this could be a writable temporary file. use atexit_close_fd to ensure
         * that it is properly cleaned up at exit on Win32
         */
        if (!read_only)
            atexit_close_fd(rwfd);
    }

    if(initfilename) {
        initfd = open(initfilename, O_BINARY | O_RDONLY);
        if(initfd < 0) {
            XLOG("could not open file %s, %s\n", initfilename, strerror(errno));
            exit(1);
        }
        if(dev_size == 0) {
            dev_size = do_lseek(initfd, 0, SEEK_END);
            do_lseek(initfd, 0, SEEK_SET);
        }
    }

    new_devs = realloc(nand_devs, sizeof(nand_devs[0]) * (nand_dev_count + 1));
    if(new_devs == NULL)
        goto out_of_memory;
    nand_devs = new_devs;
    dev = &new_devs[nand_dev_count];

    dev->page_size = page_size;
    dev->extra_size = extra_size;
    dev->erase_size = erase_pages * (page_size + extra_size);
    pad = dev_size % dev->erase_size;
    if (pad != 0) {
        dev_size += (dev->erase_size - pad);
        D("rounding devsize up to a full eraseunit, now %llx\n", dev_size);
    }
    dev->devname = devname;
    dev->devname_len = devname_len;
    dev->max_size = dev_size;
    dev->data = malloc(dev->erase_size);
    if(dev->data == NULL)
        goto out_of_memory;
    dev->flags = read_only ? NAND_DEV_FLAG_READ_ONLY : 0;
#ifdef TARGET_I386
    dev->flags |= NAND_DEV_FLAG_BATCH_CAP;
#endif

    if (initfd >= 0) {
        do {
            read_size = do_read(initfd, dev->data, dev->erase_size);
            if(read_size < 0) {
                XLOG("could not read file %s, %s\n", initfilename, strerror(errno));
                exit(1);
            }
            if(do_write(rwfd, dev->data, read_size) != read_size) {
                XLOG("could not write file %s, %s\n", rwfilename, strerror(errno));
                exit(1);
            }
        } while(read_size == dev->erase_size);
        close(initfd);
    }
    dev->fd = rwfd;

    nand_dev_count++;

    return;

out_of_memory:
    XLOG("out of memory\n");
    exit(1);

bad_arg_and_value:
    XLOG("bad arg: %.*s=%.*s\n", arg_len, arg, value_len, value);
    exit(1);
}
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
			const char *fname, int fd, OFF_T total_size)
{
	static char file_sum1[MAX_DIGEST_LEN];
	static char file_sum2[MAX_DIGEST_LEN];
	struct map_struct *mapbuf;
	struct sum_struct sum;
	int32 len, sum_len;
	OFF_T offset = 0;
	OFF_T offset2;
	char *data;
	int32 i;
	char *map = NULL;

	read_sum_head(f_in, &sum);

	if (fd_r >= 0 && size_r > 0) {
		int32 read_size = MAX(sum.blength * 2, 16*1024);
		mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
		if (verbose > 2) {
			rprintf(FINFO, "recv mapped %s of size %.0f\n",
				fname_r, (double)size_r);
		}
	} else
		mapbuf = NULL;

	sum_init(checksum_seed);

	if (append_mode > 0) {
		OFF_T j;
		sum.flength = (OFF_T)sum.count * sum.blength;
		if (sum.remainder)
			sum.flength -= sum.blength - sum.remainder;
		if (append_mode == 2) {
			for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
				if (do_progress)
					show_progress(offset, total_size);
				sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
					   CHUNK_SIZE);
				offset = j;
			}
			if (offset < sum.flength) {
				int32 len = (int32)(sum.flength - offset);
				if (do_progress)
					show_progress(offset, total_size);
				sum_update(map_ptr(mapbuf, offset, len), len);
			}
		}
		offset = sum.flength;
		if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
			rsyserr(FERROR_XFER, errno, "lseek of %s returned %.0f, not %.0f",
				full_fname(fname), (double)j, (double)offset);
			exit_cleanup(RERR_FILEIO);
		}
	}

	while ((i = recv_token(f_in, &data)) != 0) {
		if (do_progress)
			show_progress(offset, total_size);

		if (i > 0) {
			if (verbose > 3) {
				rprintf(FINFO,"data recv %d at %.0f\n",
					i,(double)offset);
			}

			stats.literal_data += i;
			cleanup_got_literal = 1;

			sum_update(data, i);

			if (fd != -1 && write_file(fd,data,i) != i)
				goto report_write_error;
			offset += i;
			continue;
		}

		i = -(i+1);
		offset2 = i * (OFF_T)sum.blength;
		len = sum.blength;
		if (i == (int)sum.count-1 && sum.remainder != 0)
			len = sum.remainder;

		stats.matched_data += len;

		if (verbose > 3) {
			rprintf(FINFO,
				"chunk[%d] of size %ld at %.0f offset=%.0f\n",
				i, (long)len, (double)offset2, (double)offset);
		}

		if (mapbuf) {
			map = map_ptr(mapbuf,offset2,len);

			see_token(map, len);
			sum_update(map, len);
		}

		if (updating_basis_or_equiv) {
			if (offset == offset2 && fd != -1) {
				OFF_T pos;
				if (flush_write_file(fd) < 0)
					goto report_write_error;
				offset += len;
				if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset) {
					rsyserr(FERROR_XFER, errno,
						"lseek of %s returned %.0f, not %.0f",
						full_fname(fname),
						(double)pos, (double)offset);
					exit_cleanup(RERR_FILEIO);
				}
				continue;
			}
		}
		if (fd != -1 && map && write_file(fd, map, len) != (int)len)
			goto report_write_error;
		offset += len;
	}

	if (flush_write_file(fd) < 0)
		goto report_write_error;

#ifdef HAVE_FTRUNCATE
	if (inplace && fd != -1
	 && ftruncate(fd, offset) < 0) {
		rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
			full_fname(fname));
	}
#endif

	if (do_progress)
		end_progress(total_size);

	if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
	    report_write_error:
		rsyserr(FERROR_XFER, errno, "write failed on %s",
			full_fname(fname));
		exit_cleanup(RERR_FILEIO);
	}

	sum_len = sum_end(file_sum1);

	if (mapbuf)
		unmap_file(mapbuf);

	read_buf(f_in, file_sum2, sum_len);
	if (verbose > 2)
		rprintf(FINFO,"got file_sum\n");
	if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0)
		return 0;
	return 1;
}
Example #30
0
void *extra_self_tests(int arg1, void *arg2)
{
        /* creating /test1/test2/ directories */
   dbg(DBG_ERROR | DBG_VFS,"TEST: Creating directories\n");        
                do_mkdir("dir");
                do_mkdir("dir/dir1");
                do_mkdir("dir/dir2");
                do_mkdir("dir/dir3");             
                do_mkdir("dir/dir4");  
   dbg(DBG_ERROR | DBG_VFS,"TEST: Directories are created\n");
        int fd;
        char *file2buf="File 2 write only test case";
        char *file1buf="Testing file_1 for write operation";
        char readbuf[150];

   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir1\n");
        do_chdir("dir/dir1");

        /* file1.txt creation with O_CREAT|O_WRONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file1.txt with O_CREAT|O_WRONLY flag in directory dir/dir1\n");
        fd = do_open("file1.txt", O_CREAT|O_WRONLY);
        do_write(fd, file1buf, strlen(file1buf));
        do_close(fd);
        
        /* file2.txt creation with O_CREAT|O_RDONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir2\n");
        do_chdir("/dir/dir2");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file2.txt with O_CREAT | O_RDONLY flag  in directory dir/dir2\n");
        fd = do_open("file2.txt", O_CREAT | O_RDONLY);
        do_close(fd);
        
         /* Write into file2.txt using O_WRONLY flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Write into file2.txt with O_WRONLY flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY);
        do_write(fd, file2buf, strlen(file2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: written chars: \"%s\" in file2.txt\n",file2buf);
   
        char *appendbuf=" Appending for O_WRONLY|O_APPEND mode";
      /* Append into file2.txt using  O_WRONLY|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_WRONLY|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY|O_APPEND);
        do_write(fd, appendbuf, strlen(appendbuf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",appendbuf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

        char *append2buf=" Appending for O_RDWR|O_APPEND mode in file2";
      /* Append into file2.txt using  O_RDWR|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_RDWR|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_RDWR|O_APPEND);
        do_write(fd, append2buf, strlen(append2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",append2buf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(append2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source directory => /dir/dir2, Destination directory => /dir/linkofdir2 \n");
        do_chdir("/");
        do_link("dir/dir2","dir/linkofdir2");

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source file => /dir/dir1/file1.txt, to the Destination => /dir/linkoffile1 \n");
        do_link("dir/dir1/file1.txt","dir/linkoffile1");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming directory from dir/dir3 to dir/renamed \n");
        do_rename("dir/dir3","dir/renameddir3");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming file from dir/dir1/file1.txt to dir/dir1/renamedfile1.txt \n");
        do_rename("dir/dir1/file1.txt","dir/dir1/renamedfile1.txt");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Removing directory dir/dir4 \n");
        do_rmdir("dir/dir4");

   dbg(DBG_ERROR | DBG_VFS,"TEST: reading 18 chars from file: /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        fd = do_open("dir/linkoffile2", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read 18 chars: \"%s\" from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: reading file using lseek function on  /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        memset(readbuf,0,sizeof(char)*150);
        fd = do_open("dir/linkoffile2", O_RDONLY);
        do_lseek(fd,-19,2);
        do_read(fd,readbuf,19);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read chars: \"%s\" using lseek from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup()\n");
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
    int fd2= do_dup(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: duplicate file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
             do_close(fd);        do_close(fd2);
                     
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup2()\n");    
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
        fd2= do_dup2(fd,20);
   dbg(DBG_ERROR | DBG_VFS,"TEST: custom file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
                do_close(fd);        do_close(fd2);

        /*  Testing stat
        struct *statbuf;
   dbg(DBG_ERROR | DBG_VFS,"TEST: Testing the stat system call for directory dir\n");
        do_stat("dir",statbuf);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Output of stat for directory dir is :\"%s\" \n",statbuf);*/

        shellTest(); 

     return NULL;
}