Exemplo n.º 1
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode)
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      lock_acquire (&inode->lock);

      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);

      /* Deallocate blocks if removed. */
      if (inode->removed)
        {
          inode_clear (inode);
          free_map_release (inode->sector, 1);
        }

      lock_release (&inode->lock);
      free (inode);
    }
}
Exemplo n.º 2
0
// Reads from a file, f_offset must be kept in the client to remember the last point read
unsigned int fs_read_file(int inode, char * data, int size, unsigned long * f_offset) {
	inode_clear(&n);								// Clear inode to take off the trash
	
	inode_read(inode, &n);							// Read the current inode
	int log_block = * f_offset / FS_BLOCK_SIZE;		// Current logical block
	int block_index = * f_offset % FS_BLOCK_SIZE;	// Current block index
	int top_log_block = n.blocks / 2;				// Maximum logical block
	int i = 0;
	
	if (!top_log_block && n.mode & EXT2_S_IFDIR) {
		top_log_block = 1;							// Directory hack
	}

	// If we match the conditions, start reading
	if (log_block < top_log_block || log_block == top_log_block && block_index < n._last_write_offset) {
		log_block_read(&n, &log_block);
		char * block = (char *) &b;
		
		// Read iteratively and easy :)
		for (; i < size; i++, block_index++) {
			data[i] = block[block_index];
			
			if (top_log_block == log_block && block_index == n._last_write_offset - 1) {
				break;	// If it's a top, get out
			}
			
			if (block_index == FS_BLOCK_SIZE - 1) {
				log_block++;
				log_block_read(&n, &log_block);
				block_index = -1;
			}
		}
		* f_offset += i;
	} else {
		return 0; // Bad offset given
	}

	
	return i;
}
Exemplo n.º 3
0
// Writes to a file, as simple as unix
unsigned int fs_write_file(int inode, char * data, int size) {
	inode_clear(&n);							// Clear the inode to take off the trash
	inode_read(inode, &n);						// Read the current inode.
	

	int log_block = n.blocks / 2;
	block_clear(&b);							// Prepare to read the data, clear it.

	int i = 0;
	int block_index = n._last_write_offset;
	log_block_read(&n, &log_block);				// Set up the point where we'll write
	char * block = (char *) &b;
	
	// Write until we reach end
	for (; i < size; i++) {
		block[block_index] = data[i];
		if (block_index == FS_BLOCK_SIZE - 1) {
			log_block_write(&n, &log_block);
			log_block++;						// Iterate if necessary.
			log_block_read(&n, &log_block);
			block_index = 0;
		} else {
			block_index++;
		}
	}
	
	n._last_write_offset = block_index;
	log_block_write(&n, &log_block);			// Save the last bits
	
	n.blocks = log_block * 2;					// Update the inodes

	inode_write(inode,&n);
	fs_bitmaps_write_all();  					// Persist the changes in the FS

	return i;
}
Exemplo n.º 4
0
// Makes a new directory
unsigned int fs_mkdir(char * name, unsigned int parent_inode) {
	unsigned int inode_id = 0;
	if ((inode_id = fs_indir(name, parent_inode))) {
		return 0;
	}
	inode_id = bitmap_first_valued(bm_inodes, FS_INODE_BITMAP_SIZE, 0) + 1;
	
	if (!parent_inode) {
		parent_inode = inode_id;
	}
	
	int log_block;
	
	if (parent_inode != inode_id) {
		inode_read(parent_inode, &n);
		
		if(!fs_has_perms(&n, ACTION_WRITE))	{
			return ERR_PERMS;
		}
		
		log_block = n.blocks / 2;
		
		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, inode_id, name, &log_block);
		log_block_write(&n, &log_block);
		
		inode_write(parent_inode, &n);	
	}
	bitmap_write(bm_inodes, inode_id - 1, 1);

	
	

	
	inode_clear(&n);
	

	if(!fs_done)
	{
		n.uid = 0;
	} else {
		n.uid = current_ttyc()->uid;
	}

	n.mode = EXT2_S_IFDIR;
	n.size = 0;
	n.blocks = 0; // Beware! This represents the SECTORS!
	
	
	log_block = n.blocks / 2;
	
	block_clear(&b);
	dir_op_offset = 0;
	
	add_dir_entry(&n, EXT2_FT_DIR, inode_id, ".", &log_block);
	add_dir_entry(&n, EXT2_FT_DIR, parent_inode, "..", &log_block);

	log_block_write(&n, &log_block);
	
	n.blocks = (log_block) * 2;
	
	n.i_file_acl = 511;
	n._dir_inode = parent_inode;
	n._last_write_offset = dir_op_offset;
	
	inode_write(inode_id, &n);	
	



	
	fs_bitmaps_write_all();
	return inode_id;
}
Exemplo n.º 5
0
// Opens a file
unsigned int fs_open_file(char * name, unsigned int folder_inode, int mode, int type) {
	unsigned int inode_id = 0;

	if(strcmp(name, "/") == 0 && strlen(name) == strlen("/"))	{
		return 1; // root
	}


	if(name[0] == 0)
	{
		inode_id = current_ttyc()->pwd;
	} else {
		inode_id = fs_indir(name, folder_inode);
	}
	
	if (inode_id) {
		if (mode & O_CREAT) {
			int _rm_res = fs_rm(inode_id, 0);
			if(_rm_res < 0) {
				return _rm_res;
			}
		} else if(mode & O_NEW) {
			inode_read(inode_id, &n);
			if(n.mode == EXT2_S_IFLNK)	{
				return n.data_blocks[0];
			}
			return inode_id;
		} 
		else {
			inode_read(inode_id, &n);
			int can = 1;
			if((mode & O_RD) && !fs_has_perms(&n, ACTION_READ))	{
				can = 0;
			}
			if((mode & O_WR) && !fs_has_perms(&n, ACTION_WRITE))	{
				can = 0;
			}
			if(can || !fs_done)	{
				if(n.mode == EXT2_S_IFLNK)	{
					return n.data_blocks[0];
				}
				return inode_id;
			} else {
				return ERR_PERMS;
			}
		}
	} else if (!(mode & (O_NEW | O_CREAT))) {
		return ERR_NO_EXIST;
	}
	
	inode_id = bitmap_first_valued(bm_inodes, FS_INODE_BITMAP_SIZE, 0) + 1;
	
	if (!folder_inode) {
		folder_inode = inode_id;
	}
	
	int log_block;
	
	if (folder_inode != inode_id) {
		inode_read(folder_inode, &n);
		
		if(!fs_has_perms(&n, ACTION_WRITE))	{
			return ERR_PERMS;
		}
		
		log_block = n.blocks / 2;
		
		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, inode_id, name, &log_block);
		log_block_write(&n, &log_block);
		
		inode_write(folder_inode, &n);	
	}
	bitmap_write(bm_inodes, inode_id - 1, 1);
		
	inode_clear(&n);
	
	
	if(!fs_done)
	{
		n.uid = 0;
	} else {
		n.uid = current_ttyc()->uid;
	}
	
	n.mode =  type;
	n.size = 0;
	n.blocks = 0; // Beware! This represents the SECTORS!
	
	
	n._last_write_offset = 0;
	n.i_file_acl = 511;
	n._dir_inode = folder_inode;
	
	inode_write(inode_id, &n);	
	
	inode_clear(&n);

	if(n.mode == EXT2_S_IFLNK)	{
		return n.data_blocks[0];
	}
	
	return inode_id;
}