Пример #1
0
/*
 * 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;
    }
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
/*
 * 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;
}
Пример #7
0
/*
 * 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;
}
Пример #8
0
/*
 * 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;
}