Example #1
0
static int PFAT_FStat_Dir(struct File *dir, struct VFS_File_Stat *stat)
{
    /* FIXME: for now, there is only one directory */
    struct PFAT_Instance *instance = (struct PFAT_Instance*) dir->mountPoint->fsData;
    Copy_Stat(stat, &instance->rootDirEntry);
    return 0;
}
Example #2
0
/*
 * Get metadata for given file. Need to find the file from the given path.
 */
int GOSFS_Stat(struct Mount_Point *mountPoint, const char *path,
               struct VFS_File_Stat *stat) {
    int rc = 0;
    int blockNum = 0; // The GOSFS block the fileNode(file or dir) exists in
    bool found = 0;
    char name[MAX_NAME_SIZE] = {};
    GOSFSsuperblock *super = (GOSFSsuperblock *)mountPoint->fsData;
    GOSFSptr *gosfsEntry = Safe_Calloc(sizeof(GOSFSptr));
    GOSFSdirectory *currDir = Safe_Calloc(PAGE_SIZE);

    /* Grab the root directory from disk */
    blockNum = super->rootDir;
    GOSFS_Block_Read(mountPoint->dev, super->rootDir, currDir);

    while(*path != 0) {
        memset(name, '\0', MAX_NAME_SIZE);
        memset(gosfsEntry, '\0', sizeof(GOSFSptr));
        Get_Next_Name_In_Path(&path, name);
        found = GOSFS_Lookup(currDir, name, blockNum, gosfsEntry);

        /* Entry exists but not a file and not end of path */
        if (found == true && gosfsEntry->node.isDirectory == 0 && *path != 0) {
            rc = ENOTDIR;
            goto fail;
        }
            
        /* Entry exists but directory ,search in that dir */
        if (found == true && gosfsEntry->node.isDirectory == 1 && *path != 0) {
            blockNum =  gosfsEntry->node.blocks[0];
            GOSFS_Block_Read(mountPoint->dev, blockNum, currDir);
            continue;
        }

        /* If entry does not exist then fail */
        if (found == false ) {
            rc = ENOTFOUND;
            goto fail;
        }

    }

    /* Copy metadata */
    Copy_Stat(stat, &gosfsEntry->node);

  fail:
  done:
    Free(gosfsEntry);
    Free(currDir);
    return rc;
}
Example #3
0
/*
 * Stat function for PFAT filesystems.
 */
static int PFAT_Stat(struct Mount_Point *mountPoint, const char *path, struct VFS_File_Stat *stat)
{
    struct PFAT_Instance *instance = (struct PFAT_Instance*) mountPoint->fsData;
    directoryEntry *entry;

    KASSERT(path != 0);
    KASSERT(stat != 0);

    Debug("PFAT_Stat(%s)\n", path);

    entry = PFAT_Lookup(instance, path);
    if (entry == 0)
	return ENOTFOUND;

    Copy_Stat(stat, entry);

    return 0;
}
Example #4
0
/*
 * Read next directory entry from an open directory.
 * Return 1 on success, < 0 on failure.
 */
int GOSFS_Read_Entry(struct File *dir, struct VFS_Dir_Entry *entry) {
    int rc = 1;
    GOSFSfileNode *currNode = 0;
    GOSFSdirectory *currDir = Safe_Calloc(PAGE_SIZE);
    GOSFSptr *currEntry = (GOSFSptr *)dir->fsData;

    /* struct File is not a directory */
    if (currEntry->node.isDirectory == 0) {
        rc = ENOTDIR;
        goto fail;
    }

    /* file position at end of dir */
    if (dir->filePos >= MAX_FILES_PER_DIR) {
        rc = EINVALID;
        goto fail;
    }

    /* Grab the open directory's actual directory structure from disk */
    GOSFS_Block_Read(dir->mountPoint->dev, currEntry->node.blocks[0], currDir);

    /* Get the next non-empty entry */
    for (; dir->filePos < MAX_FILES_PER_DIR; dir->filePos++) {
        currNode = &currDir->files[dir->filePos]; 
        if (currNode->isUsed == 1) {
            memcpy(entry->name, currNode->name, MAX_NAME_SIZE);
            Copy_Stat(&entry->stats, currNode);
            dir->filePos++;
            goto done;
        }
    }

    rc = ENOTFOUND;

  fail:
  done:
    Free(currDir);
    return rc;

}
Example #5
0
/*
 * Read a directory entry.
 */
static int PFAT_Read_Entry(struct File *dir, struct VFS_Dir_Entry *entry)
{
    directoryEntry *pfatDirEntry;
    struct PFAT_Instance *instance = (struct PFAT_Instance*) dir->mountPoint->fsData;

    if (dir->filePos >= dir->endPos)
	return VFS_NO_MORE_DIR_ENTRIES; /* Reached the end of the directory. */

    pfatDirEntry = &instance->rootDir[dir->filePos++];

    /*
     * Note: we don't need to bounds check here, because
     * generic struct VFS_Dir_Entry objects have much more space for filenames
     * than PFAT directoryEntry objects.
     */
    strncpy(entry->name, pfatDirEntry->fileName, sizeof(pfatDirEntry->fileName));
    entry->name[sizeof(pfatDirEntry->fileName)] = '\0';

    Copy_Stat(&entry->stats, pfatDirEntry);

    return 0;
}
Example #6
0
/*
 * FStat function for PFAT files.
 */
static int PFAT_FStat(struct File *file, struct VFS_File_Stat *stat)
{
    struct PFAT_File *pfatFile = (struct PFAT_File*) file->fsData;
    Copy_Stat(stat, pfatFile->entry);
    return 0;
}
Example #7
0
/*
 * Read data from current position in file.
 * Return > 0 on success, < 0 on failure.
 */
int GOSFS_Read(struct File *file, void *buf, ulong_t numBytes) {
    int bytesRead = 0;
    int bytesToRead = 0;
    int blockNum = 0;
    int offset = file->filePos % PAGE_SIZE;
    int endPos = file->filePos + numBytes;
    int numDirEntries = 0;
    int dirEntriesRead = 0;
    int index = 0;
    void *tempBuffer = 0;
    struct Block_Device *dev = file->mountPoint->dev;
    GOSFSptr *entry = (GOSFSptr *)file->fsData;
    GOSFSfileNode *node = &entry->node;
    GOSFSfileNode *currNode = 0;
    GOSFSdirectory *currDir = 0;
    struct VFS_Dir_Entry *dirEntry = 0;

    /* If the read is called on a directory, read dir entries into buffer */
    if (node->isDirectory == 1) {
        currDir = Safe_Calloc(PAGE_SIZE);
        dirEntry = Safe_Calloc(sizeof(struct VFS_Dir_Entry));
        numDirEntries = numBytes; // Num dir entries I need to read

        if ((file->filePos + numDirEntries) > file->endPos) {
            numDirEntries = file->endPos - file->filePos;
        }

        GOSFS_Block_Read(dev, node->blocks[0], currDir);

        /* Write the number of dir entries we need to the buffer */
        while (numDirEntries > 0) {
            memset(dirEntry, '\0', sizeof(struct VFS_Dir_Entry));
            currNode = &currDir->files[file->filePos];

            memcpy(dirEntry->name, currNode->name, MAX_NAME_SIZE);
            Copy_Stat(&dirEntry->stats, currNode);
            
            memcpy(buf, dirEntry, sizeof(struct VFS_Dir_Entry));
            
            buf += sizeof(struct VFS_Dir_Entry);
            numDirEntries--;
            dirEntriesRead++;
            file->filePos++;
        }

        Free(dirEntry);
        Free(currDir);
        return dirEntriesRead;
    } 
    /* If read is called on a file */
    else {

        /* No read access */
        if ((file->mode & O_READ) == 0) {
            return EACCESS; 
        }

        /* If trying to read more bytes than exists, only read what's left */
        if (endPos > file->endPos) {
            numBytes = file->endPos - file->filePos;
        }

        tempBuffer = Safe_Calloc(PAGE_SIZE);

        while (numBytes > 0) {
            memset(tempBuffer, '\0', PAGE_SIZE);
            blockNum = Get_Blocknum_To_Read(file);
            if (blockNum == 0) 
                return -1;

            if (numBytes < (PAGE_SIZE - offset)) {
                bytesToRead = numBytes;
            } else if (numBytes >= (PAGE_SIZE - offset)) {
                bytesToRead = PAGE_SIZE - offset; 
            }

            GOSFS_Block_Read(dev, blockNum, tempBuffer);
            memcpy(buf, tempBuffer + offset, bytesToRead);
            offset = 0;

            file->filePos += bytesToRead; 
            bytesRead += bytesToRead;
            numBytes -= bytesToRead;
        }
        Free(tempBuffer);
        return bytesRead; 
    }
}
Example #8
0
/*
 * Get metadata for given File. Called with a file descriptor.
 */
int GOSFS_FStat(struct File *file, struct VFS_File_Stat *stat) {
    GOSFSptr *entry = (GOSFSptr *)file->fsData;
    Copy_Stat(stat, &entry->node);
    return 0;
}