📄 fatfs.c
字号:
err = fatfs_get_disk_info(disk); if (err != ENOERR) { fatfs_tcache_delete(disk); cyg_blib_delete(&disk->blib); free(disk->bcache_mem); free(disk); return err; } #if TFS print_disk_info(disk);#endif CYG_TRACE0(TFS, "Initializing node cache"); fatfs_node_cache_init(disk); CYG_TRACE0(TFS, "Initializing root node"); fatfs_get_root_node(disk, &root_data); disk->root = fatfs_node_alloc(disk, &root_data); fatfs_node_ref(disk, disk->root); mte->root = (cyg_dir)disk->root; mte->data = (CYG_ADDRWORD)disk; CYG_TRACE0(TFS, "Disk mounted"); return ENOERR;}// -------------------------------------------------------------------------// fatfs_umount()// Unmount the filesystem. This will currently only succeed if the// filesystem is empty.static intfatfs_umount(cyg_mtab_entry *mte){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_node_t *root = (fatfs_node_t *)mte->root; CYG_TRACE3(TFS, "Umount mte=%p %d live nodes %d dead nodes", mte, fatfs_get_live_node_count(disk), fatfs_get_dead_node_count(disk)); if (root->refcnt > 1) return EBUSY; if (fatfs_get_live_node_count(disk) != 1) return EBUSY; fatfs_node_unref(disk, root); fatfs_node_cache_flush(disk); fatfs_tcache_delete(disk); // FIXME: cache delete can fail if cache can't be synced cyg_blib_delete(&disk->blib); free(disk->bcache_mem); free(disk); mte->root = CYG_DIR_NULL; mte->data = (CYG_ADDRWORD)NULL; CYG_TRACE0(TFS, "Disk umounted"); return ENOERR;}// -------------------------------------------------------------------------// fatfs_open()// Open a file for reading or writing.static int fatfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name, int mode, cyg_file *file){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_node_t *node = NULL; fatfs_dirsearch_t ds; int err; CYG_TRACE5(TFS, "Open mte=%p dir=%p name='%s' mode=%d file=%p", mte, dir, name, mode, file); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err == ENOENT) { if (ds.last && (mode & O_CREAT)) { fatfs_node_t node_data; // No node there, if the O_CREAT bit is set then we must // create a new one. The dir and name fields of the dirsearch // object will have been updated so we know where to put it. CYG_TRACE1(TFS, "Creating new file '%s'", name); err = fatfs_create_file(disk, ds.dir, ds.name, ds.namelen, &node_data); if (err != ENOERR) return err; node = fatfs_node_alloc(disk, &node_data); if (NULL == node) return ENOMEM; // Update directory times ds.dir->atime = ds.dir->mtime = cyg_timestamp(); err = ENOERR; } } else if (err == ENOERR) { // The node exists. If the O_CREAT and O_EXCL bits are set, we // must fail the open. if ((mode & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) err = EEXIST; else node = ds.node; } if (err == ENOERR && (mode & O_TRUNC)) { // If the O_TRUNC bit is set we must clean out the file data. CYG_TRACE0(TFS, "Truncating file"); fatfs_trunc_file(disk, node); } if (err != ENOERR) return err; // Check that we actually have a file here if (S_ISDIR(node->mode)) return EISDIR; // Make a reference to this file node fatfs_node_ref(disk, node); // Initialize the file object file->f_flag |= mode & CYG_FILE_MODE_MASK; file->f_type = CYG_FILE_TYPE_FILE; file->f_ops = &fatfs_fileops; file->f_offset = (mode & O_APPEND) ? node->size : 0; file->f_data = (CYG_ADDRWORD)node; file->f_xops = 0; return ENOERR;}// -------------------------------------------------------------------------// fatfs_unlink()// Remove a file link from its directory.static int fatfs_unlink(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; CYG_TRACE3(TFS, "Unlink mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; if (ds.node->refcnt > 0) return EBUSY; // Delete node err = fatfs_delete_file(disk, ds.node); if (err == ENOERR) fatfs_node_free(disk, ds.node); return err;}// -------------------------------------------------------------------------// fatfs_mkdir()// Create a new directory.static intfatfs_mkdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; CYG_TRACE3(TFS, "Mkdir mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err == ENOENT) { if (ds.last) { fatfs_node_t node_data; // The entry does not exist, and it is the last element in // the pathname, so we can create it here. err = fatfs_create_dir(disk, ds.dir, ds.name, ds.namelen, &node_data); if (err != ENOERR) return err; fatfs_node_alloc(disk, &node_data); return ENOERR; } } else if (err == ENOERR) { return EEXIST; } return err;}// -------------------------------------------------------------------------// fatfs_rmdir()// Remove a directory.static int fatfs_rmdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; CYG_TRACE3(TFS, "Rmdir mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; // Check that this is actually a directory. if (!S_ISDIR(ds.node->mode)) return EPERM; if (ds.node->refcnt > 0) return EBUSY; err = fatfs_delete_file(disk, ds.node); if (err == ENOERR) fatfs_node_free(disk, ds.node); return err;}// -------------------------------------------------------------------------// fatfs_rename()// Rename a file/dir.static int fatfs_rename(cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, cyg_dir dir2, const char *name2){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds1, ds2; int err; CYG_TRACE5(TFS, "Rename mte=%p dir1=%p name1='%s' dir2=%p name2='%s'", mte, dir1, name1, dir2, name2); init_dirsearch(&ds1, disk, (fatfs_node_t *)dir1, name1); err = fatfs_find(&ds1); if (err != ENOERR) return err; // Protect the found nodes from being reused by the // following search fatfs_node_ref(disk, ds1.dir); fatfs_node_ref(disk, ds1.node); init_dirsearch(&ds2, disk, (fatfs_node_t *)dir2, name2); err = fatfs_find(&ds2); if (err == ENOERR && ds2.last) { err = EEXIST; goto out; } if (err == ENOENT && !ds2.last) goto out; if (ds1.node == ds2.node) { err = ENOERR; goto out; } err = fatfs_rename_file(disk, ds1.dir, ds1.node, ds2.dir, ds2.name, ds2.namelen); fatfs_node_rehash(disk, ds1.node);out: fatfs_node_unref(disk, ds1.dir); fatfs_node_unref(disk, ds1.node); if (err == ENOERR) { ds1.dir->atime = ds1.dir->mtime = ds2.dir->atime = ds2.dir->mtime = cyg_timestamp(); } return err;}// -------------------------------------------------------------------------// fatfs_link()// Make a new directory entry for a file.static int fatfs_link(cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, cyg_dir dir2, const char *name2, int type){ CYG_TRACE6(TFS, "Link mte=%p dir1=%p name1='%s' dir2=%p name2='%s' type=%d", mte, dir1, name1, dir2, name2, type); // Linking not supported return EINVAL;}// -------------------------------------------------------------------------// fatfs_opendir()// Open a directory for reading.static intfatfs_opendir(cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_file *file){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; CYG_TRACE4(TFS, "Opendir mte=%p dir=%p name='%s' file=%p", mte, dir, name, file); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; // Check it is really a directory. if (!S_ISDIR(ds.node->mode)) return ENOTDIR; // Make a reference to this dir node fatfs_node_ref(disk, ds.node); // Initialize the file object file->f_type = CYG_FILE_TYPE_FILE; file->f_ops = &fatfs_dirops; file->f_data = (CYG_ADDRWORD)ds.node; file->f_xops = 0; file->f_offset = 0; return ENOERR;}// -------------------------------------------------------------------------// fatfs_chdir()// Change directory support.static intfatfs_chdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_dir *dir_out){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; CYG_TRACE4(TFS, "Chdir mte=%p dir=%p dir_out=%p name=%d", mte, dir, dir_out, name); if (dir_out != NULL) { // This is a request to get a new directory pointer in // *dir_out. fatfs_dirsearch_t ds; int err; init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -