/* * Create two struct File object with Pipe's operations * and fsData point to a Pipe object. */ int Pipe_Create(struct File **read_file, struct File **write_file) { /* TODO_P(PROJECT_PIPE, "Create a pipe"); */ // Print("Pipe_Create called\n"); struct Pipe *pipe = (struct Pipe *)Malloc(sizeof(struct Pipe)); if (pipe == NULL) { return ENOMEM; } pipe->readers = 1; pipe->writers = 1; pipe->read_idx = 0; pipe->write_idx = 0; pipe->buffer = (void *)Malloc(BUF_SZ); if (pipe->buffer == NULL) { return ENOMEM; } pipe->buffer_bytes = 0; *read_file = Allocate_File(&Pipe_Read_Ops, 0, 0, pipe, 0, NULL); *write_file = Allocate_File(&Pipe_Write_Ops, 0, 0, pipe, 0, NULL); if (read_file != NULL && write_file != NULL) { (*read_file)->refCount = 1; (*write_file)->refCount = 1; return 0; } else { return ENOMEM; } }
int Create_Pipe(struct File **pRead, struct File **pWrite) { int rc = 0; struct File *read = 0, *write = 0; /* Allocate File objects */ if ((read = Allocate_File(&s_readPipeFileOps, 0, 0, 0, O_READ, 0)) == 0 || (write = Allocate_File(&s_writePipeFileOps, 0, 0, 0, O_WRITE, 0)) == 0) { rc = ENOMEM; goto done; } /* * TODO: you should allocate a data structure for managing the * pipe, and store it in the fsData field of the read and * write pipes. It will need a reference count field * in order to destroy it when the last File connected * to the pipe is closed. */ *pRead = read; *pWrite = write; KASSERT(rc == 0); done: if (rc != 0) { if (read != 0) Free(read); if (write != 0) Free(write); } return rc; }
/* * Open a directory named by given path. */ int GOSFS_Open_Directory(struct Mount_Point *mountPoint, const char *path, struct File **pDir) { int rc = 0; int blockNum = 0; // The GOSFS block the fileNode(file or dir) exists in char name[MAX_NAME_SIZE] = {}; struct File *dir = 0; bool found = 0; GOSFSsuperblock *super = (GOSFSsuperblock *)mountPoint->fsData; GOSFSptr *gosfsEntry = Safe_Calloc(sizeof(GOSFSptr)); GOSFSdirectory *currDir = Safe_Calloc(PAGE_SIZE); /* Grab the root directory from the disk */ blockNum = super->rootDir; GOSFS_Block_Read(mountPoint->dev, blockNum, currDir); /* Iterate through the path until reaching the end */ while (*path != 0) { memset(name, '\0', MAX_NAME_SIZE); // Reset name to empty memset(gosfsEntry, '\0', sizeof(GOSFSptr)); // Reset GOSFSentry to empty Get_Next_Name_In_Path(&path, name); found = GOSFS_Lookup(currDir, name, blockNum, gosfsEntry); /* If dir does not exist */ if (found == false) { rc = ENOTFOUND; goto fail; } /* If entry exists but is a file */ if (found == true && gosfsEntry->node.isDirectory == 0) { rc = ENOTDIR; goto fail; } /* If dir exists search in that directory */ if (found == true && gosfsEntry->node.isDirectory == 1 && *path != 0) { blockNum = gosfsEntry->node.blocks[0]; GOSFS_Block_Read(mountPoint->dev, blockNum, currDir); continue; } } /* Open directory */ dir = Allocate_File(&s_gosfsDirOps, 0, MAX_FILES_PER_DIR, gosfsEntry, 0, mountPoint); if (dir ==0) { goto memfail; } *pDir = dir; goto done; memfail: rc = ENOMEM; fail: Free(gosfsEntry); done: Free(currDir); return rc; }
/* * Open function for PFAT filesystems. */ static int PFAT_Open(struct Mount_Point *mountPoint, const char *path, int mode, struct File **pFile) { int rc = 0; struct PFAT_Instance *instance = (struct PFAT_Instance*) mountPoint->fsData; directoryEntry *entry; struct PFAT_File *pfatFile = 0; struct File *file = 0; int i = 0; /* Reject attempts to create or write */ if ((mode & (O_WRITE | O_CREATE)) != 0) return EACCESS; /* Look up the directory entry */ entry = PFAT_Lookup(instance, path); if (entry == 0) return ENOTFOUND; /* Make sure the entry is not a directory. */ if (entry->directory) return EACCESS; /* Get PFAT_File object */ pfatFile = Get_PFAT_File(instance, entry); if (pfatFile == 0) goto done; /* Create the file object. */ file = Allocate_File(&s_pfatFileOps, 0, entry->fileSize, pfatFile, mode, mountPoint); if (file == 0) { rc = ENOMEM; goto done; } /* Success! */ *pFile = file; // Error: I have to fix this to let pfat work with the standard syscalls; if (g_currentThread->userContext != 0) { for(i = 0; i < GOSFS_NUM_DIR_ENTRY; i++) { if(g_currentThread->userContext->fileList[i] == 0) break; } g_currentThread->userContext->fileList[i] = file; rc = i; Debug("gosfs open rc:%d\n", rc); g_currentThread->userContext->fileCount++; } done: return rc; }
/* * Clone a file. * The clone will access the same underlying file as the * original, but read/write/seek operations, etc. will be distinct. * Returns 0 if successful, or an error code if unsuccessful. */ static int PFAT_Clone(struct File *file, struct File **pClone) { int rc = 0; struct File *clone; /* Create a duplicate File object. */ clone = Allocate_File(file->ops, file->filePos, file->endPos, file->fsData, file->mode, file->mountPoint); if (clone == 0) { rc = ENOMEM; goto done; } *pClone = clone; done: return rc; }
/* * Open function for PFAT filesystems. */ static int PFAT_Open(struct Mount_Point *mountPoint, const char *path, int mode, struct File **pFile) { int rc = 0; struct PFAT_Instance *instance = (struct PFAT_Instance*) mountPoint->fsData; directoryEntry *entry; struct PFAT_File *pfatFile = 0; struct File *file = 0; /* Reject attempts to create or write */ if ((mode & (O_WRITE | O_CREATE)) != 0) return EACCESS; /* Look up the directory entry */ entry = PFAT_Lookup(instance, path); if (entry == 0) return ENOTFOUND; /* Make sure the entry is not a directory. */ if (entry->directory) return EACCESS; /* Get PFAT_File object */ pfatFile = Get_PFAT_File(instance, entry); if (pfatFile == 0) goto done; /* Create the file object. */ file = Allocate_File(&s_pfatFileOps, 0, entry->fileSize, pfatFile, 0, 0); if (file == 0) { rc = ENOMEM; goto done; } /* Success! */ *pFile = file; done: return rc; }
/* * Open a file with the given name and mode. * Return 0 on success, < 0 on failure (e.g. does not exist). */ int GOSFS_Open(struct Mount_Point *mountPoint, const char *path, int mode, struct File **pFile) { int rc = 0; int blockNum = 0; // The GOSFS block the fileNode(file or dir) exists in char name[MAX_NAME_SIZE] = {}; struct File *file = 0; bool found = 0; GOSFSsuperblock *super = (GOSFSsuperblock *)mountPoint->fsData; GOSFSptr *gosfsEntry = Safe_Calloc(sizeof(GOSFSptr)); GOSFSdirectory *currDir = Safe_Calloc(PAGE_SIZE); /* Grab the root directory from the disk */ blockNum = super->rootDir; GOSFS_Block_Read(mountPoint->dev, super->rootDir, currDir); /* Iterate through the path until reaching the end */ while (*path != 0) { memset(name, '\0', MAX_NAME_SIZE); // Reset name to empty memset(gosfsEntry, '\0', sizeof(GOSFSptr)); // Reset GOSFSentry to empty Get_Next_Name_In_Path(&path, name); found = GOSFS_Lookup(currDir, name, blockNum, gosfsEntry); /* If entry does not exist and it's not the end of the path */ if (found == false && *path != 0) { rc = ENOTFOUND; goto fail; } /* Entry's file and not end of path */ if (found == true && gosfsEntry->node.isDirectory == 0 && *path != 0) { rc = ENOTDIR; goto fail; } /* If entry exists but is a directory, search in that directory */ if (found == true && gosfsEntry->node.isDirectory == 1 && *path != 0) { blockNum = gosfsEntry->node.blocks[0]; GOSFS_Block_Read(mountPoint->dev, blockNum, currDir); continue; } } /* Fail if open called on directory since we have an openDirectory */ if (found == true && gosfsEntry->node.isDirectory == 1) { rc = EUNSUPPORTED; goto fail; } /* If entry exist and is a file then open it up */ if (found == true && gosfsEntry->node.isDirectory == 0) { file = Allocate_File(&s_gosfsFileOps, 0, gosfsEntry->node.size, gosfsEntry, mode, mountPoint); if (file == 0) { goto memfail; } *pFile = file; goto done; } /* If entry does not exist and not trying to create */ if (found == false && (mode & O_CREATE) == 0) { rc = ENOTFOUND; goto fail; } /* If entry does not exist but want to create */ if (found == false && (mode & O_CREATE) == 1) { if (Create_File(currDir, name, blockNum, gosfsEntry) < 0) { rc = ENOSPACE; goto fail; } file = Allocate_File(&s_gosfsFileOps, 0, 0, gosfsEntry, mode, mountPoint); if (file == 0) { goto memfail; } *pFile = file; /* Write currDir back to disk */ GOSFS_Block_Write(mountPoint->dev, blockNum, currDir); goto done; } memfail: rc = ENOMEM; fail: Free(gosfsEntry); done: Free(currDir); return rc; }
/* * Open a file with the given name and mode. * Return > 0 on success, < 0 on failure (e.g. does not exist). */ int GOSFS_Open(struct Mount_Point *mountPoint, const char *path, int mode, struct File **pFile) { GOSFSinstance *instance = (GOSFSinstance *) mountPoint->fsData; GOSFSdirectory *dir = 0; GOSFSfileNode *dirFileNode = 0, *fileNode = 0; GOSFSptr *cached; struct File *file; char *filePath = path; int rc; cached = Malloc(sizeof(GOSFSptr)); if (cached == 0) goto memfail; dirFileNode = lookupDirectory(instance, &dir, &filePath); if (dirFileNode == 0 && dir == 0) { /* Complete failure. */ rc = EACCESS; goto fail; } /* Now lookup desired file in the directory. */ fileNode = lookupFileInDirectory(dir, filePath, strlen(filePath)); if (fileNode == 0) { /* File does not exist. */ if (mode & O_CREATE) { /* Create the file in this directory. */ fileNode = createFileInDirectory(instance, dirFileNode, dir, filePath); if (fileNode == 0) { rc = EACCESS; goto fail; } } else { rc = EACCESS; goto fail; } } /* Fill in GOSFSptr fields */ if (dirFileNode) /* Non-root directory */ cached->blockNum = dirFileNode->blocks[0]; else /* Root directory */ cached->blockNum = instance->superblock->rootDirPointer; /* Calculate offset via ptr arithmetic */ cached->offset = fileNode - dir->files; /* Copy over file node */ memcpy(&cached->node, fileNode, sizeof(GOSFSfileNode)); /* Allocate file for VFS */ file = Allocate_File(&s_gosfsFileOps, 0, fileNode->size, cached, mode, mountPoint); if (file == 0) goto memfail; /* Success! */ *pFile = file; if (dirFileNode) Free(dirFileNode); Free(dir); return 0; memfail: rc = ENOMEM; goto fail; fail: if (dirFileNode) Free(dirFileNode); if (dir) Free(dir); if (cached) Free(cached); return rc; }