Esempio n. 1
0
block_store_t *block_store_create() {
    // While assembly-wise it shouldn't change, it looks cleaner,
    //   even if we have extra free/destruct calls on the error path
    //   (but then again, who cares about the length of the error path?)

    // This will probably have to be encapsulated eventually, like bitmap's creations
    // (also because import is a MEEEESSSSSSSSS)
    // (Actually, with bitmap_overlay now, we may just be able to call create whenever)
    // (Although file-backed stuff will throw a wrench in it, but it's VERY different (just an fd?))
    // (file-backing is a headache for some other day)

    block_store_t *bs = calloc(sizeof(block_store_t), 1);
    if (bs) {
        if ((bs->data_blocks = calloc(BLOCK_SIZE, BLOCK_COUNT)) &&
                // Eh, calloc, why not (technically a security risk if we don't)
                (bs->fbm = bitmap_overlay(BLOCK_COUNT, bs->data_blocks)) &&
                (bs->dbm = bitmap_create(BLOCK_COUNT))) {
            for (size_t idx = 0; idx < FBM_BLOCK_COUNT; ++idx) {
                bitmap_set(bs->fbm, idx);
            }
            bitmap_format(bs->dbm, 0xFF);
            // we have never synced, mark all as changed
            bs->flags = DIRTY;
            bs->fd = -1;
            bs_errno = BS_OK;
            return bs;
        }
        free(bs->data_blocks);
        bitmap_destroy(bs->dbm);
        bitmap_destroy(bs->fbm);
        free(bs);
    }
    bs_errno = BS_MEMORY;
    return NULL;
}
Esempio n. 2
0
void block_store_flush(block_store_t *const bs) {
    if (bs) {
        if (FLAG_CHECK(bs, FILE_LINKED)) {
            if (FLAG_CHECK(bs, DIRTY)) { // actual work to do
                // size_t blocks_to_write = bitmap_total_set(bs->dbm);
                /*
                    typedef struct {
                        int disaster_errno;
                        block_store_t *const bs;
                        size_t byte_counter;
                        bs_status status;
                    } bs_sync_obj;
                */
                bs_sync_obj sync_results = {0, bs, 0, BS_OK};

                bitmap_for_each(bs->dbm, &block_sync, &sync_results);
                if (sync_results.status == BS_OK) {
                    // Well it worked, hopefully
                    // Sipe the DBM and clear the dirty bit
                    bitmap_format(bs->dbm, 0x00);
                    FLAG_CLEAR(bs, DIRTY);
                }
                bs_errno = sync_results.status;
                return;
            }
            bs_errno = BS_OK;
            return;
        }
        bs_errno = BS_NO_LINK;
        return;
    }
    bs_errno = BS_PARAM;
    return;
}
Esempio n. 3
0
void block_store_link(block_store_t *const bs, const char *const filename) {
    if (bs && filename) {
        if (! FLAG_CHECK(bs, FILE_LINKED)) {
            // Ok, I can make a giant complicated hunk of logic to:
            //   Create if it doesn't exist
            //   Increase size if smaller
            //   Decrease size if larger
            // and It'll be a giant headache for various reasons (error checking, portability)
            // OR, I can just do it in two commands and call it a day.
            bs->fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
            if (bs->fd != -1) {
                if (utility_write_file(bs->fd, bs->data_blocks, BLOCK_COUNT * BLOCK_SIZE) == BLOCK_COUNT * BLOCK_SIZE) {
                    // Kill the DBM and dirty flag, set link state
                    bitmap_format(bs->dbm, 0x00);
                    FLAG_CLEAR(bs, DIRTY);
                    FLAG_SET(bs, FILE_LINKED);
                    bs_errno = BS_OK;
                    return;
                }
                bs_errno = BS_FILE_IO;
                return;
            }
            bs_errno = BS_FILE_ACCESS;
            return;
        }
        bs_errno = BS_LINK_EXISTS;
        return;
    }
    bs_errno = BS_PARAM;
}
Esempio n. 4
0
    /* 
 * PURPOSE: imports block store
 * INPUTS: char, filename
 * RETURN: block_store_t
 **/
block_store_t *block_store_import(const char *const filename) {
    block_store_t *bs = block_store_create(); //create blockstore bs
    if(bs){
        bitmap_destroy(bs -> fbm); //destroy fbm in bs
        bitmap_format(bs -> dbm, 0); //format dbm in bs
        struct stat file_info; //
        size_t urf = 0;
        if(stat(filename, &file_info) != -1){
            if(file_info.st_size == BLOCK_SIZE * BLOCK_COUNT){
                int fd;
                fd = open(filename, O_RDONLY);
                if(fd != -1){
                    size_t ct = FBM_SIZE * BLOCK_SIZE;
                    urf = utility_read_file(fd, bs -> data_blocks, ct);
                    if (urf)
                    {
                        bs -> fbm = bitmap_import(BLOCK_COUNT, bs -> data_blocks);
                        if (bs -> fbm)
                        {
                            ct = (BLOCK_COUNT - FBM_SIZE) * BLOCK_SIZE;
                            urf = utility_read_file(fd, bs -> data_blocks, ct);
                            if (urf)
                            {
                                block_store_errno = BS_OK;
                                close(fd);
                            }return 0;
                        }
                    }
                }
            }
        }
    }
    


// struct stat {
//                dev_t     st_dev;         /* ID of device containing file */
//                ino_t     st_ino;         /* inode number */
//                mode_t    st_mode;        /* protection */
//                nlink_t   st_nlink;       /* number of hard links */
//                uid_t     st_uid;         /* user ID of owner */
//                gid_t     st_gid;         /* group ID of owner */
//                dev_t     st_rdev;        /* device ID (if special file) */
//                off_t     st_size;        /* total size, in bytes */
//                blksize_t st_blksize;     /* blocksize for filesystem I/O */
//                blkcnt_t  st_blocks;      /* number of 512B blocks allocated */


    block_store_errno = BS_FATAL;
    return NULL;
}
Esempio n. 5
0
block_store_t *block_store_import(const char *const filename) {
    block_store_t *bs = NULL;
    int fd = 0;
    if (filename) {
        struct stat file_stat;
        // macro count * size ?
        if (!stat(filename, &file_stat) && file_stat.st_size == (BLOCK_COUNT * BLOCK_SIZE)) {
            fd = open(filename, O_RDONLY);
            if (fd != -1) {
                bs = block_store_create();
                if (bs) {
                    if (utility_read_file(fd, bs->data_blocks, BLOCK_COUNT * BLOCK_SIZE) == BLOCK_COUNT * BLOCK_SIZE) {
                        // We're good to go, attempt to link.

                        close(fd);
                        // manual override because I'm not going to call link
                        //  and just have it write what we just read back out
                        bs->fd = open(filename, O_WRONLY);
                        if (bs->fd != -1) {
                            // Wipe it, we have a link to something we JUST read
                            // So it SHOULD be in sync with us unless something else is using the file
                            FLAG_SET(bs, FILE_LINKED);
                            FLAG_CLEAR(bs, DIRTY);
                            bitmap_format(bs->dbm, 0x00);
                        }
                        bs_errno = ((bs->fd == -1) ? BS_NO_LINK : BS_OK);
                        return bs;
                    }
                    // WAY less branching and resource management
                    //  no real need for the dreaded goto for maintainability
                    bs_errno = BS_FILE_IO;
                    block_store_destroy(bs, BS_NO_FLUSH);
                    close(fd);
                    return NULL;
                }
                close(fd);
            }
        }
        bs_errno = BS_FILE_ACCESS;
        return NULL;
    }
    bs_errno = BS_PARAM;
    return NULL;
}