Esempio n. 1
0
File: fs.c Progetto: rbkloss/dcc_fs
uint64_t fs_get_block(struct superblock *sb) {
    if (sb->freeblks == 0) {
        //report Error
        return 0;
    }
    uint64_t freeList = sb->freelist;
    struct freepage *fp = (struct freepage *) malloc(sb->blksz);
    struct freepage *fp_prev = (struct freepage *) malloc(sb->blksz);
    struct freepage *fp_next = (struct freepage *) malloc(sb->blksz);
    seek_read(sb, freeList, fp);
    if (fp->count != 0) {
        //update previous pointers        
        seek_read(sb, fp->links[0], fp_prev);
        fp_prev->next = fp->next;
        seek_write(sb, fp->links[0], fp_prev);
    }

    if (fp->next != 0) {
        //update next pointers        
        seek_read(sb, fp->next, fp_next);
        fp_next->links[0] = fp->links[0];
        seek_write(sb, fp->next, fp_next);
    }

    sb->freelist = fp->next;
    sb->freeblks--;
    seek_write(sb, 0, sb);

    free(fp_prev);
    free(fp);
    free(fp_next);
    return freeList;
}
Esempio n. 2
0
File: fs.c Progetto: rbkloss/dcc_fs
int fs_put_block(struct superblock *sb, uint64_t block) {
    if (sb->freeblks != 0) {
        uint64_t freeList = sb->freelist;
        struct freepage *fp = NULL, *fp_next = NULL;
        fp = (struct freepage *) malloc(sb->blksz);
        fp_next = (struct freepage *) malloc(sb->blksz);

        seek_read(sb, freeList, fp_next);
        fp->next = freeList;
        fp->count = 0;
        seek_write(sb, block, fp);
        fp_next->count = 1;
        fp_next->links[0] = block;
        seek_write(sb, freeList, fp_next);

        free(fp);
        free(fp_next);
    } else {
        struct freepage *fp = NULL;
        fp = (struct freepage *) malloc(sb->blksz);
        fp->next = 0;
        fp->count = 0;
        seek_write(sb, block, fp);
        free(fp);
    }
    sb->freelist = block;
    sb->freeblks++;
    seek_write(sb, 0, sb);
    return 0;
}
Esempio n. 3
0
int InsertInNode(struct superblock* sb, const char* dirName,
        const uint64_t fileBlock) {
    int exists;
    struct inode*dirNode = NULL;
    struct nodeinfo* meta = NULL;
    dirNode = malloc(sb->blksz);
    meta = malloc(sb->blksz);
    uint64_t dirBlock = findFile(sb, dirName, &exists);
    seek_read(sb, dirBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    int len = 0;
    char** fileparts = getFileParts(dirName, &len);
    if (strcmp(meta->name, fileparts[len - 1]) != 0)return 0; //dir does not exists
    if ((++meta->size) % getLinksMaxLen(sb) == 0) {
        //needs to create another link block      
        struct inode* linknode = NULL;
        linknode = malloc(sb->blksz);
        linknode->links[0] = fileBlock;
        linknode->links[1] = 0;
        uint64_t lastLinkBlock = getNodeLastLinkBlock(sb, dirBlock);
        struct inode* lastLinkNode = NULL;
        lastLinkNode = malloc(sb->blksz);
        seek_read(sb, lastLinkBlock, lastLinkNode);
        if (lastLinkNode->next != 0) {
            exit(EXIT_FAILURE);
        }
        lastLinkNode->next = fs_get_block(sb);
        seek_write(sb, lastLinkNode->next, linknode);
        seek_write(sb, lastLinkBlock, lastLinkNode);
        free(linknode);
        free(lastLinkNode);
    } else {
        int linkLen = getLinksLen(dirNode);
        dirNode->links[linkLen] = fileBlock;
        dirNode->links[linkLen + 1] = 0;
    }
    seek_write(sb, dirBlock, dirNode);
    seek_write(sb, dirNode->meta, meta);

    freeFileParts(&fileparts, len);
    free(dirNode);
    free(meta);
    return FALSE;
}
Esempio n. 4
0
File: fs.c Progetto: rbkloss/dcc_fs
int fs_close(struct superblock *sb) {
    if (sb == NULL) {
        return -1;
    }
    seek_write(sb, 0, sb);
    if (flock(sb->fd, LOCK_UN | LOCK_NB) != 0) {
        errno = EBADF;
        return -1;
    }
    close(sb->fd);
    free(sb);
    return 0;
}
Esempio n. 5
0
/**
 * Inserts block2Add in the links relative to destBlock.
 * Does not check if destBlock is valid!
 * @param sb the superblock
 * @param destBlock block to receive block2Add as a child
 * @param block2Add block to be added in the children of destBlock
 * @return as of now you can ignore this
 */
int insertInBlock(struct superblock* sb, const uint64_t destBlock,
        const uint64_t block2Add) {
    struct inode *dirNode = NULL;
    struct nodeinfo* meta = NULL;
    dirNode = malloc(sb->blksz);
    meta = malloc(sb->blksz);
    seek_read(sb, destBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    if ((++meta->size) % getLinksMaxLen(sb) == 0) {
        //needs to create another link block      
        struct inode* linknode = NULL;
        linknode = malloc(sb->blksz);
        linknode->links[0] = block2Add;
        linknode->links[1] = 0;
        uint64_t lastLinkBlock = getNodeLastLinkBlock(sb, destBlock);
        struct inode* lastLinkNode = NULL;
        lastLinkNode = malloc(sb->blksz);
        seek_read(sb, lastLinkBlock, lastLinkNode);
        if (lastLinkNode->next != 0) {
            exit(EXIT_FAILURE);
        }
        lastLinkNode->next = fs_get_block(sb);
        seek_write(sb, lastLinkNode->next, linknode);
        seek_write(sb, lastLinkBlock, lastLinkNode);
        free(linknode);
        free(lastLinkNode);
    } else {
        int linkLen = getLinksLen(dirNode);
        dirNode->links[linkLen] = block2Add;
        dirNode->links[linkLen + 1] = 0;
    }
    seek_write(sb, destBlock, dirNode);
    seek_write(sb, dirNode->meta, meta);

    free(dirNode);
    free(meta);
    return TRUE;
}
Esempio n. 6
0
//////////////////////////////////////////////////
//
// SND_IO_File
//
//////////////////////////////////////////////////
bool SND_IO_File::open(const char *fname)
{
  if (file.is_open())
    close();
  file.clear();
  is_valid = false;
  file.open(fname, ios::in | ios::out | ios::binary);
  if (!file)
    return false;

  if (!read_header(file)) {
    file.close();
    return false;
  }

  if (!seek_read(0) || !seek_write(0)) {
    file.close();
    return false;
  }

  is_valid = true;
  return true;
}
Esempio n. 7
0
int main(int argc, char** argv)
{
	int i = 0;

	if (argc == 1) {
		printf("Usage: %s <filename>\n", argv[0]);
		return EXIT_FAILURE;
	}

	signal(SIGBUS, catch_sigbus);

	/* the next test should not trigger SIGBUS */
	expect_sigbus = 0;
	for (i = 0; i < RUN_LOOP; i++) {
		seek_write(argv[1]);
	}

	/* the next test should trigger SIGBUS */
	expect_sigbus = 1;
	if (read_after_eof(argv[1]))
		return EXIT_FAILURE;

	return EXIT_SUCCESS;
}
Esempio n. 8
0
File: fs.c Progetto: rbkloss/dcc_fs
int fs_mkdir(struct superblock *sb, const char *dname) {

    if (!sb->freeblks) {
        // disk is full
        errno = ENOSPC;
        return invalid;
    }

    int exists = 0;

    uint64_t fileBlock = findFile(sb, dname, &exists);

    if (exists) {
        // dir already exist;
        errno = EEXIST;
        return invalid;
    }

    struct inode *father = (struct inode*) malloc(sb->blksz);
    struct inode *folder = (struct inode*) malloc(sb->blksz);
    struct nodeinfo *n_info = (struct nodeinfo*) malloc(sb->blksz);

    uint64_t folder_block = fs_get_block(sb);
    uint64_t nodeinfo_block = fs_get_block(sb);

    init_folder_struct(folder, folder_block, nodeinfo_block);
    int status = init_nodeinfo_struct(sb, dname, n_info, nodeinfo_block);

    if (status == invalid) {
        free(father);
        father = NULL;

        free(folder);
        folder = NULL;

        free(n_info);
        n_info = NULL;

        errno = ENAMETOOLONG;
        return invalid;
    }

    /* Read father inode stored in file */
    seek_read(sb, fileBlock, father);
    status = checkfather_path(sb, dname, father);

    if (status == invalid) {
        free(father);
        father = NULL;

        free(folder);
        folder = NULL;

        free(n_info);
        n_info = NULL;

        errno = ENOENT;
        return invalid;
    }

    /* Ok, proceed */
    if (!exists) {
        insertInBlock(sb, fileBlock, folder_block);

        /* store both inodes related to the folder that
                 has been just created
         */
        seek_write(sb, folder_block, folder);
        seek_write(sb, nodeinfo_block, n_info);

    }


    free(father);
    father = NULL;
    free(folder);
    folder = NULL;
    free(n_info);
    n_info = NULL;

    return success;
}
Esempio n. 9
0
File: fs.c Progetto: rbkloss/dcc_fs
int fs_delete_file(struct superblock *sb, const char *fname) { //o proprio nome ja diz.
    int i = 0, found, maxLink, ultimo;
    uint64_t fileBlock, fileLinkBlk, lastBlock, folderBlock; //numero do bloco e do bloco do link no diretorio que tem ele

    struct inode *file;
    struct inode *folder;
    struct inode *aux;
    struct nodeinfo *folderInfo;

    maxLink = getLinksMaxLen(sb);
    file = (struct inode *) malloc(sb->blksz);
    folder = (struct inode *) malloc(sb->blksz);
    aux = (struct inode *) malloc(sb->blksz);
    folderInfo = (struct nodeinfo *) malloc(sb->blksz);

    fileBlock = findFile(sb, fname, &found);

    if (found == 0) { //arquivo nao existe
        errno = ENOENT;
        return -1;
    }

    seek_read(sb, fileBlock, file); //pegando inode do arquivo
    if (file->mode == IMDIR) { //se for diretorio
        errno = EISDIR;
        return -1;
    }

    folderBlock = file->parent;
    fileLinkBlk = folderBlock;
    seek_read(sb, folderBlock, folder); //diretorio onde esta o arquivo
    seek_read(sb, folder->meta, folderInfo);


    //removendo o arquivo e blocos associados
    fs_put_block(sb, file->meta); //liberando bloco nodeinfo
    while ((i < maxLink) && (file->links[i] != 0)) {
        //if (i == maxLink)
        fs_put_block(sb, file->links[i]);
        file->links[i] = 0; //marcando que nao tem mais bloco neste link.
        i++;
        if (i == maxLink && file->next != 0) {
            seek_read(sb, file->next, file);
            fs_put_block(sb, file->meta); //apagando bloco anterior depois de ir pro próximo.
            i = 0;
        }
    }
    //removendo na pasta tambem;
    ultimo = (folder->links[getLinksLen(folder) - 1] == fileBlock);
    if (ultimo) {
        folder->links[getLinksLen(folder) - 1] = 0;
        //folderInfo->size--;
    } else {
        i = 0;
        while ((folder->links[i % maxLink] != fileBlock) && i < folderInfo->size) {
            i++;
            if ((i % maxLink == 0) && (folder->next != 0)) {
                fileLinkBlk = folder->next; //guardando bloco que pode conter link pro arquivo. Saindo do while sera ele.
                seek_read(sb, folder->next, folder);
            }
        }
        lastBlock = getNodeLastLinkBlock(sb, folderBlock);
        if (lastBlock == fileLinkBlk) {
            folder->links[i % maxLink] = folder->links[getLinksLen(folder) - 1];
            folder->links[getLinksLen(folder) - 1] = 0;
        } else {
            seek_read(sb, lastBlock, aux);
            folder->links[i % maxLink] = aux->links[getLinksLen(aux) - 1]; //copiando ultimo link pra posicao q indicava bloco do arquivo removido
            aux->links[getLinksLen(aux) - 1] = 0;
            seek_write(sb, lastBlock, aux); //Devo escrever o bloco alterado de volta no disco, certo?
        }

    }
    folderInfo->size--;

    seek_write(sb, fileLinkBlk, folder); //escrevendo o que contem o link pro arquivo (foi alterado ali em cima)
    seek_read(sb, folderBlock, folder); //voltando pro inode principal da pasta
    seek_write(sb, folder->meta, folderInfo); //pra escrever o folderinfo no bloco onde ele estava.

    free(file);
    free(folder);
    free(folderInfo);
    free(aux);

    return 0;
}
Esempio n. 10
0
File: fs.c Progetto: rbkloss/dcc_fs
int fs_write_file(struct superblock *sb, const char *fname, char *buf, size_t cnt) {
    const uint64_t blocksNeeded = MAX(1, cnt / sb->blksz);
    if (blocksNeeded > sb->freeblks) {
        errno = ENOSPC;
        return -1;
    }
    int blocksUsed = 0;

    if (strlen(fname) + 1 > getFileNameMaxLen(sb)) {
        errno = ENAMETOOLONG;
        return -1;
    }

    if (existsFile(sb, fname)) {
        errno = EEXIST;
        return -1;
    }

    int len = 0, exists = 0;
    char** fileParts = getFileParts(fname, &len);
    uint64_t dirBlock = findFile(sb, fname, &exists);
    char* dirName = NULL;
    struct inode* dirNode, *node;
    struct nodeinfo* meta = (struct nodeinfo*) calloc(1, sb->blksz);
    initNode(&dirNode, sb->blksz);
    initNode(&node, sb->blksz);
    seek_read(sb, dirBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    dirName = calloc(1, sizeof (char)* (strlen(meta->name) + 1));
    strcpy(dirName, meta->name);

    if (strcmp(fileParts[MAX(0, len - 2)], dirName) != 0) {
        errno = EBADF;
        free(dirName);
        free(node);
        free(meta);
        free(dirNode);
        return -1;
    }


    uint64_t fileBlock = fs_get_block(sb);
    insertInBlock(sb, dirBlock, fileBlock);
    uint64_t blocksList[blocksNeeded];
    ///properly write the file
    while (blocksUsed < blocksNeeded) {
        uint64_t block = fs_get_block(sb);
        blocksList[blocksUsed] = block;
        char* temp = calloc(1, sb->blksz);
        char* blockContent = buf + sb->blksz * (blocksUsed);
        strcpy(temp, blockContent);
        blocksUsed++;
        seek_write(sb, block, temp);
        free(temp);
    }
    strcpy(meta->name, fileParts[len - 1]);
    meta->size = cnt;
    meta->reserved[0] = 0;

    node->meta = fs_get_block(sb);
    node->mode = IMREG;
    node->parent = dirBlock;

    seek_write(sb, node->meta, meta);

    uint64_t nodeBlock = fileBlock;
    blocksUsed = 0;
    while (blocksUsed < blocksNeeded) {
        int i = 0;
        int linksLen = getLinksMaxLen(sb);
        int N = MIN(linksLen, blocksNeeded);
        while (i < N) {
            node->links[i] = blocksList[i];
            i++;
            blocksUsed++;
        }
        if (blocksUsed < blocksNeeded) {
            node->next = fs_get_block(sb);
            seek_write(sb, nodeBlock, node);
            nodeBlock = node->next;
            node->next = 0;
            node->parent = fileBlock;
            node->mode = IMCHILD | IMREG;
            node->meta = fs_get_block(sb);
            strcpy(meta->name, fileParts[len - 1]);
            meta->size = cnt;
            seek_write(sb, node->meta, meta);
        }
    }
    seek_write(sb, nodeBlock, node);

    free(meta);
    free(node);
    freeFileParts(&fileParts, len);
    free(dirNode);
    free(dirName);

    return 0;
}