예제 #1
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Used to check if the file is a fifo or not.
unsigned int fs_is_fifo(int inode) {
	if(inode < 0)	{
		return 0;
	}
	inode_read(inode, &n);
	return n.mode & EXT2_S_IFIFO;
}
예제 #2
0
int
fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
	struct inode *ino = (struct inode *)fi->fh;
	ino->i_atime = time(NULL);
	return inode_read(ino, buf, size, offset);
}
예제 #3
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//******** cnopen *********************
//mode: FD_READ/FD_WRITE
int16_t cnopen(dir_ptr* dir, const char* name, uint8_t mode)
{
	stat_st stat_buf;
	if(cnstat(dir,name,&stat_buf) != 0)
	{
		if(mode == FD_WRITE) {
			check(cncreat(dir,name) == 0, "Could not create %s", name);
		}
		check(cnstat(dir,name,&stat_buf) == 0, "Could not stat %s", name);
	}
	//TODO: The fd bitmap is not 1 block long, hope we don't run out of fds
	int16_t fd = (int16_t)(uint16_t)find_free_bit((block*)fd_bm);
	set_bitmap((block*)fd_bm, fd);
	fd_tbl[fd].cursor = 0;
	fd_tbl[fd].state = mode;
	fd_tbl[fd].inode_id = stat_buf.inode_id;
	inode_read(stat_buf.inode_id, &fd_tbl[fd].inode);

	if(fd_tbl[fd].inode.blocks > 0)
	{
		fd_tbl[fd].data = calloc(fd_tbl[fd].inode.blocks,sizeof(block));
		llread(&fd_tbl[fd].inode, fd_tbl[fd].data);
	}
	else
	{
		fd_tbl[fd].data = NULL;
	}
	return fd;

error:
	return -1;
}
예제 #4
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//******** rmdir ********************
int8_t cnrmdir(const char* name)
{
	char parent_name[512];
	char entry_name[256];
	dir_entry* entry;
	inode dir_inode;
	memset(&dir_inode, 0, sizeof(inode));

	strcpy(parent_name, name);
	strcat(parent_name, "/..");

	dir_ptr* parent = cnopendir(parent_name);
	check(parent != NULL, "Cannot open parent directory");

	//Copy the entire directory minus the entry
	dir_ptr* new_parent = calloc(1,sizeof(dir_ptr));
	new_parent->data = calloc(parent->inode_st.blocks, sizeof(block));
	dir_entry* new_dir_entry = (dir_entry*)new_parent->data;
	new_parent->inode_st = parent->inode_st;
	new_parent->inode_id = parent->inode_id;
	new_parent->inode_st.size = 0;
	new_parent->index = 0;

	while((entry = cnreaddir(parent)))
	{
		memcpy(entry_name, entry->name, entry->name_len);
		entry_name[entry->name_len] = 0;
		if(strcmp(entry_name, name) == 0)  //If this is the directory we want
		{
			inode_read(entry->inode, &dir_inode);
			check(dir_inode.size == 24, "Directory is not empty");
			release_block(dir_inode.data0[0]);  //Release target directory block
			release_inode(entry->inode);        //Release target inode
			continue;
		}
		new_dir_entry->entry_len = entry->entry_len;
		new_dir_entry->name_len = entry->name_len;
		new_dir_entry->file_type = entry->file_type;
		new_dir_entry->inode = entry->inode;
		memcpy(new_dir_entry->name, entry->name, entry->name_len);
		new_parent->inode_st.size += entry->entry_len;
		new_parent->index += entry->entry_len;
		new_dir_entry = (dir_entry*)((uint8_t*)new_parent->data+new_parent->index);
	}

	inode_write(new_parent->inode_id, &new_parent->inode_st);
	llwrite(&new_parent->inode_st, new_parent->data);

	free(new_parent->data);
	free(new_parent);
	cnclosedir(parent);
	return 0;
error:
	if(new_parent != NULL && new_parent->data != NULL) free(new_parent->data);
	if(new_parent != NULL) free(new_parent);
	if(parent != NULL) cnclosedir(parent);
	return -1;
}
예제 #5
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//******** inflatedir *****************
//Populates a dir_ptr from an iptr
void inflatedir(dir_ptr* dir, iptr inode_id)
{
	inode_read(inode_id,&dir->inode_st);
	dir->inode_id = inode_id;
	//Read the directory file for this inode
	dir->data = calloc(dir->inode_st.blocks, sizeof(block));  	//Memory for all directory file blocks
	llread(&dir->inode_st, dir->data);	//Read the directory file
	dir->index = 0;
}
예제 #6
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Returns the inode's permissions
unsigned int fs_getmod(char * filename) {
	int start_inode = current_ttyc()->pwd;
	int namenode = fs_indir(filename, start_inode);
	if (namenode) {
		inode_read(namenode, &n);
		return n.i_file_acl & 0777;
	} else {
		return ERR_NO_EXIST;
	}
}
예제 #7
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Tells the current location
char *	fs_pwd() {
	
	int j = 1023;
	int i = 0;
	
	for(; i < 1024; ++i) {
		pwd_string[i] = 0;
	}
		
	int start_inode = current_ttyc()->pwd;

	inode_read(start_inode, &n);

	while(n._dir_inode != start_inode) {
		int _old_dirnode = n._dir_inode;
		char * name = fs_iname(start_inode, n._dir_inode);
		int k = strlen(name) - 2;
		for(; k >= 0; k--, j--) {
			pwd_string[j] = name[k];
		}
		pwd_string[j] = '/';
		j--;
		start_inode = _old_dirnode;
		inode_read(start_inode, &n);
	}
	if(j == 1023)
	{
		pwd_string[j] = '/';
	} else {
		j++;
	}

	
	for(i = 0; j < 1024; i++,j++)
	{
		pwd_string[i] = pwd_string[j];
		pwd_string[j] = 0;
	}
		
	return pwd_string;
}
예제 #8
0
void remove_from_dir(int inode_id, inode parent, FILE *ufs, superblock spb)
{
	uint16_t children[1024] = {0};
	inode realoc;
	int i;
	int position = -1;
	int blocksize = spb.magic_number;
	int last = first_free_child(parent, ufs, spb, blocksize, children);
	for (i = 0; i < last; i++)
	{
		if (children[i] == inode_id)
		{
			position = i;
		}
	}
	if (last == -1) last = 1023;
	else last -= 1;
	if (position == -1) 
	{
		printf("Error\n");
		return;
	}
	// printf("Position %d last %d children %d\n", position, last, children[last]);
	write_to_dir(position, parent, children[last], spb, ufs);
	inode_read(parent.id, ufs, spb.magic_number, spb.root_inode, &parent);
	// printf("last one is %d\n",last);
	//inode_read(last, ufs, blocksize, spb.root_inode, &realoc);
	// inode_write(inode_id, ufs, blocksize, uint16_t first_inode_blk, realoc);

	// write_to_dir(inode_id, parent, last, spb, ufs);
	write_to_dir(last, parent, 0, spb, ufs);
	if ((last - (BLK_PER_IND-4))%(blocksize/2) == 0)
	{
		// printf("caiu aqui\n");
		int block_in_vec = (BLK_PER_IND-4) + ((last - (BLK_PER_IND-4))/(blocksize/2));
		inode_read(parent.id, ufs, spb.magic_number, spb.root_inode, &parent);
		parent.blocks[block_in_vec] = 0;
		inode_write(parent.id, ufs, blocksize, spb.root_inode, parent);
	}
}
예제 #9
0
파일: fs.c 프로젝트: kshmir/so-2011-3
// Opens a link filetype
unsigned int fs_open_link(char * name, char * target_name) {
	unsigned int folder_inode = current_ttyc()->pwd;
	int target_inode = fs_indir(target_name, folder_inode);
	if(target_inode > 0)
	{
		int result = fs_open_file(name, folder_inode, O_NEW, EXT2_S_IFLNK);
		if(result > 0)	{
			inode_read(result, &n);
			n.data_blocks[0] = target_inode;
			inode_write(result, &n);	
			result = fs_open_reg_file(target_name, folder_inode, O_RD);
			inode_read(result, &n);
			n.links++;
			inode_write(result, &n);				
			return 1;
		}
		else {
			return result;
		}
	} else {
		return ERR_NO_EXIST;
	}

}
예제 #10
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Gets info from the file
void fs_finfo(char * filename, int * data) {
	int start_inode = current_ttyc()->pwd;
	int namenode = fs_indir(filename, start_inode);
	if(namenode)
	{
		inode_read(namenode, &n);	
		
		data[0] = namenode;						// Inode
		data[1] = n.blocks / 2;					// Blocks
		data[2] = n.blocks / 2 * 1024;			// Bytes
		data[3] = n.i_file_acl;					// Permissions
		data[4] = n.uid;						// UID
		data[5] = n._dir_inode;					// Directory inode
 	}
}
예제 #11
0
/**
 * Read from file f.
 */
int
file_read(struct file *f, char *addr, int n)
{
  int r;

  if(f->readable == 0)
    return -1;
  if(f->type == FD_INODE){
    inode_lock(f->ip);
    if((r = inode_read(f->ip, addr, f->off, n)) > 0)
      f->off += r;
    inode_unlock(f->ip);
    return r;
  }
  KERN_PANIC("file_read");
}
예제 #12
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//****** cncat *********************
int8_t cncat(const char* name, char* buf)
{
	stat_st filestat;
	dir_ptr* dir = cnopendir(".");

	check(cnstat(dir, name, &filestat) == 0, "Can not stat file");
	inode file_i;
	inode_read(filestat.inode_id, &file_i);

	int8_t fd = cnopen(dir,name,FD_READ);
	check(fd >= 0, "Can not open file");
	cnread((uint8_t*)buf, file_i.size, fd);
	return 0;
error:
	cnclosedir(dir);
	return -1;
}
예제 #13
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//******* cntree ************
void treedir(dir_ptr* dir, uint8_t indents, char** buf)
{
	dir_entry* entry;
	inode entry_i;
	memset(&entry_i, 0, sizeof(inode));
	int chars;

	//Write indent pattern
	char indent_str[256];
	uint8_t indents_ptr = indents;
	while(indents_ptr > 0)
	{
		strcat(indent_str,"    ");
		indents_ptr--;
	}

	while((entry = cnreaddir(dir)))
	{
		char name_copy[256];
		memset(name_copy, 0, 256);
		memcpy(name_copy, entry->name, entry->name_len);
		if(strcmp(name_copy,".") == 0) continue;
		if(strcmp(name_copy,"..") == 0) continue;

		inode_read(entry->inode,&entry_i);

		if(indents > 0)
		{
			strcpy(*buf,indent_str);
			*buf += strlen(indent_str);
		}
		memcpy(*buf, entry->name, entry->name_len);
		*buf += entry->name_len;
		chars = sprintf(*buf, "  %s  %u  %s", (entry_i.type == ITYPE_FILE) ? "F":"D", entry_i.size, ctime((const time_t *)&entry_i.modified));
		*buf += chars;

		if(entry->file_type == ITYPE_DIR)  //Go to next indent level if a dir
		{
			cncd(name_copy);
			dir_ptr* next_dir = cnopendir(".");
			treedir(next_dir,indents+1,buf);
			cnclosedir(next_dir);
			cncd("..");
		}
	}
}
예제 #14
0
파일: fs.c 프로젝트: claytondus/cdnwsh
//****** cnexport ****************
int8_t cnexport(const char* g_name, const char* h_name)
{
	FILE* h_file;
	size_t h_size;
	char* buf;
	size_t result;
	int16_t g_file;
	stat_st statbuf;

	h_file = fopen(h_name, "wb");
	check(h_file != NULL, "Can not open host file");

	dir_ptr* cwd = cnopendir(".");
	g_file = cnopen(cwd, g_name, FD_READ);
	check(g_file >= 0, "Cannot open guest file for reading");

	check(cnstat(cwd, g_name, &statbuf) == 0, "Cannot stat guest file");
	inode g_inode;
	inode_read(statbuf.inode_id, &g_inode);
	h_size = g_inode.size;

	//buffer for whole file
	buf = calloc(h_size, sizeof(char));

	//load file
	result = cnread((uint8_t*)buf, h_size, g_file);
	check(result == h_size, "Error reading from guest file");

	//write the buffer to the host
	result = fwrite(buf, sizeof(char), h_size, h_file);
	check(result > 0, "Error writing to host file");

	//close guest resources
	cnclose(g_file);
	cnclosedir(cwd);
	fclose(h_file);
	free(buf);
	return 0;
error:
	//close guest resources
	cnclose(g_file);
	cnclosedir(cwd);
	fclose(h_file);
	free(buf);
	return -1;
}
예제 #15
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Changes the permissions of the file
unsigned int fs_chmod(char * filename, int perms) {
	int current_uid = current_ttyc()->uid;
	int start_inode = current_ttyc()->pwd;
	int namenode = fs_indir(filename, start_inode);
	if (namenode) {
		inode_read(namenode, &n);
		if (n.uid == current_uid || current_uid == 0) {
			n.i_file_acl = perms;
			inode_write(namenode, &n);
		} else {
			return ERR_PERMS;
		}
		return 1;
	} else {
		return ERR_NO_EXIST;
	}
}
예제 #16
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Removes an entry from a folder
unsigned int folder_rem_direntry(unsigned int file_inode, unsigned int folder_inode) {
	inode_read(folder_inode, &n);
	
	int index = 0;
	int max_log_block = n.blocks / 2;
	if (!max_log_block) {
		max_log_block = 1;
	}
	dir_op_offset = 0;
	block_clear(&b);
	
	dir_entry * old_dot = NULL;
	dir_entry * dot = NULL;
	// Iterates dir entries
	while (index < max_log_block + 1) {
		old_dot = dot;
		dot = iterate_dir_entry(&b);
		if (dot == NULL) {
			if (index == max_log_block) {
				break;
			}
			log_block_read(&n,&index);
			dir_op_offset = 0;
			dot = NULL;
			index++;	
		} else {
			int i = 0; ;
			int match = file_inode == dot->inode;
			if (match) {
				if (old_dot != NULL) {
					old_dot->rec_len += dot->rec_len;
					dot->inode = 0;
					dot->name_len = 0; // Sets as deleted
				} else {
					dot->name_len = 0; // Sets as deleted
				}
				int to_write = index - 1;
				log_block_write(&n, &to_write);
				break;
			}
		}
	}	
	return 0;
}
예제 #17
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Tells the name of the inode, by reading it's parent
char * fs_iname(int inode, int folder_inode) {
	inode_read(folder_inode, &n);
	
	*iname = 0;
	
	int index = 0;
	int max_log_block = n.blocks / 2;
	if (!max_log_block) {
		max_log_block = 1;
	}
	dir_op_offset = 0;
	block_clear(&b);
	
	dir_entry * old_dot = NULL;
	dir_entry * dot = NULL;
	// Iterates dir entries
	while (index < max_log_block + 1) {
		old_dot = dot;
		dot = iterate_dir_entry(&b);
		if (dot == NULL) {
			if (index == max_log_block) {
				break;
			}
			log_block_read(&n,&index);
			dir_op_offset = 0;
			dot = NULL;
			index++;	
		} else {
			int i = 0; ;
			if (inode == dot->inode) {
				int match = 1;
				
				int i = 0;
				int len = dot->name_len;
				for(; i < len; ++i) {
					iname[i] = dot->name[i];
				}
				iname[i] = 0;
				return iname;
			}
		}
	}	
	return 0;
}
예제 #18
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Changes the inode's owner
unsigned int fs_chown(char * filename, char * username) {
	int new_uid = user_exists(username);
	int current_uid = current_ttyc()->uid;
	int start_inode = current_ttyc()->pwd;
	int namenode = fs_indir(filename, start_inode);

	if (namenode && new_uid != -1) {
		inode_read(namenode, &n);
		if (n.uid == current_uid || current_uid == 0) {
			n.uid = new_uid;
			inode_write(namenode, &n);
		} else {
			return ERR_PERMS;
		}
		return 1;
	} else {
		return ERR_NO_EXIST;
	}
}
예제 #19
0
int
fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
	struct inode *dir = (struct inode *)fi->fh;
	struct dirent dent;
	int r;

	while ((r = inode_read(dir, &dent, sizeof(dent), offset)) > 0) {
		offset += r;
		if (dent.d_name[0] == '\0')
			continue;
		if (filler(buf, dent.d_name, NULL, offset) != 0)
			return 0;
	}
	dir->i_atime = time(NULL);
	flush_block(dir);

	return 0;
}
예제 #20
0
파일: fs.c 프로젝트: steinwaywhw/Random
int fs_read (fs_t *fs, int index, int offset, void *buffer, int len) {
	// assert (fs != NULL);
	// assert (index >= 0 && index < INODE_ARRAY_SIZE);
	// assert (buffer != NULL);
	// assert (offset >= 0);
	// assert (len >= 0);

	index_node_t *inode = &fs->super_block->inodes[index];
	// assert (inode->in_use == 1);

	// EOF
	if (offset >= inode->size)
		return 0;

	int to_read = inode->size - offset;
	to_read = to_read > len ? len : to_read;

	return inode_read (fs->super_block, index, offset, buffer, to_read);
}
예제 #21
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Tells if an name is inside the folder entries
unsigned int fs_indir(char * name, int folder_inode) {
	inode_read(folder_inode, &n);
	
	int index = 0;
	int max_log_block = n.blocks / 2;
	if (!max_log_block) {
		max_log_block = 1;
	}
	dir_op_offset = 0;
	block_clear(&b);
	
	dir_entry * old_dot = NULL;
	dir_entry * dot = NULL;
	// Iterates dir entries
	while (index < max_log_block + 1) {
		old_dot = dot;
		dot = iterate_dir_entry(&b);
		if (dot == NULL) {
			if (index == max_log_block) {
				break;
			}
			log_block_read(&n,&index);
			dir_op_offset = 0;
			dot = NULL;
			index++;	
		} else {
			int i = 0; ;
			int name_len = strlen(name);
			if (name_len == dot->name_len) {
				int match = 1;
				for (;name[i] && match; i++) {
					match = name[i] == dot->name[i];
				}
				if (match) {
					return dot->inode;
				}
			}
		}
	}	
	return 0;
}
예제 #22
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Changes the directory
int	fs_cd(char * name) {
	int start_inode = current_ttyc()->pwd;
	
	int namenode = fs_indir(name, start_inode);
	if (namenode) {
		inode_read(namenode, &n);
		if(n.mode & EXT2_S_IFLNK)	{
			if (bitmap_read(bm_inodes, n.data_blocks[0] - 1))
				current_ttyc()->pwd = n.data_blocks[0];
			else {
				return ERR_NO_EXIST;
			}
			
		} else {
			current_ttyc()->pwd = namenode;
		}
		return 1;
	} else {
		return ERR_NO_EXIST;
	}
}
예제 #23
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// 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;
}
예제 #24
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// 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;
}
예제 #25
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// 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;
}
예제 #26
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Removes an inode from the filesystem, documented in header
unsigned int fs_rm(unsigned int inode, int inside_recursion) {
	inode_read(inode, &n);
	
	if(!(inode > 1))	{
		return ERR_PERMS; 					// Permissions check
	}
	
	if(!fs_has_perms(&n, ACTION_WRITE))	{
		return ERR_PERMS;					// If you can't write you can't delete...
	}
	
	if (!inside_recursion) { // I'm not sure about this, but well... at least it's just a security flaw.
		inode_read(n._dir_inode, &n);
		if(!fs_has_perms(&n, ACTION_WRITE))	{		
			return ERR_PERMS;				// If you can't write on the parent folder you can't delete
		}
		inode_read(inode, &n);
	}
	

	int log_block = n.blocks / 2 + 1;		// Logical block top
	int ph_block = 0;
	
	// Go from top to bottom to delete everything.
	while(log_block > 0) {
		log_block--;
		make_ph_block(&n, &ph_block, &log_block);
	 	
		if (n.mode & EXT2_S_IFDIR) { // If it's a directory... then... RECURSION! D:
			block entries;
			data_read_block(&entries, ph_block);
			int off = 0;
			dir_op_offset = 0;
			dir_entry * old_dot = NULL;
			dir_entry * dot = iterate_dir_entry(&entries);
			// Iterates dir entries
			while (dot != NULL) {
				if (dot == NULL) {
					break;
				} else {
					if (dot->name_len > 0 && dot->inode != inode && dot->inode != n._dir_inode) {
						// If we get an error we don't actually make anything :D, but we might delete other files.
						int _rm = fs_rm(dot->inode, 1);
						if(_rm < 0)
						{
							data_write_block(&entries, ph_block);
							bitmap_write(bm_blocks, ph_block - 1, 0);
							return _rm;
						}
						off = dir_op_offset;
						dot->name_len = 0;
						dir_op_offset = off;
						inode_read(inode, &n);
					}
				}
				old_dot = dot;
				dot = iterate_dir_entry(&entries);
			}	

			data_write_block(&entries, ph_block);
		}
		bitmap_write(bm_blocks, ph_block - 1, 0); // This deletes the stuff actually
		delete_internal_inodes(log_block);        // This deletes the EXT2 ugly but wise indirects.
	}
	
	// Delete the directory entry of the file.
	if (!inside_recursion) {
		inode_read(inode, &n);
		unsigned int folder_inode = n._dir_inode;
		inode_read(folder_inode, &n);		
		folder_rem_direntry(inode, folder_inode);
	}

	bitmap_write(bm_inodes, inode - 1, 0);		 // Persist the directory liberation.

	fs_bitmaps_write_all();  					 // Persist in the FS.

						  
	return 1;
}
예제 #27
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Filesystem Initialization
void fs_init() {
	
	int i = 0;
	for (; i < sizeof(fs_data) / 4; i += 4) {
		((int*)&dat)[i] = 0;
	}
	
	fs_sb_read();

	
	sb = (super_block *) &dat.head._super;
	gbdt = (group_descriptor *) &dat.head._descriptors;
	
	// If the magic number is on then the fs is already loaded.
	if(sb->s_magic == 0xEF53) {
		fs_gbdt_read();
		fs_bitmaps_init();
		if (_FS_DEBUG) {


			
			
			inode_read(1, &n);
		
			
			int index = 0;
			int max_log_block = n.blocks / 2;
			if (!max_log_block) {
				max_log_block = 1;
			}
			dir_op_offset = 0;
			block_clear(&b);
			while (index < max_log_block + 1) {
				dir_entry * dot = iterate_dir_entry(&b);
				
				if (dot == NULL) {
					if (index == max_log_block) {
						break;
					}
					log_block_read(&n,&index);
					dir_op_offset = 0;
					index++;	
				} else {
					
					int len = dot->name_len, i = 0;
					for (; i < len; i++) {
						printf("%c", dot->name[i]);
					}
					printf("\n");
				}
			}
			
		}
		fs_bitmaps_write_all();
		fs_gbdt_write();
		fs_sb_write();
	}
	else {
		printf("Preparing to start FS\n");
		
		printf("Starting SB\n");
		fs_sb_init();	
		printf("Starting GBDT\n");
		fs_gbdt_init();	
		printf("Starting Bitmaps\n");
		fs_bitmaps_init();
		
		printf("Creating /\n");
		int slash_inode = fs_mkdir("/", 1);
		printf("Creating /dev\n");
		int dev_inode   = fs_mkdir("dev", slash_inode);
		printf("Creating /home\n");
		int home_inode  = fs_mkdir("home", slash_inode);
		printf("Creating /root\n");
		int root_inode  = fs_mkdir("root", slash_inode);
		printf("Creating /etc\n");
		int etc_inode   = fs_mkdir("etc", slash_inode);
		printf("Creating /tmp\n");
		int tmp_inode   = fs_mkdir("tmp", slash_inode);
		printf("Creating /tmp/testfile\n");
		int f1 = fs_open_reg_file("testfile", tmp_inode, O_NEW);
		
		printf("FS ended...\n");
		
		printf("\tFree Blocks: %d\t Total Blocks: %d\n", 
			   bitmap_block_count(bm_blocks, FS_DATA_BITMAP_SIZE, 0),
			   FS_DATA_BITMAP_SIZE);
		printf("\tFree Inodes: %d\t Total Inodes: %d\n",
			   bitmap_block_count(bm_inodes, FS_INODE_BITMAP_SIZE, 0),
			   FS_INODE_BITMAP_SIZE);
		
		fs_bitmaps_write_all();
		fs_gbdt_write();
		fs_sb_write();
	}
}
예제 #28
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Used to move a file
unsigned int fs_mv(char * name, char * newname, int from_inode) {
	int i1 = fs_open_file(name, from_inode, O_WR | O_RD, EXT2_S_IFREG);
	if(i1 < 0)	{
		return i1; // If there's an error with the first name then there's nothing to do actually.
	}
	
	int i2 = fs_indir(newname, from_inode);
	if(i2 == 0)	{
		folder_rem_direntry(i1, n._dir_inode);

		inode_read(from_inode, &n);
		int 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, i1, newname, &log_block);
		log_block_write(&n, &log_block);		
		
		n.blocks = log_block * 2;
		inode_write(from_inode, &n);
		
		return 1;
	} else {
		inode_read(i2, &n);

		if(!fs_has_perms(&n, ACTION_READ))	{
			return ERR_PERMS;
		}
		
		if(!(n.mode & EXT2_S_IFDIR))	{
			return ERR_INVALID_TYPE;
		}
		
		if (fs_indir(name, i2)) {
			return ERR_REPEATED;
		}

		int 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, i1, name, &log_block);
		log_block_write(&n, &log_block);

		n.blocks = log_block * 2;
		inode_write(i2, &n);

		inode_read(i1, &n);
		folder_rem_direntry(i1, n._dir_inode);
		inode_read(i1, &n);
		folder_rem_direntry(n._dir_inode, i1);
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, i2, "..", &log_block);
		log_block_write(&n, &log_block);
		n._dir_inode = i2;
		inode_write(i1, &n);
	}	
	return i1;
	
}
예제 #29
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// Used to copy a file
unsigned int fs_cp(char * name, char * newname, int from_inode, int to_inode) {
	int i1 = fs_open_file(name, from_inode, O_RD, EXT2_S_IFREG);
	if(i1 < 0)	{
		return i1; // If there's an error with the first name then there's nothing to do actually.
	}
	inode_read(i1, &n);	
	int i2;
	if(!(n.mode & EXT2_S_IFDIR))
	{
		i2 = fs_open_file(newname, to_inode, O_WR, n.mode & (~EXT2_S_IFDIR)); 
		inode_read(i1, &n);	
		if(i2 < 0) { 
			i2 = fs_open_file(newname, to_inode, O_WR | O_NEW , n.mode & (~EXT2_S_IFDIR));
		}
		
		if(i2 < 0) { 
			return ERR_EXISTS;
		}
	} else {
		i2 = fs_mkdir(newname, to_inode);
		if(i2 < 0) { 
			return ERR_EXISTS;
		}
	}

	inode_read(i1, &n);
	block data;
	unsigned long offset = 0;
	
	while(fs_read_file(i1, (void *) &data, sizeof(block), &offset) > 0) {
		if(n.mode & EXT2_S_IFDIR)
		{
			int off = 0;
			dir_op_offset = 0;
			dir_entry * old_dot = NULL;
			dir_entry * dot = iterate_dir_entry(&data);
			// Iterates dir entries
			while (dot != NULL) {
				if (dot == NULL) {
					break;
				} else {
					if (dot->name_len > 0 && dot->inode != i1 && dot->inode != n._dir_inode && i2 != 0) {
						int _cp = fs_cp(dot->name, dot->name, i1, i2);

						if(_cp < 0)
						{
							return _cp;
						}
						off = dir_op_offset;
						dot->name_len = 0;
						dir_op_offset = off;
					}
				}
				old_dot = dot;
				dot = iterate_dir_entry(&data);
			}
			inode_read(i1, &n);
		} else {
			fs_write_file(i2, (void *)&data, sizeof(block));		
		}
	}

	return i2;
}
예제 #30
0
파일: fs.c 프로젝트: kshmir/so-2011-2
// 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;
}