int32_t rmdir(char *pathname) { /* rmdir() system call */ char *parent, *child; inode_t *dir; super_block_t *sb; namei_t namei_data; int32_t err; /* divide pathname: */ if (err = divide_path(pathname, 1, &parent, &child)) return -err; /* get the inode structure of parent: */ err = namei(NULL, parent, &namei_data); kfree(parent); /* no need anymore. */ if (err) { kfree(child); return -err; } /* extract information from namei_data: */ dir = namei_data.inode; sb = dir->sb; kfree(namei_data.path); /* not needed. */ /* call filesystem driver: */ err = sb->fsdriver->rmdir(dir, child); /* that's all! */ iput(dir); kfree(child); return -err; }
int32_t link(char *oldpath, char *newpath) { /* link() system call */ char *new_parent, *new_child; namei_t inode_data, dir_data; inode_t *inode, *dir; int32_t err; /* get the inode structure of oldpath: */ err = namei(NULL, oldpath, &inode_data); if (err) return -err; inode = inode_data.inode; kfree(inode_data.path); /* divide "newpath": */ if (err = divide_path(newpath, 0, &new_parent, &new_child)) { iput(inode); return -err; } /* get the inode structure of new_parent: */ err = namei(NULL, new_parent, &dir_data); if (err) { iput(inode); kfree(new_parent); kfree(new_child); return -err; } dir = dir_data.inode; kfree(dir_data.path); /* both paths must be on the same mount point. */ if (inode_data.mp != dir_data.mp) { iput(inode); iput(dir); kfree(new_parent); kfree(new_child); return -EXDEV; } /* call the filesystem: */ err = inode->sb->fsdriver->link(inode, dir, new_child); /* done: */ iput(inode); iput(dir); kfree(new_parent); kfree(new_child); return -err; }
int32 TFFS_fopen( IN tffs_handle_t hfs, IN byte * file_path, IN byte * open_mode, OUT tfile_handle_t * phfile) { int32 ret; tffs_t * ptffs = (tffs_t *)hfs; byte * fname, * path; byte * dup_file_path; tfile_t * pfile; tdir_t * pdir; tdir_entry_t * pdir_entry; if (!hfs || !file_path || !open_mode || !phfile) return ERR_TFFS_INVALID_PARAM; ret = TFFS_OK; pfile = (tfile_t *)Malloc(sizeof(tfile_t)); dup_file_path = dup_string(file_path); pdir_entry = dirent_malloc(); fname = (byte *)Malloc(DNAME_MAX); pfile->secbuf = (ubyte *)Malloc(ptffs->pbs->byts_per_sec); Memset(pfile->secbuf, 0, ptffs->pbs->byts_per_sec); path = dup_file_path; if (!divide_path(dup_file_path, fname)) { ret = ERR_TFFS_INVALID_PATH; goto _release; } if (!_parse_open_mode(open_mode, &pfile->open_mode)) { ret = ERR_TFFS_INVALID_OPENMODE; goto _release; } if ((dir_init(ptffs, path, &pdir)) != DIR_OK) { ret = ERR_TFFS_INVALID_PATH; goto _release; } if (dirent_find(pdir, fname, pdir_entry) != DIRENTRY_OK) { DBG("%s(): can't find file [%s] at [%s]\n", __FUNCTION__, fname, path); if (pfile->open_mode == OPENMODE_READONLY) { ret = ERR_TFFS_FILE_NOT_EXIST; goto _release; } if (!dirent_init(fname, 0, TRUE, pdir_entry)) { ret = ERR_TFFS_INVALID_PATH; goto _release; } if ((ret = dir_append_direntry(pdir, pdir_entry)) != DIR_OK) { if (ret == ERR_DIR_NO_FREE_SPACE) { ret = ERR_TFFS_NO_FREE_SPACE; } else { ret = ERR_TFFS_DEVICE_FAIL; } goto _release; } } ret = _initialize_file(ptffs, pdir, pdir_entry, pfile); if (ret == FILE_OK) { *phfile = (tfile_handle_t)pfile; } _release: Free(fname); Free(dup_file_path); return ret; }
int32 TFFS_rmfile( IN tffs_handle_t hfs, IN byte * file_path) { int32 ret; byte * fname, * path; byte * dup_file_path; tdir_t * pdir; tffs_t * ptffs; tdir_entry_t * pdir_entry; ret = TFFS_OK; if (!hfs || !file_path) return ERR_TFFS_INVALID_PARAM; ptffs = (tffs_t *)hfs; dup_file_path = dup_string(file_path); fname = (byte *)Malloc(DNAME_MAX); pdir_entry = dirent_malloc(); path = dup_file_path; if (!divide_path(dup_file_path, fname)) { ret = ERR_TFFS_INVALID_PATH; goto _release; } if ((dir_init(ptffs, path, &pdir)) != DIR_OK) { ret = ERR_TFFS_INVALID_PATH; goto _release; } if ((ret = dirent_find(pdir, fname, pdir_entry)) == DIRENTRY_OK) { if (dirent_get_dir_attr(pdir_entry) & ATTR_DIRECTORY) { ret = ERR_TFFS_IS_NOT_A_FILE; goto _release; } if (dir_del_direntry(pdir, fname) != DIR_OK) { ret = ERR_TFFS_REMOVE_FILE_FAIL; goto _release; } if (fat_free_clus(pdir->ptffs->pfat, dirent_get_clus(pdir_entry)) != FAT_OK) { ret = ERR_TFFS_REMOVE_FILE_FAIL; goto _release; } ret = TFFS_OK; } else { ret = ERR_TFFS_NO_SUCH_FILE; goto _release; } _release: Free(fname); Free(dup_file_path); dirent_release(pdir_entry); dir_destroy(pdir); return ret; }
int32_t rename(char *oldpath, char *newpath) { /* rename() system call */ char *old_parent, *old_child; char *new_parent, *new_child; namei_t old_data, new_data; inode_t *old_dir, *new_dir; int32_t err; /* divide "oldpath": */ if (err = divide_path(oldpath, 0, &old_parent, &old_child)) return -err; /* divide "newpath": */ if (err = divide_path(newpath, 0, &new_parent, &new_child)) { kfree(old_parent); kfree(old_child); return -err; } /* get the inode structure of old_parent: */ err = namei(NULL, old_parent, &old_data); if (err) { kfree(old_parent); kfree(old_child); kfree(new_parent); kfree(new_child); return -err; } old_dir = old_data.inode; kfree(old_data.path); /* get the inode structure of new_parent: */ err = namei(NULL, new_parent, &new_data); if (err) { iput(old_dir); kfree(old_parent); kfree(old_child); kfree(new_parent); kfree(new_child); return -err; } new_dir = new_data.inode; kfree(new_data.path); /* both paths must be on the same mount point. */ if (old_data.mp != new_data.mp) { iput(new_dir); iput(old_dir); kfree(old_parent); kfree(old_child); kfree(new_parent); kfree(new_child); return -EXDEV; } /* call the filesystem: */ /* TODO: err = old_dir->sb->fsdriver->rename(); */ /* done: */ iput(new_dir); iput(old_dir); kfree(old_parent); kfree(old_child); kfree(new_parent); kfree(new_child); return -err; }