Beispiel #1
0
static int newfs_utimens(const char *path, const struct timespec ts[2]){
    char message[1024];
    sprintf(message, "newfs_utimens: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system looking for the file */
    fcb current; uuid_t current_key; 
    int rec = get_fcb_from_tokens(&current, &current_key, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_utimens: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_utimens: failure ENOTDIR\n");
        return rec;
    }

    /* update the times */
    current.atime = ts[0].tv_nsec;
    current.mtime = ts[1].tv_nsec;

    /* store the updated fcb */
    store_fcb(current, current_key);
    write_log_fuse("newfs_utimens: success\n");
    return 0;
}
Beispiel #2
0
static int newfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
    char message[1024];
    sprintf(message, "newfs_read: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system to find the file */
    fcb current;
    int rec = get_fcb_from_tokens(&current, NULL, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_read: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_read: failure ENOTDIR\n");
        return rec;
    }

    /* read from the file into buf */
    int amount_read = fetch_filedata(buf, &current, size, offset);

    write_log_fuse("newfs_read: success\n");
    return amount_read;
}
Beispiel #3
0
static int newfs_chown(const char *path, uid_t uid, gid_t gid){
    char message[1024];
    sprintf(message, "newfs_chown: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system looking for the final file in path */
    fcb current; uuid_t current_key; 
    int rec = get_fcb_from_tokens(&current, &current_key, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_chown: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_chown: failure ENOTDIR\n");
        return rec;
    }

    /* update the file owners */
    current.uid = uid;
    current.gid = gid;

    /* store the updated fcb */
    store_fcb(current, current_key);
    write_log_fuse("newfs_chown: success\n");
    return 0;
}
Beispiel #4
0
static int newfs_open(const char *path, struct fuse_file_info * fi){
    char message[1024];
    sprintf(message, "newfs_open: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* look for the file to check that it exists */
    fcb current;
    int rec = get_fcb_from_tokens(&current, NULL, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_open: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_open: failure ENOTDIR\n");
        return rec;
    }
    
    /* we don't use file handles so as long as the file exists we're good */

    write_log_fuse("newfs_open: success\n");
    return 0;
}
Beispiel #5
0
static int newfs_getattr(const char *path, struct stat *stbuf){
    char message[1024];
    sprintf(message, "newfs_getattr: path = %s\n", path);
    write_log_fuse(message);

    /* split path into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);


    /* traverse the file system to find the relevent fcb */
    fcb current;
    int rec = get_fcb_from_tokens(&current, NULL, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_getattr: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_getattr: failure ENOTDIR\n");
        return rec;
    }

    /* copy the meta data from the fcb into stbuf */
    set_stat_from_fcb(&current, stbuf);

    write_log_fuse("newfs_getattr: success\n");
    return 0;
}
Beispiel #6
0
static int newfs_mkdir(const char *path, mode_t mode){
    char message[1024];
    sprintf(message, "newfs_mkdir: path = %s\n", path);
    write_log_fuse(message);

    /* split path into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system to find the fcb above where we want to add a dir */
    fcb parent; uuid_t parent_key;
    int rec = get_fcb_from_tokens(&parent, &parent_key, tokens, count - 1);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_mkdir: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_mkdir: failure ENOTDIR\n");
        return rec;
    }

    /* if the fcb above our target is not a directory, fail */
    if(!parent.dir){
        write_log_fuse("newfs_mkdir: failure ENOTDIR\n");
        return -ENOTDIR;
    }

    /* get the directory entries */
    dir_entry *dirs = malloc(sizeof(dir_entry) * parent.num_files);
    fetch_dirdata(dirs, parent.datakey, parent.num_files);
    int found=0, i=0;
    for(i = 0; i != parent.num_files; i++){ // look for our target in this directory
        if(strcmp(dirs[i].name, tokens[count-1]) == 0){
            found++;
        }
    }
    /* if the directory is found, then it can't be created */
    if(found){
        write_log_fuse("newfs_mkdir: failure EEXIST\n");
        return -EEXIST;
    }

    /* add one directory entry to the parent directory */
    uuid_t child_key;
    uuid_generate(child_key);
    init_dir_fcb(child_key, parent_key);
    parent.num_files++;
    dirs = realloc(dirs, sizeof(dir_entry) * parent.num_files);
    strcpy(dirs[parent.num_files-1].name, tokens[count-1]);
    uuid_copy(dirs[parent.num_files-1].key, child_key);
    store_dirdata(dirs, parent.datakey, parent.num_files);
    parent.size = sizeof(dir_entry) * parent.num_files;
    store_fcb(parent, parent_key);

    write_log_fuse("newfs_mkdir: success\n"); 
    return 0;
}
Beispiel #7
0
static int newfs_create(const char *path, mode_t mode, struct fuse_file_info *fi){
    char message[1024];
    sprintf(message, "newfs_create: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system looking for the directory above our target file */
    fcb parent; uuid_t parent_key;
    int rec = get_fcb_from_tokens(&parent, &parent_key, tokens, count - 1);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_create: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_create: failure ENOTDIR\n");
        return rec;
    }
    if(!parent.dir){
        write_log_fuse("newfs_create: failure ENOTDIR\n");
        return -ENOTDIR;
    }

    /* get the directory data and look for the target */
    dir_entry *dirs = malloc(sizeof(dir_entry) * parent.num_files);
    fetch_dirdata(dirs, parent.datakey, parent.num_files);
    int found=0, i=0;
    for(i = 0; i != parent.num_files; i++){
        if(strcmp(dirs[i].name, tokens[count-1]) == 0){
            found++;
        }
    }
    if(found){
        write_log_fuse("newfs_create: failure EEXIST\n");
        return -EEXIST;
    }

    /* if all is well, create a new file and store the updated fcb */
    uuid_t child_key;
    uuid_generate(child_key);
    init_file_fcb(child_key);
    parent.num_files++;
    dirs = realloc(dirs, sizeof(dir_entry) * parent.num_files);
    strcpy(dirs[parent.num_files-1].name, tokens[count-1]);
    uuid_copy(dirs[parent.num_files-1].key, child_key);
    store_dirdata(dirs, parent.datakey, parent.num_files);

    parent.size = sizeof(dir_entry) * parent.num_files;
    store_fcb(parent, parent_key);

    write_log_fuse("newfs_create: success\n"); 
    return 0;
}
Beispiel #8
0
static int newfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
    char message[1024];
    sprintf(message, "newfs_write: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system to find the file */
    fcb current; uuid_t current_key; 
    int rec = get_fcb_from_tokens(&current, &current_key, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_write: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_write: failure ENOTDIR\n");
        return rec;
    }

    /* calculate what size the file will be after the write */
    unsigned int final_file_size;
    unsigned int temp = offset + size; // offset is a signed type so weird stuff happens

    if(temp > current.size){
        final_file_size = (unsigned int)offset + size;
    } else {
        final_file_size = current.size;
    }

    /* put the current file data into a buffer */
    char *filedata = malloc(final_file_size);
    fetch_filedata(filedata, &current, final_file_size, 0); 

    /* copy the data from the buf into the same buffer as our current file data */
    memcpy(filedata + (unsigned int)offset, buf, size);
    current.size = final_file_size; 

    /* store the now updated file data and fcb */
    store_filedata(filedata, current.datakey, current.size); 
    store_fcb(current, current_key);
    free(filedata);
    write_log_fuse("newfs_write: success\n");
    return size;
}
Beispiel #9
0
static int newfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi){
    char message[1024];
    sprintf(message, "newfs_readdir: path = %s\n", path);
    write_log_fuse(message);
 
    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count;
    tokenize_path(tokens, path, &count);

    /* traverse the file system to find the current directory */
    fcb current;
    int rec = get_fcb_from_tokens(&current, NULL, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_readdir: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_readdir: failure ENOTDIR\n");
        return rec;
    }
    if(!current.dir){
        write_log_fuse("newfs_readdir: failure ENOTDIR\n");
        return -ENOTDIR;
    }

    /* get the directory entries */
    dir_entry *dirs = malloc(sizeof(dir_entry) * current.num_files);
    fetch_dirdata(dirs, current.datakey, current.num_files);
    int i;
    for(i = 0; i != current.num_files; i++){
        fcb child = fetch_fcb(dirs[i].key);
        struct stat child_stat;
        set_stat_from_fcb(&child, &child_stat); // set a stat for each file in the directory
        int rec = filler(buf, dirs[i].name, &child_stat, 0); // use filler to fill the buf with this information
        if(rec != 0){
            write_log_fuse("newfs_readdir: failure (filler failed)\n");
            return rec;
        }
    }

    free(dirs);
    write_log_fuse("newfs_readdir: success\n"); 
    return 0;
}
Beispiel #10
0
static int newfs_truncate(const char * path, off_t size){
    char message[1024];
    sprintf(message, "newfs_truncate: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system looking for the file */
    fcb current; uuid_t current_key; 
    int rec = get_fcb_from_tokens(&current, &current_key, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_truncate: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_truncate: failure ENOTDIR\n");
        return rec;
    }

    /* decide if the file should be bigged or smaller */
    int max_size = current.size; // the minimum the buffer can be is the current size because we need to fetch all the data
    if(size > current.size){
        max_size = size;
    }

    /* get the file data from the store */
    char *filedata = malloc(max_size);
    fetch_filedata(filedata, &current, current.size, 0); 

    /* update the size */
    current.size = size;

    /* store the updated file data and fcb */
    store_filedata(filedata, current.datakey, current.size); 
    store_fcb(current, current_key);
    free(filedata);
    write_log_fuse("newfs_truncate: success\n");
    return size;
}
Beispiel #11
0
int sfs_delete(char *pathname)
{
	char** tokens;
	uint32_t* parent_location = NULL;
	locations index_block = {NULL};
	locations inode_loc = (locations) calloc(2, sizeof(uint32_t));
	int type = -1;

	if(strlen(pathname) == 1)
	{
		print_error(INVALID_PATH);
		return -1;
	}

	/*
	 * Parse the pathname
	 */
	tokens = tokenize_path(pathname);
	if(tokens == NULL)
	{
		print_error(INVALID_PATH);
		return 0;
	}

	/*
	 * Traverse the file system to find the desired inode
	 * get the inode above the one you desired
	 */
	parent_location = traverse_file_system(tokens, true);

	if(parent_location == NULL)
	{
		/*
		 * Parent not found
		 */
		print_error(PARENT_NOT_FOUND);
		return -1;
	}

	/*if (parent_location[0] = get_root() && tokens[parent_location[1]] == NULL)
	{
		print_error(INVALID_PARAMETER);
		return -1;
	}*/

	index_block = iterate_index(get_index_block(parent_location[0]), NULL);
	if(index_block == NULL)
	{
		/*
		 * Empty or no index block
		 */
		print_error(INDEX_ALLOCATION_ERROR);
		return 0;
	}

	/*
	 * Find the inode of the file or directory with the given file name in the
	 * given index block list
	 */
	inode_loc[0] = find_inode(index_block, tokens[parent_location[1]]);

	if(inode_loc[0] == NULL)
	{
		/*
		 * Inode not found
		 */
		print_error(FILE_NOT_FOUND);
		return 0;
	}

	/*
	 * Check if it is a directory
	 */
	type = get_type(inode_loc[0]);


	index_block = iterate_index(get_index_block(inode_loc[0]), NULL);

	if(index_block == NULL)
	{
		/*
		 * Invalid index block
		 */
		print_error(INDEX_ALLOCATION_ERROR);
		return -1;
	}

	if (type == 1)
	{
		if(index_block[0] != NULL)
		{
			/*
			 * Directory has children
			 */
			print_error(DIRECTORY_HAS_CHILDREN);
			return 0;
		}
	}

	/*
	 * Delete all swoft entries for the given file
	 */
	printf("Number swoft entries remove: %d\n",find_and_remove(inode_loc[0]));

	if(unlink_inode_from_parent(parent_location[0], inode_loc[0]) < 0)
	{
		if(reset_fbl() == NULL)
		{
			print_error(ERROR_UPDATING_FBL);
			return -2;
		}

		print_error(ERROR_BLOCK_LINKAGE);
		return -1;
	}

	else if(type == 0)
	{
		/*
		 * Delete the data blocks (each time update the free_block list)
		 */
		if(update_fbl(NULL, index_block) == NULL)
		{
			print_error(ERROR_UPDATING_FBL);
			return -1;
		}
	}

	/*
	 * Delete the index blocks (each time update the free_block list)
	 */
	if(update_fbl(NULL, index_block_locations(get_index_block(inode_loc[0]), NULL)) == NULL)
	{
		print_error(ERROR_UPDATING_FBL);
		return -1;
	}

	/*
	 * Delete the Inode block (update the free_block list)
	 */
	if(update_fbl(NULL, inode_loc) == NULL)
	{
		print_error(ERROR_UPDATING_FBL);
		return -1;
	}

	/*
	 * Sync FBL, write FBL in memory to disk
	 */
	if(sync_fbl() == NULL)
	{
		print_error(ERROR_UPDATING_FBL);
		return -1;
	}

	/*
	 * return value > 0 then the file was deleted successfully.
	 * return value <= 0 then the file failed to be delete.
	 */
	print_error(SUCCESS);
	return 1;
}
Beispiel #12
0
static void
sanitize_path(char *buffer, size_t buffer_size, size_t input_length)
{
	char scratch[512];
	int i;
	int segcount;
	int dotdot_drops = 0;
	strseg segments[64];

	strcpy(scratch, buffer);
	segcount = tokenize_path(scratch, segments, sizeof(segments) / sizeof(segments[0]));

	for (i = segcount - 1; i >= 0; --i)
	{
		if (segments[i].drop)
			continue;

		if (segments[i].dotdot)
		{
			++dotdot_drops;
			segments[i].drop = 1;
		}
		else if (dotdot_drops > 0)
		{
			--dotdot_drops;
			segments[i].drop = 1;
		}
	}

	/* Format the resulting path. It can never get longer by this operation, so
	 * there's no need to check the buffer size. */
	{
		int emit_slash = 0;
		char *cursor = buffer;

		/* Emit all leading ".." tokens we've got left */
		for (i = 0; i < dotdot_drops; ++i)
		{
			memcpy(cursor, ".." TD_PATHSEP_STR, 3);
			cursor += 3;
		}

		/* Emit all remaining tokens. */
		for (i = 0; i < segcount; ++i)
		{
			int len = segments[i].len;
			const char *seg = segments[i].ptr;

			if (segments[i].drop)
				continue;

			if (emit_slash)
				*cursor++ = TD_PATHSEP;
			emit_slash = 1;

			memcpy(cursor, seg, len);
			cursor += len;
		}
		*cursor = 0;
	}
}
Beispiel #13
0
static int newfs_access(const char * path, int mask){
    char message[1024];
    sprintf(message, "newfs_access: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* traverse the file system to find the file */
    fcb current; uuid_t current_key; 
    int rec = get_fcb_from_tokens(&current, &current_key, tokens, count);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_access: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_access: failure ENOTDIR\n");
        return rec;
    }

    /* if we're just checking that the file exists, return ok because at this point it definitely does */
    if(mask == F_OK){
        return 0;
    }

    /* get the fuse uid and gid */
    struct fuse_context *context = fuse_get_context();
    uid_t r_uid = context->uid;
    gid_t r_gid = context->gid;

    int want_read = R_OK & mask;
    int want_write = W_OK & mask;
    int want_exe = X_OK & mask;

    /* for each of the tasks, check that the user is allowed to perform them (if they want to) */
    if(want_read){
        if(current.mode & S_IROTH)
            goto check_write;
        if((r_gid == current.gid) && (current.mode & S_IRGRP))
            goto check_write;
        if((r_uid == current.uid) && (current.mode & S_IRUSR))
            goto check_write;
        return -EACCES;
    }
    check_write:
    if(want_write){
        if(current.mode & S_IWOTH)
            goto check_exe;
        if((r_gid == current.gid) && (current.mode & S_IWGRP))
            goto check_exe;
        if((r_uid == current.uid) && (current.mode & S_IWUSR))
            goto check_exe;
        return -EACCES;
    }
    check_exe:
    if(want_exe){
        if(current.mode & S_IXOTH)
            return 0;
        if((r_gid == current.gid) && (current.mode & S_IXGRP))
            return 0;
        if((r_uid == current.uid) && (current.mode & S_IXUSR))
            return 0;
        return -EACCES;
    }
    return 0;
}
Beispiel #14
0
static int newfs_rename(const char *path, const char *to){
    char message[1024];
    sprintf(message, "newfs_rename: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* get the directory above the target file */
    fcb parent; uuid_t parent_key;
    int rec = get_fcb_from_tokens(&parent, &parent_key, tokens, count - 1);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_rename: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_rename: failure ENOTDIR\n");
        return rec;
    }

    int to_remove = 0;
    uuid_t move_key;

    /* get the directory data for this directory */
    dir_entry *dirs = malloc(sizeof(dir_entry) * parent.num_files);
    fetch_dirdata(dirs, parent.datakey, parent.num_files);
    int found=0, i=0;
    for(i = 0; i != parent.num_files; i++){ // look for the target
        if(strcmp(dirs[i].name, tokens[count-1]) == 0){ // if it is found, remember
            found++;
            to_remove = i;
            uuid_copy(move_key, dirs[i].key);
        }
    }
    if(!found){
        write_log_fuse("newfs_rmdir: failure ENOENT\n");
        return -ENOENT;
    }

    /* reconstruct the dirdata, skipping the file to be moved */
    int offset = 0;
    dir_entry *newdirs = malloc(sizeof(dir_entry) * (parent.num_files - 1));
    for(i = 0; i != parent.num_files; i++){
        if(i == to_remove){
            continue;
        }
        strcpy(newdirs[offset].name, dirs[i].name);
        uuid_copy(newdirs[offset].key, dirs[i].key);
        offset++;
    }

    /* update the original parent directory */
    parent.num_files--;
    store_dirdata(newdirs, parent.datakey, parent.num_files);

    parent.size = sizeof(dir_entry) * parent.num_files;
    store_fcb(parent, parent_key);

    free(dirs);
    free(newdirs);

    /* split the target path up into its parts */
    tokenize_path(tokens, to, &count);
    rec = get_fcb_from_tokens(&parent, &parent_key, tokens, count - 1);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_rename: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_rename: failure ENOTDIR\n");
        return rec;
    }

    /* get the new directory data for the target */
    dirs = malloc(sizeof(dir_entry) * parent.num_files);
    fetch_dirdata(dirs, parent.datakey, parent.num_files);
    for(i = 0; i != parent.num_files; i++){
        if(strcmp(dirs[i].name, tokens[count-1]) == 0){
            write_log_fuse("newfs_rename: failure EEXIST");
            return -EEXIST;
        }
    }

    /* add the file to the new directory and update the new parent */
    parent.num_files++;
    dirs = realloc(dirs, sizeof(dir_entry) * parent.num_files);
    strcpy(dirs[parent.num_files-1].name, tokens[count-1]);
    uuid_copy(dirs[parent.num_files-1].key, move_key);

    store_dirdata(dirs, parent.datakey, parent.num_files);

    parent.size = sizeof(dir_entry) * parent.num_files;
    store_fcb(parent, parent_key);

    write_log_fuse("newfs_rename: success\n"); 
    return 0;
}
Beispiel #15
0
static int newfs_rmdir(const char *path){
    char message[1024];
    sprintf(message, "newfs_rmdir: path = %s\n", path);
    write_log_fuse(message);

    /* split the path up into its parts */
    char tokens[1024][NAME_MAX]; int count; 
    tokenize_path(tokens, path, &count);

    /* get the directory above the target */
    fcb parent; uuid_t parent_key;
    int rec = get_fcb_from_tokens(&parent, &parent_key, tokens, count - 1);
    if(rec != 0){
        if(rec == -ENOENT)
            write_log_fuse("newfs_rmdir: failure ENOENT\n");
        if(rec == -ENOTDIR)
            write_log_fuse("newfs_rmdir: failure ENOTDIR\n");
        return rec;
    }
    if(!parent.dir){
        write_log_fuse("newfs_rmdir: failure ENOTDIR\n");
        return -ENOTDIR;
    }

    int to_remove = 0;
    int size_to_remove = 0;

    /* get the directory entries for the directory */
    dir_entry *dirs = malloc(sizeof(dir_entry) * parent.num_files);
    fetch_dirdata(dirs, parent.datakey, parent.num_files);
    int found=0, i=0;
    for(i = 0; i != parent.num_files; i++){ // look for the target
        if(strcmp(dirs[i].name, tokens[count-1]) == 0){ // if it is found, remember
            found++;
            to_remove = i;
            fcb fcb_to_remove = fetch_fcb(dirs[i].key);
            size_to_remove = fcb_to_remove.size;
        }
    }
    if(!found){
        write_log_fuse("newfs_rmdir: failure ENOENT\n");
        return -ENOENT;
    }
    /* if the target contains anything, do not remove it */
    if(size_to_remove > sizeof(dir_entry) * 2){
        write_log_fuse("newfs_rmdir: failure ENOTEMPTY\n");
        return -ENOTEMPTY;
    }

    /* reconstruct the directory data, skipping the target */
    int offset = 0;
    dir_entry *newdirs = malloc(sizeof(dir_entry) * (parent.num_files - 1));
    for(i = 0; i != parent.num_files; i++){
        if(i == to_remove){
            continue;
        }
        strcpy(newdirs[offset].name, dirs[i].name);
        uuid_copy(newdirs[offset].key, dirs[i].key);
        offset++;
    }

    /* update the parent fcb */
    parent.num_files--;
    store_dirdata(newdirs, parent.datakey, parent.num_files);

    parent.size = sizeof(dir_entry) * parent.num_files;
    store_fcb(parent, parent_key);

    write_log_fuse("newfs_rmdir: success\n"); 
    return 0;
}
Beispiel #16
0
int sfs_getsize(char *pathname)
{
	int type = -1;
	int i = 1;
	uint32_t index_block = 0;
	locations inode_location = NULL;
	locations index_locations = NULL;
	char** tokens = NULL;
	int size = 0;

	/* Parse the pathname */
	tokens = tokenize_path(pathname);
	if(tokens == NULL)
	{
		/* Invalid pathname */
		print_error(INVALID_PATH);
		return -1;
	}

	/* Traverse the file system to find the desired inode */
	inode_location = traverse_file_system(tokens, false);

	if(inode_location == NULL)
	{
		/* Invalid path or file/directory not found */
		print_error(FILE_NOT_FOUND);
		return -1;
	}

	/*
	 * Check if it is a file or directory
	 * 	- If directory:
	 * 		Count entries
	 * 	- If file:
	 * 		get size
	 */
	type = get_type(inode_location[0]);

	index_locations = index_block_locations(inode_location[0], NULL);

	if(index_locations == NULL)
	{
		/*
		 * Invalid index block
		 */
		print_error(INDEX_ALLOCATION_ERROR);
		return -1;
	}

	/*
	 * Count the number of index blocks
	 */
	while(index_locations[i+1] != NULL)
	{
		i++;
	}

	/* Add the inode */
	i++;

	/* print out the number of index blocks + the inode block */
	printf("Overhead Size =  %d\n", i*BLKSIZE);

	if(type == 0)
	{
		/* Get the size of the file from the Inode return the
		 * size of the file
		 */
		size =  get_size(inode_location[0]);
		printf("Data Size = %d\n", size);
		return size;
	}
	else if(type == 1)
	{
		/* Get the index block's location */
		index_block = get_index_block(inode_location[0]);

		/* Return the number of locations found in the index block(s) */
		size = count_files_in_dir(index_block);
		printf("Size = %d\n", size);

		print_error(SUCCESS);
		return size;
	}

	print_error(INVALID_FILE_TYPE);
	return -1;
}