Beispiel #1
0
static int
remove_block(ospfs_inode_t *oi)
{
	// current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size);
	uint32_t block_no = 0;
	uint32_t *ptr;

	// keep track of allocations to free in case of -ENOSPC
	uint32_t allocated[2] = { 0, 0 };

	/* EXERCISE: Your code here */
	if (0 < n && n <= OSPFS_NDIRECT) {
		oi->oi_direct[n - 1] = 0;
		free_block(n - 1);
		goto out;
	}

	// The block to be allocated has to be in indirect or indirect2
	n -= OSPFS_NDIRECT;
	if (0 < n && n <= OSPFS_NINDIRECT) {
		if (oi->oi_indirect) {
			ptr = ospfs_block(oi->oi_indirect);
			free_block(ptr[n - 1]);
			ptr[n - 1] = 0;
			if ((n - 1) == 0) {
				free_block(oi->oi_indirect);
				oi->oi_indirect = 0;
			}
		}
		goto out;
	}

	// next block must lie in indirect2
	n -= OSPFS_NINDIRECT;
	if (0 < n && n <= (OSPFS_NINDIRECT * OSPFS_NINDIRECT)) {
		uint32_t *ptrl1, *ptrl2;
		uint32_t level1 = (n - 1) / OSPFS_NINDIRECT;
		uint32_t level2 = (n - 1) % OSPFS_NINDIRECT;

		ptrl1 = ospfs_block(oi->oi_indirect2);
		ptrl2 = ospfs_block(ptrl1[level1]);
		if (ptrl2[level2]) {
			free_block(ptrl2[level2]);
			ptrl2[level2] = 0;
		}
		if (level2 == 0) {
			free_block(ptrl1[level1]);
			ptrl1[level1] = 0;
			if (level1 == 0) {
				free_block(oi->oi_indirect2);
				oi->oi_indirect2 = 0;
			}
		}
	}
 out:
	return 0;
}
Beispiel #2
0
static int
remove_block(ospfs_inode_t *oi)
{
	// current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size);
	//the nth block is the one to remove
	if (n < 0 || n > OSPFS_MAXFILEBLKS)
		return -EIO;
	if (n == 0)
		return 0;
	n--;
	//just remove n and free the block
	if (n < OSPFS_NDIRECT) {
		free_block(oi->oi_direct[n]);
		oi->oi_direct[n] = 0;
	}
	// we have single indirection
	else if (n < OSPFS_NDIRECT + OSPFS_NINDIRECT) {
		// actual indirect block in memory
		uint32_t* indirect_block = (uint32_t *) ospfs_block(oi->oi_indirect);

		// free the direct block, data block is simply unbound after freeing the direct block
		free_block(indirect_block[direct_index(n)]);
		// set the block number of n in the indirect block to 0
		indirect_block[direct_index(n)] = 0;

		// if we freed the last block indirected to, we free the indirect block and variable as well
		if (!direct_index(n)) {
			free_block(oi->oi_indirect);
			oi->oi_indirect = 0;
		}
	}
	// ugh, double indirection
	else {
		uint32_t* indirect2_block = (uint32_t *) ospfs_block(oi->oi_indirect2);
		uint32_t* indirect_block = (uint32_t *) ospfs_block(indirect2_block[indir_index(n)]);

		// free the direct block
		free_block(indirect_block[direct_index(n)]);
		indirect_block[direct_index(n)] = 0;

		if (direct_index(n) == 0) {
			free_block(indirect2_block[indir_index(n)]);
			indirect2_block[indir_index(n)] = 0;
		}
		
		if (indir_index(n) == 0) {
			free_block(oi->oi_indirect2);
			oi->oi_indirect2 = 0;
		}
	}

	oi->oi_size = oi->oi_size - OSPFS_BLKSIZE;
	return 0;
}
Beispiel #3
0
static uint32_t
allocate_block(void)
{
	/* EXERCISE: Your code here */
	uint32_t i; 
	for(i = 1; i < ospfs_super->os_nblocks; i++){
		if(bitvector_test(ospfs_block(OSPFS_FREEMAP_BLK),i)){
			bitvector_clear(ospfs_block(OSPFS_FREEMAP_BLK),i);
			return i;
		}
	}
	return 0;
}
Beispiel #4
0
static void
free_block(uint32_t blockno)
{
	/* EXERCISE: Your code here */
	if(blockno > ospfs_super->os_firstinob + ospfs_super->os_ninodes/OSPFS_BLKINODES && blockno < ospfs_super->os_nblocks)
		bitvector_set(ospfs_block(OSPFS_FREEMAP_BLK),blockno);
}
Beispiel #5
0
static inline uint32_t
ospfs_inode_blockno(ospfs_inode_t *oi, uint32_t offset)
{
	uint32_t blockno = offset / OSPFS_BLKSIZE;
	if (offset >= oi->oi_size || oi->oi_ftype == OSPFS_FTYPE_SYMLINK)
		return 0;
	else if (blockno >= OSPFS_NDIRECT + OSPFS_NINDIRECT) {
		uint32_t blockoff = blockno - (OSPFS_NDIRECT + OSPFS_NINDIRECT);
		uint32_t *indirect2_block = ospfs_block(oi->oi_indirect2);
		uint32_t *indirect_block = ospfs_block(indirect2_block[blockoff / OSPFS_NINDIRECT]);
		return indirect_block[blockoff % OSPFS_NINDIRECT];
	} else if (blockno >= OSPFS_NDIRECT) {
		uint32_t *indirect_block = ospfs_block(oi->oi_indirect);
		return indirect_block[blockno - OSPFS_NDIRECT];
	} else
		return oi->oi_direct[blockno];
}
Beispiel #6
0
int
mark_inode_bitmap(ospfs_inode_t *oi, uint8_t *bitmap)
{
	int i, j;
	uint32_t *ptrl1, *ptrl2;
	int next_block = ospfs_size2nblocks(oi->oi_size);

	if (next_block == 0) {
		return 0;
	}

	for (i = 0; (i < OSPFS_NDIRECT) && oi->oi_direct[i]; i++) {
		bitvector_clear(bitmap, oi->oi_direct[i]);
	}

	if (i < OSPFS_NDIRECT || !oi->oi_indirect) {
		return 0;
	}

	next_block -= OSPFS_NDIRECT;
	bitvector_clear(bitmap, oi->oi_indirect);
	ptrl1 = ospfs_block(oi->oi_indirect);
	for (i = 0; i < OSPFS_NINDIRECT && ptrl1[i]; i++) {
		bitvector_clear(bitmap, ptrl1[i]);
	}

	if (i < OSPFS_NINDIRECT || !oi->oi_indirect2) {
		return 0;
	}

	next_block -= OSPFS_NINDIRECT;
	bitvector_clear(bitmap, oi->oi_indirect2);
	ptrl1 = ospfs_block(oi->oi_indirect);
	for (i = 0; i < OSPFS_NINDIRECT && ptrl1[i]; i++) {
		ptrl2 = ospfs_block(ptrl1[i]);
		bitvector_clear(bitmap, ptrl1[i]);
		for (j = 0; j < OSPFS_NINDIRECT && ptrl2[j]; j++) {
			bitvector_clear(bitmap, ptrl2[j]);
		}
		if (j < OSPFS_NINDIRECT) {
			break;
		}
	}

	return 0;
}
Beispiel #7
0
static void
zero_block(uint32_t block){
	char *ptr = (char*)ospfs_block(block);
	int i;
	for(i = 0; i < OSPFS_BLKSIZE; i++){
		ptr[i] = 0;	
	}
}
Beispiel #8
0
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Make sure we don't read past the end of the file!
	// Change 'count' so we never read past the end of the file.
	if(*f_pos > oi->oi_size)
		return 0;
	//we do not read past the end of the file
	if(*f_pos + count > oi->oi_size)
		count = oi->oi_size - *f_pos;
	/* EXERCISE: Your code here */

	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;
		//eprintk("reading!!");
		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);
		int offs = *f_pos % OSPFS_BLKSIZE;
		n = OSPFS_BLKSIZE - offs;
		int left = count - amount;
		n = (n > left) ? left : n;
		if(copy_to_user (buffer, data, n))
			//if copy success return 0;
		{
			retval = -EFAULT;
			goto done;
		}
		//to: Destination address, in user space.
 		//from: Source address, in kernel space.
 		//n: Number of bytes to copy.
		// Figure out how much data is left in this block to read.
		// Copy data into user space. Return -EFAULT if unable to write
		// into user space.
		// Use variable 'n' to track number of bytes moved.
		/* EXERCISE: Your code here */
		//retval = -EIO; // Replace these lines
		//goto done;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
Beispiel #9
0
static inline ospfs_inode_t *
ospfs_inode(ino_t ino)
{
	ospfs_inode_t *oi;
	if (ino >= ospfs_super->os_ninodes)
		return 0;
	oi = ospfs_block(ospfs_super->os_firstinob);
	return &oi[ino];
}
Beispiel #10
0
static void
free_block(uint32_t blockno)
{
	void *bitmap = ospfs_block(OSPFS_FREEMAP_BLK);

	// TODO: check validity of block

	bitvector_set(bitmap, blockno); // mark as free (set i bit to 1)
}
Beispiel #11
0
static void
free_block(uint32_t blockno)
{
	/* EXERCISE: Your code here */
	if(blockno < ospfs_super->os_firstinob)
		return;
	bitvector_set(ospfs_block(blockno / OSPFS_BLKBITSIZE + OSPFS_FREEMAP_BLK),
			blockno % OSPFS_BLKBITSIZE);
}
Beispiel #12
0
static int
ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
	//eprintk("simlink");
	ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino);
	uint32_t entry_ino = 0;
	//EXERCISE: Your code here. 
	if (dentry->d_name.len > OSPFS_MAXNAMELEN)
		return -ENAMETOOLONG;
	if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len))
		return -EEXIST;
	//create a new symlink inode
	ospfs_inode_t *free_inode = ospfs_block(ospfs_super->os_firstinob);
	uint32_t count = 1;
	while(count<ospfs_super->os_ninodes)
	{
		if (free_inode[count].oi_nlink == 0)
			break;
		count++;
	}
	//no free inode
	if (count == ospfs_super->os_ninodes)
	{
		count = 0;
		return -ENOSPC;
	}
	else 
		entry_ino = count;
	//create new inode and entry;
	ospfs_symlink_inode_t* symlink_oi = ospfs_inode(entry_ino);
	ospfs_direntry_t * sym_dentry = create_blank_direntry(dir_oi);
	if (IS_ERR(sym_dentry))
		return PTR_ERR(sym_dentry);
	//init symlink inode:
	if (strlen(symname)>OSPFS_MAXSYMLINKLEN)
		return -ENAMETOOLONG;
	symlink_oi->oi_size = strlen(symname);
	symlink_oi->oi_ftype = OSPFS_FTYPE_SYMLINK;
	symlink_oi->oi_nlink = 1;
	memcpy (symlink_oi->oi_symlink, symname, strlen(symname)); 
	symlink_oi->oi_symlink[strlen(symname)] = '\0';
	memcpy (sym_dentry->od_name, dentry->d_name.name, dentry->d_name.len);
	sym_dentry->od_name[dentry->d_name.len] = '\0';
	sym_dentry->od_ino = entry_ino;

	 //Execute this code after your function has successfully created the
	   //file.  Set entry_ino to the created file's inode number before
	   //getting here. 
	{
		struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino);
		if (!i)
			return -ENOMEM;
		d_instantiate(dentry, i);
		return 0;
	}
}
Beispiel #13
0
static int
remove_block(ospfs_inode_t *oi)
{
	// current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size);		
	/* EXERCISE: Your code here */
	uint32_t blockno = n - 1;
	if (blockno >= OSPFS_NDIRECT + OSPFS_NINDIRECT) {
		uint32_t blockoff = blockno - (OSPFS_NDIRECT + OSPFS_NINDIRECT);
		uint32_t *indirect2_block;
		uint32_t *indirect_block;
		if (oi->oi_indirect2 == 0)
			return -EIO;
		indirect2_block = ospfs_block(oi->oi_indirect2);
		if (indirect2_block[blockoff / OSPFS_NINDIRECT] == 0)
			return -EIO;
		indirect_block = ospfs_block(indirect2_block[blockoff / OSPFS_NINDIRECT]);

		free_block(indirect_block[blockoff % OSPFS_NINDIRECT]);
		indirect_block[blockoff % OSPFS_NINDIRECT] = 0;
		if (blockoff % OSPFS_NINDIRECT == 0) {
			free_block(indirect2_block[blockoff / OSPFS_NINDIRECT]);
			indirect2_block[blockoff / OSPFS_NINDIRECT] = 0;
			if (blockno == OSPFS_NDIRECT + OSPFS_NINDIRECT) {
				free_block(oi->oi_indirect2);
				oi->oi_indirect2 = 0;
			}
		}
	} else if (blockno >= OSPFS_NDIRECT) {
		uint32_t *indirect_block = ospfs_block(oi->oi_indirect);
		if (oi->oi_indirect == 0)
			return -EIO;

		free_block(indirect_block[blockno - OSPFS_NINDIRECT]);
		if (blockno - OSPFS_NDIRECT == 0)
			free_block(oi->oi_indirect);
	} else {
		free_block(oi->oi_direct[blockno]);
		oi->oi_direct[blockno] = 0;
	}
	oi->oi_size -= OSPFS_BLKSIZE;
	return 0; 
}
Beispiel #14
0
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Make sure we don't read past the end of the file!
	// Change 'count' so we never read past the end of the file.
	/* DONE: Your code here */
	if (count > oi->oi_size - *f_pos) {
		count = oi->oi_size - *f_pos;
	}
	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to read.
		// Copy data into user space. Return -EFAULT if unable to write
		// into user space.
		// Use variable 'n' to track number of bytes moved.

		//goto done;

		long block_pos = *f_pos % OSPFS_BLKSIZE;
		if (count - amount > OSPFS_BLKSIZE - block_pos) {
			n = OSPFS_BLKSIZE - block_pos;
		}
		else {
			n = count - amount;
		}
		retval = copy_to_user(buffer, data + block_pos, n);
		if (retval != 0) {
			return -EFAULT;
		}

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
Beispiel #15
0
/* Return Newly allocated block number */
static uint32_t
_add_block(int *ptr)
{
	uint32_t block_no = allocate_block();

	if (block_no) {
		*ptr = block_no;
		memset(ospfs_block(block_no), 0, OSPFS_BLKSIZE);
	}
	return block_no;
}
Beispiel #16
0
static void
free_block(uint32_t blockno)
{
	/* DONE: Your code here */
	// will not free boot, super, bitmap, or inode blocks
	if (blockno > ospfs_super->os_firstinob + OSPFS_BLKINODES){ 
		void* bitvector = ospfs_block(OSPFS_FREEMAP_BLK);
		bitvector_set(bitvector, blockno);
	}
	return 0;
}
Beispiel #17
0
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* EXERCISE: Your code here */
	int append = filp->f_flags & O_APPEND;
	if (append)
		*f_pos = oi->oi_size;
	
	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* EXERCISE: Your code here */
	if (count > oi->oi_size - *f_pos) {
		change_size(oi, count + oi->oi_size);
	}

	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}
		data = ospfs_block(blockno);
		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.  
		
		/* EXERCISE: Your code here */
		n = count - amount; //left to write!
		if (n > OSPFS_BLKSIZE)
		    n = OSPFS_BLKSIZE;
		if (copy_from_user(data + *f_pos, buffer, n) != 0)
		{   
		    return -EFAULT;
		}
        
		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
Beispiel #18
0
static int
remove_block(ospfs_inode_t *oi)
{
	// current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size);
	if(indir2_index(n)==0)
	{
		uint32_t *id2_block = ospfs_block(oi->oi_indirect2);
		uint32_t id2_off = indir_index(n);
		uint32_t *id_block = ospfs_block(id2_block[id2_off]);
		uint32_t d_off = direct_index(n);
		if(d_off == 0)//d_off == 0 means the direct is null which should make id2_block[id2_off] null
		{
			id2_block[id2_off] = NULL;
			if(id2_off == 0)
				oi->oi_indirect2 = NULL;
		}
		free_block(id_block[d_off]);
		id_block[d_off] = NULL;
	}
	else if(indir_index(n)==0)
	{
		uint32_t *id_block = ospfs_block(oi->oi_indirect);
		uint32_t d_off = direct_index(n);
		if(d_off == 0)//d_off == 0 means the direct is null which should make id2_block[id2_off] null
		{
			oi->oi_indirect = NULL;
		}
		free_block(id_block[d_off]);
		id_block[d_off] = NULL;
	}
	else
	{
		uint32_t d_off = direct_index(n);
		free_block(oi->oi_direct[d_off]);
		oi->oi_direct[d_off] = NULL;
	}
	/* EXERCISE: Your code here */
	oi->oi_size = (n-1)*OSPFS_BLKSIZE;
	return 0; // Replace this line
}
Beispiel #19
0
static void
free_block(uint32_t blockno)
{
	/* EXERCISE: Your code here */
	void* input_bitmap = ospfs_block(OSPFS_FREEMAP_BLK);
	int upperlimit = ospfs_super->os_nblocks;
	//make sure our blocknumber is within the bounds, then call set on that blocknumber
	if (blockno > OSPFS_FREEMAP_BLK && blockno < upperlimit) {
    	bitvector_set(input_bitmap, blockno);
	}
	else printk("Error! Invalid block number to be freed\n");
}
Beispiel #20
0
static void
free_block(uint32_t blockno)
{
	/* EXERCISE: Your code here */
  //might want to add in functionality so that it skips all inode blocks
	int min_blocks = ospfs_super->os_firstinob;
	void *bitmap = ospfs_block(OSPFS_FREEMAP_BLK);
	if(blockno > min_blocks && blockno < OSPFS_MAXFILEBLKS){
		if(bitvector_test(bitmap, blockno) == 0){
			bitvector_set(bitmap, blockno);		
		}
	}
}
Beispiel #21
0
static int
remove_block(ospfs_inode_t *oi)
{
	// current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size);

	/* EXERCISE: Your code here */
	if(n < 0) return -EIO; 
	else if(n == 0) return 0;
	
	int index = n-1;
	if(index < OSPFS_NDIRECT){
		free_block(oi->oi_direct[index]);
		oi->oi_direct[index] = 0;
	}
	else if(index < OSPFS_NDIRECT + OSPFS_NINDIRECT && index > OSPFS_NDIRECT){
		uint32_t* indirect_block = (uint32_t *)ospfs_block(oi->oi_indirect);
		free_block(indirect_block[direct_index(index)]);
		indirect_block[direct_index(index)] = 0;
		free_block(oi->oi_indirect);
		oi->oi_indirect = 0;
	}
	else if(index < OSPFS_MAXFILEBLKS){
		uint32_t * indirect2_block = (uint32_t *) ospfs_block(oi->oi_indirect2);
		uint32_t * indirect_block = (uint32_t *) ospfs_block(indirect2_block[indir_index(index)]);
		free_block(indirect_block[direct_index(index)]);
		indirect_block[direct_index(index)] = 0;
		free_block(indirect2_block[indir_index(index)]);
		indirect2_block[indir_index(index)] = 0;
		free_block(oi->oi_indirect2);
		oi->oi_indirect2 = 0;
	}
	else return -EIO;

	oi->oi_size -= OSPFS_BLKSIZE;
	return 0;
}
Beispiel #22
0
static int
remove_block(ospfs_inode_t *oi)
{
 // current number of blocks in file
	uint32_t n = ospfs_size2nblocks(oi->oi_size) - 1;

/* EXERCISE: Your code here */
	//3 cases: below OSPFS_NDIRECT, below OSPFS_NDIRECT+OSPFS_NINDIRECT, below OSPFS_NDIRECT+OSPFS_NINDRECT+OSPFS_NINDIRECT^2
	uint32_t* block;
	if(n <= OSPFS_NDIRECT)
		free_block(oi->oi_direct[n]);

	else if(n <= (OSPFS_NDIRECT + OSPFS_NINDIRECT))
	{
		block = ospfs_block(oi->oi_indirect);
		free_block(block[n-OSPFS_NDIRECT]);
		if(n == OSPFS_NDIRECT+1)
			free_block(oi->oi_indirect);
	}
	else if(n <= (OSPFS_NINDIRECT + OSPFS_NDIRECT + (OSPFS_NINDIRECT*OSPFS_NINDIRECT)))
	{
		block = ospfs_block(oi->oi_indirect2);

	//edge cases:
		if ((n-OSPFS_NDIRECT-OSPFS_NINDIRECT)%OSPFS_NINDIRECT == 0)
			free_block(block[(n-OSPFS_NDIRECT-OSPFS_NINDIRECT)%OSPFS_NINDIRECT]);
		if ((n-OSPFS_NDIRECT-OSPFS_NINDIRECT)/OSPFS_NINDIRECT == 0)
			free_block(block[(n-OSPFS_NDIRECT-OSPFS_NINDIRECT)/OSPFS_NINDIRECT]);
		//otherwise:
		free_block(oi->oi_indirect2);
	}
	else
		return -EIO;
	
	oi->oi_size = n * OSPFS_BLKSIZE;
	return 0;
}
Beispiel #23
0
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* EXERCISE: Your code here */

	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* EXERCISE: Your code here */

	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);
		//unsigned long copy_from_user (	(void *) ,(const void __user *) buffer, unsigned long count);

		//   Returns: a pointer to that block's data
		//to Destination address, in kernel space.
		//from: Source address, in user space.
		//n: Number of bytes to copy.
		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.
		/* EXERCISE: Your code here */
		retval = -EIO; // Replace these lines
		goto done;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
Beispiel #24
0
static uint32_t
allocate_block(void)
{
	void *bitmap = ospfs_block(OSPFS_FREEMAP_BLK);

	int i; // iterate through bitmap vector and return first free block
	for (i = 0; i < ospfs_super->os_nblocks; i++) {
		if (bitvector_test(bitmap, i)) {
			bitvector_clear(bitmap, i); // mark as used (set i bit to 0)
			return i;
		}
	}

	return 0;
}
Beispiel #25
0
static void
free_block(uint32_t blockno)
{
	/* EXERCISE: Your code here */

	
	/* EXERCISE: Your code here */
	if(blockno < ospfs_super->os_firstinob || blockno >= ospfs_super->os_nblocks)
		return;
	void *bitmap = ospfs_block(OSPFS_FREEMAP_BLK);
	/// bitvector_set -- Set 'i'th bit of 'vector' to 1.
	bitvector_set(bitmap, blockno);


}
Beispiel #26
0
static uint32_t
allocate_block(void)
{
	/* DONE: Your code here */
	int bits_in_bitmap = ospfs_super->os_nblocks;	// also is the number of blocks in our entire FS
	int x;
	void* bitvector = ospfs_block(OSPFS_FREEMAP_BLK);
	for (x = 0; x < bits_in_bitmap; x++) {
		if (bitvector_test(bitvector, x)) {
			bitvector_clear(bitvector, x);
			return x;
		}
	}
	return 0;
}
Beispiel #27
0
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;
	/* EXERCISE: Your code here */
	//Never let count request more data than the file size
	if(count > oi->oi_size - *f_pos)
		count = oi->oi_size - *f_pos;

	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		/* EXERCISE: Your code here */
		//Calulate amount of block left needed to copy
		n = count-amount;
		//Calculate offset of f_pos from a multiple of blocksize
		uint32_t offset = *f_pos % OSPFS_BLKSIZE; 
		if(count-amount > OSPFS_BLKSIZE - offset){
			n = OSPFS_BLKSIZE - offset;
		}
		
		if(copy_to_user(buffer, data + offset, n) != 0){
			//eprintk("Unable to write into user space.\n");
			retval = -EFAULT;
			goto done;		
		}

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
Beispiel #28
0
static uint32_t
allocate_block(void)
{
	int i;
	/* EXERCISE: Your code here */
	void *free_map = ospfs_block(OSPFS_FREEMAP_BLK);

	for (i = OSPFS_FREEMAP_BLK; i < ospfs_super->os_nblocks; i++) {
		if (bitvector_test(free_map, i)) {
			bitvector_clear(free_map, i);
			break;
		}
	}

	return (i == ospfs_super->os_nblocks) ? 0 : i;
}
Beispiel #29
0
static uint32_t
allocate_block(void)
{
	/* EXERCISE: Your code here */
	int i;
	for (i = OSPFS_FREEMAP_BLK; i < ospfs_super->os_firstinob; i++) {
		char *bitvector = ospfs_block(i);
		int j = 0;
		for (j = 0; j < OSPFS_BLKBITSIZE; j++) {
			if (bitvector_test(bitvector, j)) {
				bitvector_clear(bitvector, j);
				return (i - OSPFS_FREEMAP_BLK) * OSPFS_BLKBITSIZE + j;
			}
		}
	}
	return 0;
}
Beispiel #30
0
static uint32_t
allocate_block(void)
{
	/* EXERCISE: Your code here */
	
	void *bitmap = ospfs_block(OSPFS_FREEMAP_BLK);

	//check for free blocks. 0-2 blocks are always reserved so start at 3.
	int i;
	for(i = OSPFS_FREEMAP_BLK+1; i < ospfs_super->os_nblocks; i++){
			if(bitvector_test(bitmap, i) == 1){
				bitvector_clear(bitmap, i);
				return i;					
			}
	}
	return 0;
}