Beispiel #1
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	ospfs_direntry_t *dir_entry;
	int retval;

	// look for empty entry
	uint32_t offset;
	for (offset = 0; offset < dir_oi->oi_size; offset += OSPFS_DIRENTRY_SIZE) {
		dir_entry = ospfs_inode_data(dir_oi, offset);
		if (dir_entry->od_ino == 0)
			return dir_entry;
	}

	// no empty entry, add block (will be added at offset = current oi_size)
	retval = add_block(dir_oi);
	if (retval < 0)
		return ERR_PTR(retval);

	dir_entry = ospfs_inode_data(dir_oi, offset);
	return dir_entry;
}
Beispiel #2
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	// not a directory
	if (dir_oi->oi_ftype != OSPFS_FTYPE_DIR) return ERR_PTR(-EINVAL);

	// check existing directory for empty entry
	int k;
	for (k = 0; k < dir_oi->oi_size; k += OSPFS_DIRENTRY_SIZE) {
		ospfs_direntry_t* od = ospfs_inode_data(dir_oi, k);
		// entry is empty
		if (od->od_ino == 0) {
			return od;
		}
	}

	// no empty entry exists
	// add new entry
	int r = add_block(dir_oi);
	if (r) return ERR_PTR(r);
	return ospfs_inode_data(dir_oi, dir_oi->oi_size - OSPFS_BLKSIZE);
	/* DONE: Your code here. */
}
Beispiel #3
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//	if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//	Use ERR_PTR if this fails; otherwise, clear out all the directory
	//	entries and return one of them.

	/* EXERCISE: Your code here. */
	//return ERR_PTR(-EINVAL); // Replace this line
    
	//Part 1:
	//Iterate through directory data and find empty entry
	uint32_t i = 0;
	ospfs_direntry_t *tmp;
	uint32_t num_entries = dir_oi->oi_size;

	for (i = 0; i < num_entries; i+= OSPFS_DIRENTRY_SIZE) {
    	tmp = ospfs_inode_data(dir_oi, i);
    	if (tmp->od_ino == 0)
    	return tmp;
	}

	int blankdir = change_size(dir_oi, dir_oi->oi_size+OSPFS_DIRENTRY_SIZE);
	if (blankdir == 0) {
    	tmp = ospfs_inode_data(dir_oi, num_entries);
    	return tmp;
	}
	return ERR_PTR(blankdir);

}
Beispiel #4
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	/* EXERCISE: Your code here. */
	int f_pos = 0;
	int r;
	//Search for empty directory
	for(; f_pos < dir_oi->oi_size; f_pos+= OSPFS_DIRENTRY_SIZE){
			ospfs_direntry_t *od = ospfs_inode_data(dir_oi, f_pos);
			if(od->od_ino == 0){
				return od;			
			}
	} 

	//No empty directories found, so add a new block
	r = change_size(dir_oi, dir_oi->oi_size + OSPFS_BLKSIZE);
	//Check for error
	if(r < 0){
		return ERR_PTR(r);	

	}

	//Don't know if this is right, get the pos of the newly added block
	return ospfs_inode_data(dir_oi, f_pos);
}
Beispiel #5
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	/* EXERCISE: Your code here. */
	int i;
	int error;
	ospfs_direntry_t *entry = NULL;
	
	for(i = 0; i < dir_oi->oi_size; i += OSPFS_DIRENTRY_SIZE) {
		entry = ospfs_inode_data(dir_oi, i);
		if(entry->od_ino == 0) {
			return entry;
		}
	}
	
	error = add_block(dir_oi);
	if (error != 0) {
		return ERR_PTR(error);
	}
	
	entry = ospfs_inode_data(dir_oi, i);
	entry->od_ino = 0;
	entry->od_name[0] = 0;
	return entry;
}
Beispiel #6
0
static int
ospfs_unlink(struct inode *dirino, struct dentry *dentry)
{
	ospfs_inode_t *oi = ospfs_inode(dentry->d_inode->i_ino);
	ospfs_inode_t *dir_oi = ospfs_inode(dentry->d_parent->d_inode->i_ino);
	int entry_off;
	ospfs_direntry_t *od;

	od = NULL; // silence compiler warning; entry_off indicates when !od
	for (entry_off = 0; entry_off < dir_oi->oi_size;
     	entry_off += OSPFS_DIRENTRY_SIZE) {
    	od = ospfs_inode_data(dir_oi, entry_off);
    	if (od->od_ino > 0
        	&& strlen(od->od_name) == dentry->d_name.len
        	&& memcmp(od->od_name, dentry->d_name.name, dentry->d_name.len) == 0)
        	break;
	}

	if (entry_off == dir_oi->oi_size) {
    	printk("<1>ospfs_unlink should not fail!\n");
    	return -ENOENT;
	}

	od->od_ino = 0;
	oi->oi_nlink--;

	//after unlinking, decrement number of links
	dir_oi->oi_nlink--;
	//if a file doesn't have any more links, we can delete it by giving it 0 size  
	if (oi->oi_ftype != OSPFS_FTYPE_SYMLINK && oi->oi_nlink == 0)
    	change_size(oi,0);
    
    
	return 0;
}
Beispiel #7
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	uint32_t blockno;
	uint32_t off = 1;
	int ret;
	uint32_t entry_off;

	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	/* EXERCISE: Your code here. */
	// Search through the directory block
	for (entry_off = 0; entry_off < dir_oi->oi_size;
	     entry_off += OSPFS_DIRENTRY_SIZE) {
		// Find the OSPFS inode for the entry
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, entry_off);

		// Set 'entry_inode' if we find the file we are looking for
		if (od->od_ino == 0) {
			return od;
		}
	}
	if ((ret = change_size(dir_oi, dir_oi->oi_size + OSPFS_DIRENTRY_SIZE))) {
		return NULL;
	}
	return create_blank_direntry(dir_oi);
}
Beispiel #8
0
static int
ospfs_unlink(uint32_t i_ino, char *d_name)
{
	ospfs_inode_t *oi = ospfs_inode(i_ino); // figure this out???
	ospfs_inode_t *dir_oi = ospfs_inode(i_ino);
	int entry_off;
	ospfs_direntry_t *od;

	od = NULL; // silence compiler warning; entry_off indicates when !od
	for (entry_off = 0; entry_off < dir_oi->oi_size;
	     entry_off += OSPFS_DIRENTRY_SIZE) {
		od = ospfs_inode_data(dir_oi, entry_off);
		if (od->od_ino > 0
		    && strlen(od->od_name) == strlen(d_name)
		    && memcmp(od->od_name, d_name, strlen(d_name)) == 0)
			break;
	}

	if (entry_off == dir_oi->oi_size) {
		return -ENOENT;
	}

	od->od_ino = 0;
	oi->oi_nlink--;
	return 0;
}
Beispiel #9
0
int
ospfs_dir_readdir(uint32_t i_ino, int *pos, ospfs_direntry_t **_od)
{
	ospfs_inode_t *dir_oi = ospfs_inode(i_ino);
	uint32_t f_pos = *pos;
	int r = -1;
	int entry_off;

	entry_off = f_pos * OSPFS_DIRENTRY_SIZE;
	if (f_pos >= 0 && entry_off < dir_oi->oi_size) {
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, entry_off);
		ospfs_inode_t *oi;

		/* If at the end of the directory, set 'r' to 1 and exit
		 * the loop.  For now we do this all the time.
		 */
		if (od->od_ino <= 0) {
			r = -1;
			*_od = NULL;
		} else {
			r = 0;
			f_pos++;
			*_od = od;
		}
	}

	// Save the file position and return!
	*pos = f_pos;
	return r;
}
Beispiel #10
0
static int
ospfs_unlink(struct inode *dirino, struct dentry *dentry)
{
	ospfs_inode_t *oi = ospfs_inode(dentry->d_inode->i_ino);
	ospfs_inode_t *dir_oi = ospfs_inode(dentry->d_parent->d_inode->i_ino);
	int entry_off;
	ospfs_direntry_t *od;

	od = NULL; // silence compiler warning; entry_off indicates when !od
	for (entry_off = 0; entry_off < dir_oi->oi_size;
	     entry_off += OSPFS_DIRENTRY_SIZE) {
		od = ospfs_inode_data(dir_oi, entry_off);
		if (od->od_ino > 0
		    && strlen(od->od_name) == dentry->d_name.len
		    && memcmp(od->od_name, dentry->d_name.name, dentry->d_name.len) == 0)
			break;
	}

	if (entry_off == dir_oi->oi_size) {
		printk("<1>ospfs_unlink should not fail!\n");
		return -ENOENT;
	}

	od->od_ino = 0;
	oi->oi_nlink--;

	// if not a symlink, delete file data when all links are gone
	if (oi->oi_ftype != OSPFS_FTYPE_SYMLINK && oi->oi_nlink == 0)
		return change_size(oi, 0);

	return 0;
}
Beispiel #11
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	/* EXERCISE: Your code here. */
	int off;
	for (off = 0; off < dir_oi->oi_size; off += OSPFS_DIRENTRY_SIZE) {
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, off);
		if (od->od_ino == 0)
			return od;
	}
	if (add_block(dir_oi) == -ENOSPC)
		return ERR_PTR(-EINVAL);
	return ospfs_inode_data(dir_oi, off);
}
Beispiel #12
0
static ospfs_direntry_t *
find_direntry(ospfs_inode_t *dir_oi, const char *name, int namelen)
{
	int off;
	if (namelen < 0)
		namelen = strlen(name);
	for (off = 0; off < dir_oi->oi_size; off += OSPFS_DIRENTRY_SIZE) {
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, off);
		if (od->od_ino
		    && strlen(od->od_name) == namelen
		    && memcmp(od->od_name, name, namelen) == 0)
			return od;
	}
	return 0;
}
Beispiel #13
0
static ospfs_direntry_t *
create_blank_direntry(ospfs_inode_t *dir_oi)
{
	// Outline:
	// 1. Check the existing directory data for an empty entry.  Return one
	//    if you find it.
	// 2. If there's no empty entries, add a block to the directory.
	//    Use ERR_PTR if this fails; otherwise, clear out all the directory
	//    entries and return one of them.

	/* EXERCISE: Your code here. */
	//return ERR_PTR(-EINVAL); // Replace this line
	ospfs_direntry_t* dentry;
	int offset;
	for (offset = 0; (offset*OSPFS_DIRENTRY_SIZE)<dir_oi->oi_size; offset++)
	{
		//ospfs_inode_data(oi, offset)
		dentry = ospfs_inode_data(dir_oi, offset*OSPFS_DIRENTRY_SIZE);
		if (dentry->od_ino == 0)
			return dentry;
		else 
			continue;
	}
	//no empty entries, add a block to the directory.
	int retval;
	//add_block(ospfs_inode_t *oi)
	retval = add_block (dir_oi);
	if (retval<0)
		return ERR_PTR(retval);
	else //add block success
	{
		dentry = ospfs_inode_data(dir_oi, offset*OSPFS_DIRENTRY_SIZE);	//the new block entry;
		return dentry;
	}

}
Beispiel #14
0
static struct dentry *
ospfs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *ignore)
{
	// Find the OSPFS inode corresponding to 'dir'
	ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino);
	struct inode *entry_inode = NULL;
	int entry_off;

	// Make sure filename is not too long
	if (dentry->d_name.len > OSPFS_MAXNAMELEN)
		return (struct dentry *) ERR_PTR(-ENAMETOOLONG);

	// Mark with our operations
	dentry->d_op = &ospfs_dentry_ops;

	// Search through the directory block
	for (entry_off = 0; entry_off < dir_oi->oi_size;
	     entry_off += OSPFS_DIRENTRY_SIZE) {
		// Find the OSPFS inode for the entry
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, entry_off);

		// Set 'entry_inode' if we find the file we are looking for
		if (od->od_ino > 0
		    && strlen(od->od_name) == dentry->d_name.len
		    && memcmp(od->od_name, dentry->d_name.name, dentry->d_name.len) == 0) {
			entry_inode = ospfs_mk_linux_inode(dir->i_sb, od->od_ino);
			if (!entry_inode)
				return (struct dentry *) ERR_PTR(-EINVAL);
			break;
		}
	}

	// We return a dentry whether or not the file existed.
	// The file exists if and only if 'entry_inode != NULL'.
	// If the file doesn't exist, the dentry is called a "negative dentry".

	// d_splice_alias() attaches the inode to the dentry.
	// If it returns a new dentry, we need to set its operations.
	if ((dentry = d_splice_alias(entry_inode, dentry)))
		dentry->d_op = &ospfs_dentry_ops;
	return dentry;
}
Beispiel #15
0
static int
ospfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	struct inode *dir_inode = filp->f_dentry->d_inode;
	ospfs_inode_t *dir_oi = ospfs_inode(dir_inode->i_ino);
	uint32_t f_pos = filp->f_pos;
	int r = 0;		/* Error return value, if any */
	int ok_so_far = 0;	/* Return value from 'filldir' */

	// f_pos is an offset into the directory's data, plus two.
	// The "plus two" is to account for "." and "..".
	if (r == 0 && f_pos == 0) {
		ok_so_far = filldir(dirent, ".", 1, f_pos, dir_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	if (r == 0 && ok_so_far >= 0 && f_pos == 1) {
		ok_so_far = filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	// actual entries
	while (r == 0 && ok_so_far >= 0 && f_pos >= 2) {
		/* If at the end of the directory, set 'r' to 1 and exit
		 * the loop.  For now we do this all the time.
		 *
		*/
		/* EXERCISE: Your code here */
		// bounds checking
		if(((f_pos-2)*OSPFS_DIRENTRY_SIZE >= dir_oi->oi_size))
		{
		  r = 1;		/* Fix me! */
		  break;		/* Fix me! */
		}
		
		/* Get a pointer to the next entry (od) in the directory.
		 * The file system interprets the contents of a
		 * directory-file as a sequence of ospfs_direntry structures.
		 * You will find 'f_pos' and 'ospfs_inode_data' useful.
		 *
		 * Then use the fields of that file to fill in the directory
		 * entry.  To figure out whether a file is a regular file or
		 * another directory, use 'ospfs_inode' to get the directory
		 * entry's corresponding inode, and check out its 'oi_ftype'
		 * member.
		 *
		 * Make sure you ignore blank directory entries!  (Which have
		 * an inode number of 0.)
		 *
		 * If the current entry is successfully read (the call to
		 * filldir returns >= 0), or the current entry is skipped,
		 * your function should advance f_pos by the proper amount to
		 * advance to the next directory entry.
		 */
		/* EXERCISE: Your code here */
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi,(f_pos-2)*OSPFS_DIRENTRY_SIZE);
		// ignore and advance
		if(od->od_ino == 0)
		{
		  f_pos++;
		  continue;
		}
		ospfs_inode_t *entry_oi = ospfs_inode(od->od_ino);
		
		// call filldir based on type
		if(entry_oi->oi_ftype == OSPFS_FTYPE_REG) {
		  ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_LNK);
		}
		else if(entry_oi->oi_ftype == OSPFS_FTYPE_DIR) {
		  ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_LNK);
		}
		else if(entry_oi->oi_ftype == OSPFS_FTYPE_SYMLINK) {
		  ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_LNK);
		}
		else
		  return -EFAULT;
		// ok so keep going
		if (ok_so_far >= 0)
			f_pos++;
	}

	// Save the file position and return!
	filp->f_pos = f_pos;
	return r;
}
Beispiel #16
0
static int
ospfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	struct inode *dir_inode = filp->f_dentry->d_inode;
	ospfs_inode_t *dir_oi = ospfs_inode(dir_inode->i_ino);
	uint32_t f_pos = filp->f_pos;
	int r = 0;		/* Error return value, if any */
	int ok_so_far = 0;	/* Return value from 'filldir' */

	// f_pos is an offset into the directory's data, plus two.
	// The "plus two" is to account for "." and "..".
	if (r == 0 && f_pos == 0) {
		ok_so_far = filldir(dirent, ".", 1, f_pos, dir_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	if (r == 0 && ok_so_far >= 0 && f_pos == 1) {
		ok_so_far = filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	// actual entries
	while (r == 0 && ok_so_far >= 0 && f_pos >= 2) {
		ospfs_direntry_t *od;
		ospfs_inode_t *entry_oi;

		/* If at the end of the directory, set 'r' to 1 and exit
		 * the loop.  For now we do this all the time.
		 */
		if (f_pos > dir_oi->oi_size * OSPFS_DIRENTRY_SIZE) { /* TODO: error cond */
			r = 1;
			break;
		}

		/* Get a pointer to the next entry (od) in the directory.
		 * The file system interprets the contents of a
		 * directory-file as a sequence of ospfs_direntry structures.
		 * You will find 'f_pos' and 'ospfs_inode_data' useful.
		 *
		 * Then use the fields of that file to fill in the directory
		 * entry.  To figure out whether a file is a regular file or
		 * another directory, use 'ospfs_inode' to get the directory
		 * entry's corresponding inode, and check out its 'oi_ftype'
		 * member.
		 *
		 * Make sure you ignore blank directory entries!  (Which have
		 * an inode number of 0.)
		 *
		 * If the current entry is successfully read (the call to
		 * filldir returns >= 0), or the current entry is skipped,
		 * your function should advance f_pos by the proper amount to
		 * advance to the next directory entry.
		 */

		// get inode
		od = ospfs_inode_data(dir_oi, f_pos * OSPFS_DIRENTRY_SIZE);
		entry_oi = ospfs_inode(od->od_ino);

		// ignore blank directory entries
		if(entry_oi != 0) {
			// determine filetype
			switch(entry_oi->oi_ftype) {
				case OSPFS_FTYPE_REG:
					ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_REG);
					break;
				case OSPFS_FTYPE_DIR:
					ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_DIR);
					break;
				case OSPFS_FTYPE_SYMLINK:
					ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_LNK);
					break;
				default: eprintk("Mystery error!\n"); r=1; continue;

			}
		}

		f_pos++;
	}

	// Save the file position and return!
	filp->f_pos = f_pos;
	return r;
}
Beispiel #17
0
static int
ospfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	struct inode *dir_inode = filp->f_dentry->d_inode;
	ospfs_inode_t *dir_oi = ospfs_inode(dir_inode->i_ino);
	uint32_t f_pos = filp->f_pos;
	int r = 0;    	/* Error return value, if any */
	int ok_so_far = 0;	/* Return value from 'filldir' */

	// f_pos is an offset into the directory's data, plus two.
	// The "plus two" is to account for "." and "..".
	if (r == 0 && f_pos == 0) {
    	ok_so_far = filldir(dirent, ".", 1, f_pos, dir_inode->i_ino, DT_DIR);
    	if (ok_so_far >= 0)
        	f_pos++;
	}

	if (r == 0 && ok_so_far >= 0 && f_pos == 1) {
    	ok_so_far = filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
    	if (ok_so_far >= 0)
        	f_pos++;
	}

	// actual entries
	while (r == 0 && ok_so_far >= 0 && f_pos >= 2) {
    	ospfs_direntry_t *od;
    	ospfs_inode_t *entry_oi;

    	/* If at the end of the directory, set 'r' to 1 and exit
     	* the loop.  For now we do this all the time.
     	*
     	* EXERCISE: Your code here */ 
    	//r = 1;    	/* Fix me! */
    	//break;    	/* Fix me! */
   	 
    	//If we found the end, set r to 1 and break
    	//how to find end?
    	//dir_oi pulls up inode struct for our file
    	//we then pull up its property oi_size which gives us file size
    	//then we have to multiply file size by size of each entry
    	//when f_pos gets past that, we know we've hit the end
    	if (f_pos >= dir_oi->oi_size * OSPFS_DIRENTRY_SIZE) {
        	r = 1;
        	break;
    	}

    	/* Get a pointer to the next entry (od) in the directory.
     	* The file system interprets the contents of a
     	* directory-file as a sequence of ospfs_direntry structures.
     	* You will find 'f_pos' and 'ospfs_inode_data' useful.
     	*
     	* Then use the fields of that file to fill in the directory
     	* entry.  To figure out whether a file is a regular file or
     	* another directory, use 'ospfs_inode' to get the directory
     	* entry's corresponding inode, and check out its 'oi_ftype'
     	* member.
     	*
     	* Make sure you ignore blank directory entries!  (Which have
     	* an inode number of 0.)
     	*
     	* If the current entry is successfully read (the call to
     	* filldir returns >= 0), or the current entry is skipped,
     	* your function should advance f_pos by the proper amount to
     	* advance to the next directory entry.
     	*/

    	/* EXERCISE: Your code here */ 
   	 
    	//get pointer to nex entry -> put in od
    	//offset for ospfs_inode_data = (f_pos - 2) * size of each entry
    	od = ospfs_inode_data(dir_oi, (f_pos-2)*OSPFS_DIRENTRY_SIZE);
    	entry_oi = ospfs_inode(od->od_ino);
   	 
    	//if od's ino = 0 or entry is null, increment f_pos
    	if (od->od_ino == 0 || entry_oi == NULL) {
        	f_pos++;
    	}

    	int ftype;
    	if (r == 0 && ok_so_far >= 0)
    	{
        	switch(entry_oi->oi_ftype)
        	{
            	case OSPFS_FTYPE_DIR:
            	{
            	ftype = DT_DIR;
            	break;
            	}
            	case OSPFS_FTYPE_REG:
            	{
            	ftype = DT_REG;
            	break;
            	}
            	case OSPFS_FTYPE_SYMLINK:
            	{
            	ftype = DT_LNK;
            	break;
            	}
        	}
    	ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, ftype);
    	}
   	 
    	if (ok_so_far >= 0)
        	f_pos++;

	}

	// Save the file position and return!
	filp->f_pos = f_pos;
	return r;
}
Beispiel #18
0
static int
ospfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	struct inode *dir_inode = filp->f_dentry->d_inode;
	ospfs_inode_t *dir_oi = ospfs_inode(dir_inode->i_ino);
	uint32_t f_pos = filp->f_pos;
	int r = 0;		/* Error return value, if any */
	int ok_so_far = 0;	/* Return value from 'filldir' */

	// f_pos is an offset into the directory's data, plus two.
	// The "plus two" is to account for "." and "..".
	if (r == 0 && f_pos == 0) {
		ok_so_far = filldir(dirent, ".", 1, f_pos, dir_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	if (r == 0 && ok_so_far >= 0 && f_pos == 1) {
		ok_so_far = filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
		if (ok_so_far >= 0)
			f_pos++;
	}

	/* EXERCISE: Your code here */
	// actual entries
	while (r == 0 && ok_so_far >= 0 && f_pos >= 2 && f_pos < dir_oi->oi_size) {
		ospfs_direntry_t *od = ospfs_inode_data(dir_oi, f_pos-2);
		ospfs_inode_t *entry_oi = ospfs_inode(od->od_ino);			

		//Skip entry if inode number is 0
		if(od->od_ino > 0 && entry_oi && entry_oi->oi_nlink > 0){			
			//eprintk("inode: %d, name:%s\n", od->od_ino, od->od_name);
			switch(entry_oi->oi_ftype){
					case OSPFS_FTYPE_REG:
						ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_REG);
						break;

					case OSPFS_FTYPE_DIR:
						ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_DIR);
						break;

					case OSPFS_FTYPE_SYMLINK:	
					ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos, od->od_ino, DT_LNK);
						break;

					default:
						r = 0;
						continue;
			}
			
			//If error on filldir exit while loop and return 0
			if(ok_so_far < 0){
				return 0;		
			}
		}

		//Advance f_pos by dir entry size, if at the end of the directory, set 'r' to 1 and exit
		f_pos += sizeof(OSPFS_DIRENTRY_SIZE);
		if(f_pos-2 >= dir_oi->oi_size){
			r = 1;		
		}
	}

	// Save the file position and return!
	filp->f_pos = f_pos;
	return r;
}