Exemplo n.º 1
0
/*
 * sys_fstat
 */
int
sys_fstat(int fd, userptr_t statptr)
{
    DEBUG(DB_VFS, "fstat %d\n", fd);
	struct stat kbuf;
	int err;

    /* Check if fd is a valid file descriptor. */
    struct filetable *ft = curthread->t_filetable;
    spinlock_acquire(&ft->ft_spinlock);
    
    /* If fd is not a valid file descriptor, return error */
    if ((fd < 0) || (fd >= __OPEN_MAX) || (ft->ft_entries[fd] == NULL) ||
            (ft->ft_entries[fd]->ft_vnode == NULL)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }

	/* Call VOP_STAT on the vnode */
	err = VOP_STAT(ft->ft_entries[fd]->ft_vnode, &kbuf);
    spinlock_release(&ft->ft_spinlock);
	if (err) {
		return err;
	}

	return copyout(&kbuf, statptr, sizeof(struct stat));
}
void swap_init() {
	int ret = vfs_open((char*) SWAP_DISK_NAME, O_RDWR, 0, &swap_vnode);
	if (ret) {
		kprintf("WARN swap disk not found Ret = %d\n", ret);
		swap_state = SWAP_STATE_NOSWAP;
		return;
	}
	struct stat statbuf;
	ret = VOP_STAT(swap_vnode, &statbuf);
	if (ret) {
		kprintf("ERR Stat on swap disk failed\n");
		swap_state = SWAP_STATE_NOSWAP;
		return;
	}

	swap_page_count = (statbuf.st_size / PAGE_SIZE) - 1;
	swap_map = (struct swap_entry*) kmalloc(
			sizeof(struct swap_entry) * swap_page_count);

	int i;
	for (i = 0; i < swap_page_count; i++) {
		swap_map[i].se_used = SWAP_PAGE_FREE;
		swap_map[i].se_paddr = i;
	}

	swap_lock = lock_create("swap_lock");

	swap_state = SWAP_STATE_READY;
	kprintf("Swap init done. Total available pages = %d\n", swap_page_count);

}
Exemplo n.º 3
0
off_t
lseek(int fd,off_t pos, int whence,int *err)
{
	off_t nPos=0;
	struct stat eoFILE;
	//kprintf("lseek entered\n");
	if ( fd < 0 || fd > OPEN_MAX)
		{
			*err = EBADF;
			 return -1;
		}
	if (curthread->ft[fd] == NULL)
	{
		*err = EBADF;
		 return -1;
	}
	//kprintf("curthread->ft[fd] == NULL\n");

	//kprintf("fd < 0 || fd > OPEN_MAX\n");
	if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)
	{
		*err = EINVAL;
		return -1;
	}
	//kprintf("whence != SEEK_SET || whence != SEEK_CUR || whence != SEEK_END\n");
	//kprintf("Acquiring lock\n");
	lock_acquire(curthread->ft[fd]->lock);
	//kprintf("Stat gathering\n");
	VOP_STAT(curthread->ft[fd]->vn,&eoFILE);
	if (whence == SEEK_SET)
	{
		nPos = pos;
	}
	if (whence == SEEK_CUR)
	{
		nPos = curthread->ft[fd]->offset+pos;
	}
	if (whence == SEEK_END)
	{
		nPos = eoFILE.st_size+pos;
	}
	if (nPos < 0)
	{
		*err = EINVAL;
		lock_release(curthread->ft[fd]->lock);
		return -1;
	}
	//kprintf("NPos %llu\n",nPos);
	*err = VOP_TRYSEEK(curthread->ft[fd]->vn,nPos);
	if (*err)
	{
		lock_release(curthread->ft[fd]->lock);
	    return -1;
	}
	curthread->ft[fd]->offset = nPos;
	lock_release(curthread->ft[fd]->lock);
	//kprintf("New position  %llu\n",nPos);
	return curthread->ft[fd]->offset;
}
Exemplo n.º 4
0
/*
 * swap_bootstrap: Initializes swap information and finishes
 * bootstrapping the VM so that processes can use it.
 *
 * Synchronization: none (runs during boot before anyone else uses VM)
 */
void
swap_bootstrap(size_t pmemsize)
{
	int rv;
	struct stat st;
	char path[sizeof(swapfilename)];
	off_t minsize;

	strcpy(path, swapfilename);
	rv = vfs_open(path, O_RDWR, &swapstore);
	if (rv) {
		kprintf("swap: Error %d opening swapfile %s\n", rv, 
			swapfilename);
		kprintf("swap: Please create swapfile/swapdisk.\n");
		panic("swap: Unable to continue.\n");
	}

	minsize = pmemsize*10;

	VOP_STAT(swapstore, &st);
	if (st.st_size < minsize) {
		kprintf("swap: swapfile %s is only %lu bytes.\n", swapfilename,
			(unsigned long) st.st_size);
		kprintf("swap: with %lu bytes of physical memory it should "
			"be at least\n", (unsigned long) pmemsize);
		kprintf("      %lu bytes (%lu blocks).\n", 
			(unsigned long) minsize, 
			(unsigned long) minsize / 512);
		kprintf("swap: Please extend it.\n");
		panic("swap: Unable to continue.\n");
	}

	kprintf("swap: swapping to %s (%lu bytes; %lu pages)\n", swapfilename,
		(unsigned long) st.st_size, 
		(unsigned long) st.st_size / PAGE_SIZE);

	swap_total_pages = st.st_size / PAGE_SIZE;
	swap_free_pages = swap_total_pages;
	swap_reserved_pages = 0;

	swapmap = bitmap_create(st.st_size/PAGE_SIZE);
	DEBUG(DB_VM, "creating swap map with %d entries\n",
			st.st_size/PAGE_SIZE);
	if (swapmap == NULL) {
		panic("swap: No memory for swap bitmap\n");
	}

	swaplock = lock_create("swaplock");
	if (swaplock == NULL) {
		panic("swap: No memory for swap lock\n");
	}

	/* mark the first page of swap used so we can check for errors */
	bitmap_mark(swapmap, 0);
	swap_free_pages--;
}
Exemplo n.º 5
0
static
bool
swap_device_suficient( size_t ram_size, size_t *swap_size ) {
	size_t		min_size;
	struct stat	stat;

	min_size = ram_size * SWAP_MIN_FACTOR;
	VOP_STAT( vn_sw, &stat );
	
	*swap_size = stat.st_size;
	return stat.st_size >= min_size;
}
Exemplo n.º 6
0
int
sys_lseek(int fd, off_t pos, int whence, off_t *new_pos)
{
        int err;
        struct fd_file *file;
        struct stat stat;

        file = get_file_from_fd_table(curproc->p_fd_table, fd);
        if (file == NULL) {
                err = EBADF;
                goto err1;
        }

        lock_acquire(file->fdf_lock);

        if (!VOP_ISSEEKABLE(file->fdf_vnode)) {
                err = ESPIPE;
                goto err2;
        }

        switch (whence) {
        case SEEK_SET:
                *new_pos = pos;
                break;
        case SEEK_CUR:
                *new_pos = file->fdf_offset + pos;
                break;
        case SEEK_END:
                VOP_STAT(file->fdf_vnode, &stat);
                *new_pos = stat.st_size + pos;
                break;
        default:
                err = EINVAL;
                goto err2;
        }

        if (*new_pos < 0) {
                err = EINVAL;
                goto err2;
        }

        file->fdf_offset = *new_pos;
        lock_release(file->fdf_lock);

        return 0;


        err2:
                lock_release(file->fdf_lock);
        err1:
                return err;
}
Exemplo n.º 7
0
void coreswap_init() {
	struct stat temp;
	VOP_STAT(swap_file, &temp);
	coreswap_size = temp.st_size/PAGE_SIZE;
	swap_map = bitmap_create(coreswap_size);
	coreswap = (struct page_table_entry*)kmalloc(coreswap_size * sizeof(struct page_table_entry));
	int coreswap_start=0;
	kprintf("COREMAP INIT: %d %d\n",coremap_start,coremap_size);
	for(int i = 0; i < temp.st_size/PAGE_SIZE; i++) {
		coreswap[i].paddr = (coreswap_start + (i * PAGE_SIZE));
	}
	kprintf("COREMAP INIT: %d %d\n",coremap_start,coremap_size);
}
Exemplo n.º 8
0
/*
 * sys_lseek
 * 
 */
int
sys_lseek(int fd, off_t offset, int whence, off_t *retval)
{
    DEBUG(DB_VFS, "Lseeking fd %d with offset %d\n", fd, (int)offset);
    struct filetable *ft = curthread->t_filetable;
    spinlock_acquire(&ft->ft_spinlock);
    
    /* If fd is not a valid file descriptor, return error. */
    if ((fd < 0) || (fd >= __OPEN_MAX) || (ft->ft_entries[fd] == NULL) ||
            (ft->ft_entries[fd]->ft_vnode == NULL)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }
    
    int pos;
    if (whence == SEEK_SET) {
        /* Update new position to offset.*/
        pos = (int)offset;
    }
    else if (whence == SEEK_CUR) {
        /* Update new position to current position + pos. */
        pos = (ft->ft_entries[fd]->ft_pos + (int)offset);
    } else if (whence == SEEK_END) {
        /* Update new positionto end-of-file + pos. */
        struct stat ft_stat;
        VOP_STAT(ft->ft_entries[fd]->ft_vnode, &ft_stat);
        pos = ft_stat.st_size + offset;
    } else {
        /* whence value is invalid. return error. */
        spinlock_release(&ft->ft_spinlock);
        return EINVAL;
    }

    /* If resulting position is negative, return error. */
    if (pos < 0) {
        spinlock_release(&ft->ft_spinlock);
        return EINVAL;
    }
    
    int result = VOP_TRYSEEK(ft->ft_entries[fd]->ft_vnode, pos);
    if (result != 0) {
        DEBUG(DB_VFS, "   tryseek failed with %d\n", result);
        spinlock_release(&ft->ft_spinlock);
        return ESPIPE;
    }
    
    ft->ft_entries[fd]->ft_pos = pos;
    *retval = (off_t)pos;
    spinlock_release(&ft->ft_spinlock);
	return 0;
}
Exemplo n.º 9
0
off_t 
sys_lseek(int fd,off_t pos, int whence, int *err){
  if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END){
    *err = EINVAL;
    return -1;
  }
  if (fd < 0 || fd >= MAX_FILE_DESCRIPTOR){
    *err = EBADF;
    return -1;
  }
  if (curthread->fd[fd] == NULL){
    *err = EBADF;
    return -1;
  }
  lock_acquire(curthread->fd[fd]->mutex);
  if (curthread->fd[fd]->update_pos == 0){
    *err = ESPIPE;
    lock_release(curthread->fd[fd]->mutex);
    return -1;
  }

  off_t newpos;
  struct stat stat;
  VOP_STAT(curthread->fd[fd]->file,&stat);
  if (whence == SEEK_SET)
    newpos = pos;
  if (whence == SEEK_CUR)
    newpos = curthread->fd[fd]->offset+pos;
  if (whence == SEEK_END)
    newpos = stat.st_size+pos;

  if (newpos < 0){
    *err = EINVAL;
    lock_release(curthread->fd[fd]->mutex);
    return -1;
  }
  *err = VOP_TRYSEEK(curthread->fd[fd]->file,newpos);
  if (*err){
    lock_release(curthread->fd[fd]->mutex);
    return -1;
  }
  curthread->fd[fd]->offset = newpos;
  lock_release(curthread->fd[fd]->mutex);
  return curthread->fd[fd]->offset;
}
Exemplo n.º 10
0
void swap_bootstrap(void)
{

	int retval;
	struct stat a;
//	struct vnode *swap_vnode;

	retval = vfs_open(SWAP_DEVICE, O_RDWR, &swap_vnode);
	if(retval)
	{
		panic("could not open swap device\n")	;
	}

	VOP_STAT(swap_vnode, &a);
	swap_map = bitmapCreate(a.st_size / PAGE_SIZE);
	if(swap_map == NULL)
	{
		panic("could not create swap map\n")	;
	}

	vfs_close(swap_vnode);
}
Exemplo n.º 11
0
/*
 * Initialize the swap area and the bitmap to describe the area. We steal memory 
 * from ram to store these data structures. Initialize each of the page's chunk
 * address.
 */
void init_swaparea() 
{
    int i;
    struct stat file_stat;    
    //read the size of the disk0 into file_stat
    VOP_STAT(swap_fp, &file_stat);   
    
    //swaparea size is in PAGE_SIZE unit
    swaparea_size = file_stat.st_size/PAGE_SIZE;   
    //bitmap to describe the swaparea (in memory or in disk)
    swap_memmap = bitmap_create(swaparea_size);    
    //allocate the swaparea into memory by stealing some memory from RAM
    swaparea = (struct _PTE*)kmalloc(swaparea_size * sizeof(struct _PTE));    

    //we are initializing swaparea first, so base address should be 0
    swap_base = 0;    
    //set chunk of each of the pages in the swaparea
    for(i = 0; i < file_stat.st_size/PAGE_SIZE; i++) 
    {
        swaparea[i].paddr = (swap_base + (i * PAGE_SIZE));
    }    
}
Exemplo n.º 12
0
/*
 * sys_fstat
 */
int
sys_fstat(int fd, userptr_t statptr)
{
  struct stat kstat;
  int result;
  struct filetable *file_table = curthread->t_filetable;
  spinlock_acquire(&file_table->filetable_lock);
  //kprintf(" doing fstat");
  //check for fd is valid or not
  if((fd > __OPEN_MAX) || (file_table->ft_entries[fd] == NULL) || (fd<0)){
    spinlock_release(&file_table->filetable_lock);
    return EBADF;
  }
  //use vop_stat to return the info of file
  result = VOP_STAT(file_table->ft_entries[fd]->file_vnode, &kstat);
  if(result){
    return result;
  }
  spinlock_release(&file_table->filetable_lock);
  //kprintf(" fstat done");
	return copyout(&kstat, statptr, sizeof(struct stat));
}
Exemplo n.º 13
0
int sys_lseek(int filehandle, off_t pos, int code, int *retval)
{
	off_t newfp;
	int r;
	struct stat statbuf;
  	/* check file handle */
	r = check_fd_access(filehandle, curthread->t_fdt, F_ANY);
	if (r) return r;
	
	switch (code) {
	case SEEK_SET:
		newfp = pos;
		break;
			
	case SEEK_CUR:
		newfp = curthread->t_fdt->fd[filehandle]->fp + pos; 
		break;
	case SEEK_END:
		r = VOP_STAT(curthread->t_fdt->fd[filehandle]->vn, &statbuf);
		if (r) return r;
		newfp = statbuf.st_size + pos; 
		break;
	default:
		return EINVAL;
	}
	
	if (newfp < 0) {
		return EINVAL;
	}
	
	r = VOP_TRYSEEK(curthread->t_fdt->fd[filehandle]->vn, newfp);
	if (r < 0) {
	  return r;
	}
	curthread->t_fdt->fd[filehandle]->fp = newfp;
	*retval = newfp;
	return 0;
}
Exemplo n.º 14
0
/* normal open() function - called by user */
int sys_open(const_userptr_t fileName, int flags, int * retval) {
	
	char fileNameFromUser[BUF_SIZE]; // file name from copyinstr
	bool append_flag = false;	// if O_APPEND is one of the flags, this variable is set to TRUE
	int err;
	
	// Step 1: first check if the filename pointer is valid
	if (fileName == NULL) {
		err = EFAULT;
		return err;
	}		

	// Step 2: then check if the flags are valid (use switch statement to check for valid flags)
	switch(flags) {
		case O_RDONLY: break;
		case O_WRONLY: break;
		case O_RDWR: break;
		case O_RDONLY|O_CREAT: break;
		case O_WRONLY|O_CREAT: break;
		case O_WRONLY|O_APPEND: append_flag = true;
					 break;
		case O_RDWR|O_CREAT: break;
		case O_RDWR|O_APPEND: append_flag = true;
					break;
		case O_RDWR|O_CREAT|O_TRUNC: break;
		default: err = EINVAL;
			return err;
	}
	

	// Step 3: if steps 1 and 2 are passing, then find an empty slot in the tfd_table and allocate it to this file that is going to be opened
	int slot = -1;
	for (int i=3; i<OPEN_MAX; i++) {
		if (curthread->t_fdtable[i] == NULL) {
			slot = i;
			break;	
		}
	}

		/* in case the file table is full and there are no empty slots */
	if (slot == -1) {
		err = EMFILE;
		return err;
	}

	// Step 4: copy the valid filename into the kernel buffer, using the copyinstr function
	size_t actual;
	if ((err = copyinstr(fileName, fileNameFromUser, BUF_SIZE, &actual)) != 0) {
		return err;
	}

	// Step 5: call vfs_open, with correct arguments
	struct vnode * node;
	err = vfs_open(fileNameFromUser, flags, 0, &node);
	// add code here to check if vnode returned successfully
	if (err) {	// if vnode not successful, then return appropriate error to user
		return err;
	}	
	
	// Step 6: initialize the struct fhandle with correct values, taking the flags into consideration		
	if (append_flag) {   /* case where the APPEND flag is true, get the file size and set pass it as the offset */
		struct stat buffer;
		VOP_STAT(node, &buffer);
		int bytes = buffer.st_size;
		*retval = slot;
		curthread->t_fdtable[slot] = fhandle_create(fileNameFromUser, flags, bytes, node);
		KASSERT(curthread->t_fdtable[slot] != NULL);
	
	} else { /* case where append flag is not TRUE */
	 	*retval = slot;
		curthread->t_fdtable[slot] = fhandle_create(fileNameFromUser, flags, 0, node);
		KASSERT(curthread->t_fdtable[slot] != NULL);
	}

	/* on success, return 0 */
	return 0;

}
Exemplo n.º 15
0
/* lseek() call handler */
int sys_lseek(int fd, off_t pos, int whence, off_t * retVal64){
	
	int err;
	off_t currentPosition;
	off_t endPosition;
	off_t posSeek;
	struct stat buffer;
	
	/* Step 1: Check if the file descriptor passed in is valid */
	if (fd >= OPEN_MAX || fd < 0) {	// fd is out of bounds of the file table
		return EBADF;
	} 

	struct fhandle * fdesc = curthread->t_fdtable[fd];
	if (fdesc == NULL) {
		return EBADF;
	}

	/* Adding locks to synchronize the whole process */
	lock_acquire(fdesc->lock);		
	switch(whence) {	// logic for different cases
		case SEEK_SET: //VOP_TRYSEEK(vnode, position)
				if (pos < 0) {
					lock_release(fdesc->lock);	
					return EINVAL;	// seek position is negative
				}
	
				posSeek = pos;
				if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) {
					lock_release(fdesc->lock);
					return ESPIPE;	// in case the SEEK fails
				}
				fdesc->offset = posSeek;
				*retVal64 = fdesc->offset;
				break;
			
		case SEEK_CUR:  currentPosition = fdesc->offset;
				posSeek = currentPosition + pos;
				
				if (posSeek < 0) {
					lock_release(fdesc->lock);
					return EINVAL;
				}
	
				if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) {
					lock_release(fdesc->lock);
					return ESPIPE;
				}
				fdesc->offset = posSeek;
				*retVal64 = fdesc->offset;
				break;

		case SEEK_END:  VOP_STAT(fdesc->vn, &buffer);
				endPosition = buffer.st_size;
				posSeek = endPosition + pos;
				
				if (posSeek < 0) {
					lock_release(fdesc->lock);
					return EINVAL;
				}

				if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) {
					lock_release(fdesc->lock);
					return ESPIPE;
				}
				
				if (pos < 0) {
					fdesc->offset = posSeek + pos;
				} else {
					fdesc->offset = posSeek;
				}

				*retVal64 = fdesc->offset;
				break;
		default: 
			return EINVAL; 
	}
	lock_release(fdesc->lock);
	
	return 0;

}