Пример #1
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;
}
Пример #2
0
size_t block_store_export(const block_store_t *const bs, const char *const filename) {
    // Thankfully, this is less of a mess than import...
    // we're going to ignore dbm, we'll treat export like it's making a new copy of the drive
    if (filename && bs && bs->fbm && bs->data_blocks) {
        const int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
        if (fd != -1) {
            if (utility_write_file(fd, bitmap_export(bs->fbm), FBM_SIZE * BLOCK_SIZE) == (FBM_SIZE * BLOCK_SIZE)) {
                if (utility_write_file(fd, bs->data_blocks, BLOCK_SIZE * (BLOCK_COUNT - FBM_SIZE)) == (BLOCK_SIZE * (BLOCK_COUNT - FBM_SIZE))) {
                    block_store_errno = BS_OK;
                    close(fd);
                    return BLOCK_SIZE * BLOCK_COUNT;
                }
            }
            block_store_errno = BS_FILE_IO;
            close(fd);
            return 0;
        }
        block_store_errno = BS_FILE_ACCESS;
        return 0;
    }
    block_store_errno = BS_PARAM;
    return 0;
}
Пример #3
0
// Block sync function to feed to bitmap_for_each
// Jumps the fd to the needed location and writes to it
// Admittedly, this function is not pretty.
void block_sync(size_t block_id, void *bs_sync_ptr) {
    bs_sync_obj *bs_sync = (bs_sync_obj *)bs_sync_ptr;
    /*
        typedef struct {
            int disaster_errno;
            block_store_t *const bs;
            size_t byte_counter;
            bs_status status;
        } bs_sync_obj;
    */
    if (bs_errno == BS_OK) {
        if (bs_sync && bs_sync->status == BS_OK) {
            if (bs_sync->bs) {
                if (FLAG_CHECK(bs_sync->bs, FILE_LINKED)) {
                    // Ducks = in a row
                    // jump to file position
                    if (lseek(bs_sync->bs->fd, BLOCK_POSITION(block_id), SEEK_SET) == BLOCK_POSITION(block_id)) {
                        // attempt to write
                        size_t written = utility_write_file(bs_sync->bs->fd, bs_sync->bs->data_blocks + BLOCK_POSITION(block_id), BLOCK_SIZE);
                        // Update written with WHATEVER happened
                        bs_sync->byte_counter += written;
                        if (written == BLOCK_SIZE) {
                            // all is ok, we wrote everything, or so we were told
                            return;
                        }
                    }
                    bs_sync->status = BS_FILE_IO;
                    // save whatever errno was generated by seek or write
                    bs_sync->disaster_errno = errno;
                    return;
                }
                bs_sync->status = BS_NO_LINK; // HOW DID THIS HAPPEN
                return;
            }
            bs_sync->status = BS_PARAM;
        }
        bs_errno = BS_PARAM;
    }
    return;
}