int vfs_getfree(char *filesystem) { fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(filesystem); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->getfree(fs); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_file(char *pathname, int idx, char *buffer) { char volumename[VFS_NAME_LENGTH]; char dirname[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, dirname) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->file(fs, dirname, idx, buffer); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
/** * Removes given file from filesystem. * * @param pathname Full name of the file, including mountpoint. * * @return VFS_OK on success, negative (VFS_*) on failure. * */ int vfs_remove(const char *pathname) { char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_INVALID_PARAMS; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->remove(fs, filename); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_create(char *pathname, int size) { char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; KERNEL_ASSERT(size >= 0); if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if(vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->create(fs, filename, size); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_file(char *pathname, int idx, char *buffer) { char volumename[VFS_NAME_LENGTH]; char dirname[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (pathname == NULL) { semaphore_P(vfs_table.sem); for (ret = 0; ret < CONFIG_MAX_FILESYSTEMS && idx != 0; ret++) { if (vfs_table.filesystems[ret].filesystem != NULL) idx--; } /* Error can be caused if idx was <= 0 or idx was higher than the * number of mounted volumes */ if (idx != 0) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_ERROR; } stringcopy(buffer, vfs_table.filesystems[ret].mountpoint, VFS_NAME_LENGTH); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_OK; } if (vfs_parse_pathname(pathname, volumename, dirname) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->file(fs, dirname, idx, buffer); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_write(openfile_t file, void *buffer, int datasize) { openfile_entry_t *openfile; fs_t *fs; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; openfile = vfs_verify_open(file); fs = openfile->filesystem; KERNEL_ASSERT(datasize >= 0 && buffer != NULL); ret = fs->write(fs, openfile->fileid, buffer, datasize, openfile->seek_position); if(ret > 0) { semaphore_P(openfile_table.sem); openfile->seek_position += ret; semaphore_V(openfile_table.sem); } vfs_end_op(); return ret; }
/** * Seek given file to given position. The position is not verified * to be within the file's size. * * @param file Open file * * @param seek_position New positive seek position. * * @return VFS_OK, panics on invalid arguments. * */ int vfs_seek(openfile_t file, int seek_position) { openfile_entry_t *openfile; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if(seek_position < 0) { return VFS_INVALID_PARAMS; } semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } openfile->seek_position = seek_position; semaphore_V(openfile_table.sem); vfs_end_op(); return VFS_OK; }
/** * Close open file. * * @param file Openfile id * * @return VFS_OK on success, negative (VFS_*) on error. * */ int vfs_close(openfile_t file) { openfile_entry_t *openfile; fs_t *fs; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } fs = openfile->filesystem; ret = fs->close(fs, openfile->fileid); openfile->filesystem = NULL; semaphore_V(openfile_table.sem); vfs_end_op(); return ret; }
int vfs_mount(fs_t *fs, char *name) { int i; int row; KERNEL_ASSERT(name != NULL && name[0] != '\0'); if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(vfs_table.sem); for (i = 0; i < CONFIG_MAX_FILESYSTEMS; i++) { if (vfs_table.filesystems[i].filesystem == NULL) break; } row = i; if(row >= CONFIG_MAX_FILESYSTEMS) { semaphore_V(vfs_table.sem); kprintf("VFS: Warning, maximum mount count exceeded, mount failed.\n"); vfs_end_op(); return VFS_LIMIT; } for (i = 0; i < CONFIG_MAX_FILESYSTEMS; i++) { if(stringcmp(vfs_table.filesystems[i].mountpoint, name) == 0) { semaphore_V(vfs_table.sem); kprintf("VFS: Warning, attempt to mount 2 filesystems " "with same name\n"); vfs_end_op(); return VFS_ERROR; } } stringcopy(vfs_table.filesystems[row].mountpoint, name, VFS_NAME_LENGTH); vfs_table.filesystems[row].filesystem = fs; semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_OK; }
int vfs_filecount(char *pathname) { char volumename[VFS_NAME_LENGTH]; char dirname[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (pathname == NULL) { semaphore_P(vfs_table.sem); for (ret = 0; ret < CONFIG_MAX_FILESYSTEMS; ret++) { if (vfs_table.filesystems[ret].filesystem == NULL) break; } semaphore_V(vfs_table.sem); vfs_end_op(); return ret; } if (vfs_parse_pathname(pathname, volumename, dirname) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->filecount(fs, dirname); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_unmount(char *name) { int i, row; fs_t *fs = NULL; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(vfs_table.sem); for (row = 0; row < CONFIG_MAX_FILESYSTEMS; row++) { if(!stringcmp(vfs_table.filesystems[row].mountpoint, name)) { fs = vfs_table.filesystems[row].filesystem; break; } } if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NOT_FOUND; } semaphore_P(openfile_table.sem); for(i = 0; i < CONFIG_MAX_OPEN_FILES; i++) { if(openfile_table.files[i].filesystem == fs) { semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_IN_USE; } } fs->unmount(fs); vfs_table.filesystems[row].filesystem = NULL; semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_OK; }
int vfs_seek(openfile_t file, int seek_position) { openfile_entry_t *openfile; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; KERNEL_ASSERT(seek_position >= 0); semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); openfile->seek_position = seek_position; semaphore_V(openfile_table.sem); vfs_end_op(); return VFS_OK; }
/** * Tells the given file's position. * * @param file Open file * * @return the file's seek position. Negative values on error * */ int vfs_tell(openfile_t file) { openfile_entry_t *openfile; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } int seek_position = openfile->seek_position; semaphore_V(openfile_table.sem); vfs_end_op(); return seek_position; }
/** * Writes datasize bytes from given buffer to given open file. * The write is started from current seek position and after writing, the * position is updated. * * @param file Open file * * @param buffer Buffer to be written to file. * * @param datasize Number of bytes to write. * * @return Number of bytes written. All bytes are written unless error * prevented to do that. Negative values are specific error conditions. * */ int vfs_write(openfile_t file, void *buffer, int datasize) { openfile_entry_t *openfile; fs_t *fs; int fileid, seek_position, ret; if (datasize < 0 || buffer == NULL) { return VFS_INVALID_PARAMS; } if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } fs = openfile->filesystem; fileid = openfile->fileid; seek_position = openfile->seek_position; semaphore_V(openfile_table.sem); ret = fs->write(fs, fileid, buffer, datasize, seek_position); if(ret > 0) { semaphore_P(openfile_table.sem); openfile->seek_position += ret; semaphore_V(openfile_table.sem); } vfs_end_op(); return ret; }
openfile_t vfs_open(char *pathname) { openfile_t file; int fileid; char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); semaphore_P(openfile_table.sem); for(file=0; file<CONFIG_MAX_OPEN_FILES; file++) { if(openfile_table.files[file].filesystem == NULL) { break; } } if(file >= CONFIG_MAX_OPEN_FILES) { semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); kprintf("VFS: Warning, maximum number of open files exceeded."); vfs_end_op(); return VFS_LIMIT; } fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } openfile_table.files[file].filesystem = fs; semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); fileid = fs->open(fs, filename); if(fileid < 0) { semaphore_P(openfile_table.sem); openfile_table.files[file].filesystem = NULL; semaphore_V(openfile_table.sem); vfs_end_op(); return fileid; /* negative -> error*/ } openfile_table.files[file].fileid = fileid; openfile_table.files[file].seek_position = 0; vfs_end_op(); return file; }