void test_move_onto() { /* Set up */ world_t* world = world_create(5); /* Test case 1 - A is top of stack */ move_onto(world, 1, 2); assert(world->position_blocks_top[1] == NULL && world->position_blocks_bottom[1] == NULL); assert(world->position_blocks_top[2]->value == 1 && world->position_blocks_bottom[2]->value == 2); /* Test case 2 - A and B in middle of their stacks */ move_onto(world, 3, 4); move_onto(world, 2, 4); assert(block_get_stack(block_get(world, 1)) == 1 && block_get_stack(block_get(world, 3)) == 3); assert(block_get_stack(block_get(world, 2)) == 4 && block_get_stack(block_get(world, 4)) == 4); assert(world->position_blocks_top[4]->value == 2 && world->position_blocks_bottom[4]->value == 4); /* Test case 3 - A and B on same stack */ move_onto(world, 3, 2); move_onto(world, 3, 4); assert(block_get_stack(block_get(world, 2)) == 4); /* Tear down */ world_delete(&world); }
/** Read block from file located on a exFAT file system. * * @param block Pointer to a block pointer for storing result. * @param bs Buffer holding the boot sector of the file system. * @param service_id Service ID of the file system. * @param fcl First cluster used by the file. Can be zero if the file * is empty. * @param clp If not NULL, address where the cluster containing bn * will be stored. * stored * @param bn Block number. * @param flags Flags passed to libblock. * * @return EOK on success or a negative error code. */ int exfat_block_get_by_clst(block_t **block, exfat_bs_t *bs, service_id_t service_id, bool fragmented, exfat_cluster_t fcl, exfat_cluster_t *clp, aoff64_t bn, int flags) { uint32_t clusters; uint32_t max_clusters; exfat_cluster_t c; int rc; if (fcl < EXFAT_CLST_FIRST || fcl > DATA_CNT(bs) + 2) return ELIMIT; if (!fragmented) { rc = block_get(block, service_id, DATA_FS(bs) + (fcl - EXFAT_CLST_FIRST)*SPC(bs) + bn, flags); } else { max_clusters = bn / SPC(bs); rc = exfat_cluster_walk(bs, service_id, fcl, &c, &clusters, max_clusters); if (rc != EOK) return rc; assert(clusters == max_clusters); rc = block_get(block, service_id, DATA_FS(bs) + (c - EXFAT_CLST_FIRST) * SPC(bs) + (bn % SPC(bs)), flags); if (clp) *clp = c; } return rc; }
/** Get cluster from the first FAT. * * @param bs Buffer holding the boot sector for the file system. * @param service_id Service ID for the file system. * @param clst Cluster which to get. * @param value Output argument holding the value of the cluster. * * @return EOK or a negative error code. */ static int fat_get_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno, fat_cluster_t clst, fat_cluster_t *value) { block_t *b, *b1; uint16_t byte1, byte2; aoff64_t offset; int rc; offset = (clst + clst / 2); if (offset / BPS(bs) >= SF(bs)) return ERANGE; rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); if (rc != EOK) return rc; byte1 = ((uint8_t *) b->data)[offset % BPS(bs)]; /* This cluster access spans a sector boundary. Check only for FAT12 */ if ((offset % BPS(bs)) + 1 == BPS(bs)) { /* Is this the last sector of FAT? */ if (offset / BPS(bs) < SF(bs)) { /* No, read the next sector */ rc = block_get(&b1, service_id, 1 + RSCNT(bs) + SF(bs) * fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); if (rc != EOK) { block_put(b); return rc; } /* * Combining value with last byte of current sector and * first byte of next sector */ byte2 = ((uint8_t*) b1->data)[0]; rc = block_put(b1); if (rc != EOK) { block_put(b); return rc; } } else { /* Yes. This is the last sector of FAT */ block_put(b); return ERANGE; } } else byte2 = ((uint8_t *) b->data)[(offset % BPS(bs)) + 1]; *value = uint16_t_le2host(byte1 | (byte2 << 8)); if (IS_ODD(clst)) *value = (*value) >> 4; else
static ssize_t block_read(struct cdev *cdev, void *buf, size_t count, unsigned long offset, unsigned long flags) { struct block_device *blk = cdev->priv; unsigned long mask = BLOCKSIZE(blk) - 1; unsigned long block = offset >> blk->blockbits; size_t icount = count; int blocks; if (offset & mask) { size_t now = BLOCKSIZE(blk) - (offset & mask); void *iobuf = block_get(blk, block); now = min(count, now); if (IS_ERR(iobuf)) return PTR_ERR(iobuf); memcpy(buf, iobuf + (offset & mask), now); buf += now; count -= now; block++; } blocks = count >> blk->blockbits; while (blocks) { void *iobuf = block_get(blk, block); if (IS_ERR(iobuf)) return PTR_ERR(iobuf); memcpy(buf, iobuf, BLOCKSIZE(blk)); buf += BLOCKSIZE(blk); blocks--; block++; count -= BLOCKSIZE(blk); } if (count) { void *iobuf = block_get(blk, block); if (IS_ERR(iobuf)) return PTR_ERR(iobuf); memcpy(buf, iobuf, count); } return icount; }
void test_pile_over(){ /* Set up*/ world_t* world = world_create(7); pile_over(world, 1, 2); pile_over(world, 3, 4); pile_over(world, 5, 6); /* Test case 1 - move all left stack to right stack*/ pile_over(world, 2, 4); int i = 0; for(i = 1; i <= 4; i++) { assert(block_get_stack(block_get(world, i)) == 4); } assert(world->position_blocks_bottom[2] == NULL && world->position_blocks_top[2] == NULL); /* Test case 2 - move part of left stack to right stack. Choose middle elem in right stack*/ /* Elements should be on top of 6*/ pile_over(world, 3, 5); int stack[] = {1, 2, 3, 5, 6}; for(i = 0; i < 5; i++) { assert(block_get_stack(block_get(world, stack[i])) == 6); } assert(world->position_blocks_bottom[4]->value == 4 && world->position_blocks_top[4]->value == 4); assert(world->position_blocks_bottom[6]->value == 6 && world->position_blocks_top[6]->value == 1); /* Test case 3 - move block that is already on top of another*/ pile_over(world, 3, 5); for(i = 0; i < 5; i++) { assert(block_get_stack(block_get(world, stack[i])) == 6); } assert(world->position_blocks_bottom[4]->value == 4 && world->position_blocks_top[4]->value == 4); assert(world->position_blocks_bottom[6]->value == 6 && world->position_blocks_top[6]->value == 1); /* Test case 4 - move stack to middle of stack*/ pile_over(world, 0, 4); pile_over(world, 4, 2); for (i = 0; i < 7; i++) { assert(block_get_stack(block_get(world, i)) == 6); } /* Tear down */ world_delete(&world); }
void print_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t data) { int rc; uint32_t data_block_index; block_t *block; rc = ext2_filesystem_get_inode_data_block_index(fs, inode, data, &data_block_index); if (rc != EOK) { printf("Failed getting data block #%u\n", data); return; } printf("Data for inode contents block #%u is located in filesystem " "block %u\n", data, data_block_index); printf("Data preview (only printable characters):\n"); rc = block_get(&block, fs->device, data_block_index, 0); if (rc != EOK) { printf("Failed reading filesystem block %u\n", data_block_index); return; } print_data(block->data, block->size); printf("\n"); rc = block_put(block); if (rc != EOK) { printf("Failed putting filesystem block\n"); } }
/* **************************************************************** * Encerra o uso das entradas da tabela "disktb" * **************************************************************** */ int disktb_close_entry (dev_t dev) { DISKTB *up; int i; BHEAD *bp; /* * Obtém a partição inicial do dispositivo */ if ((up = disktb_get_first_entry (dev)) == NODISKTB) return (-1); /* * Força a releitura da tabela de partições */ bp = block_get (up->p_dev, 0, 0); #ifdef DEBUG printf ("%v: O bloco 0 == %d\n", up->p_dev, EVENTTEST (&bp->b_done)); #endif DEBUG EVENTCLEAR (&bp->b_done); block_put (bp); /* * Encerra as entradas */ for (i = 0; i < 2; i++, up++) { /*** up->p_name = ...; ***/ up->p_offset = 0; up->p_size = BL4SZ / BLSZ; /* Provisório, para ler a "parttb" */ /*** up->p_dev = ...; ***/ /*** up->p_unit = ...; ***/ /*** up->p_target = ...; ***/ up->p_type = 0; up->p_flags = 0; up->p_head = 0; up->p_sect = 0; up->p_cyl = 0; if (up->p_nopen != 0) { printf ( "%s: p_nopen residual: %d\n", up->p_name, up->p_nopen ); } up->p_nopen = 0; up->p_lock = 0; } return (0); } /* end disktb_close_entry */
int block_next_lin(struct map_rect_priv *mr) { struct coord_rect r; for (;;) { block_lin_count++; block_mem+=sizeof(struct block *); mr->b.block_num++; if (! mr->b.block_num) mr->b.p=mr->file->begin+0x2000; else mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; if (mr->b.p >= mr->file->end) { dbg(lvl_debug,"end of blocks %p vs %p\n", mr->b.p, mr->file->end); return 0; } mr->b.block_start=mr->b.p; mr->b.b=block_get(&mr->b.p); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+block_get_size(mr->b.b); if (block_get_count(mr->b.b) == -1) { dbg(lvl_warning,"empty blocks\n"); return 0; } block_get_r(mr->b.b, &r); if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { block_active_count++; block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); dbg(lvl_debug,"block ok\n"); return 1; } dbg(lvl_info,"block not in cur_sel\n"); } }
int block_next_lin(struct map_rect_priv *mr) { for (;;) { block_lin_count++; block_mem+=sizeof(struct block *); mr->b.block_num++; if (! mr->b.block_num) mr->b.p=mr->file->begin+0x2000; else mr->b.p=mr->b.block_start+mr->b.b->blocks*512; if (mr->b.p >= mr->file->end) return 0; mr->b.block_start=mr->b.p; mr->b.b=block_get(&mr->b.p); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+mr->b.b->size; if (mr->b.b->count == -1) return 0; if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->rect, &mr->b.b->r)) { block_active_count++; block_active_mem+=mr->b.b->blocks*512-sizeof(struct block *); return 1; } } }
void test_pile_onto() { /* Set up */ world_t* world = world_create(7); pile_onto(world, 1, 2); pile_onto(world, 3, 4); pile_onto(world, 2, 4); /* Test case 1 - Middle of stack A to middle of stack B */ assert(block_get_stack(block_get(world, 3)) == 3); assert(block_get_stack(block_get(world, 1)) == 4 && block_get_stack(block_get(world, 2)) == 4); assert(world->position_blocks_top[4]->value == 1 && world->position_blocks_bottom[4]->value == 4); /* Test case 2 - stack A already on top of block B*/ pile_onto(world, 1, 4); assert(block_get_stack(block_get(world, 2)) == 4); /* Tear down */ world_delete(&world); }
/** Read block from file located on a FAT file system. * * @param block Pointer to a block pointer for storing result. * @param bs Buffer holding the boot sector of the file system. * @param nodep FAT node. * @param bn Block number. * @param flags Flags passed to libblock. * * @return EOK on success or a negative error code. */ int fat_block_get(block_t **block, struct fat_bs *bs, fat_node_t *nodep, aoff64_t bn, int flags) { fat_cluster_t firstc = nodep->firstc; fat_cluster_t currc; aoff64_t relbn = bn; int rc; if (!nodep->size) return ELIMIT; if (!FAT_IS_FAT32(bs) && nodep->firstc == FAT_CLST_ROOT) goto fall_through; if (((((nodep->size - 1) / BPS(bs)) / SPC(bs)) == bn / SPC(bs)) && nodep->lastc_cached_valid) { /* * This is a request to read a block within the last cluster * when fortunately we have the last cluster number cached. */ return block_get(block, nodep->idx->service_id, CLBN2PBN(bs, nodep->lastc_cached_value, bn), flags); } if (nodep->currc_cached_valid && bn >= nodep->currc_cached_bn) { /* * We can start with the cluster cached by the previous call to * fat_block_get(). */ firstc = nodep->currc_cached_value; relbn -= (nodep->currc_cached_bn / SPC(bs)) * SPC(bs); } fall_through: rc = _fat_block_get(block, bs, nodep->idx->service_id, firstc, &currc, relbn, flags); if (rc != EOK) return rc; /* * Update the "current" cluster cache. */ nodep->currc_cached_valid = true; nodep->currc_cached_bn = bn; nodep->currc_cached_value = currc; return rc; }
/** Read block from file located on a FAT file system. * * @param block Pointer to a block pointer for storing result. * @param bs Buffer holding the boot sector of the file system. * @param service_id Service ID handle of the file system. * @param fcl First cluster used by the file. Can be zero if the file * is empty. * @param clp If not NULL, address where the cluster containing bn * will be stored. * stored * @param bn Block number. * @param flags Flags passed to libblock. * * @return EOK on success or a negative error code. */ int _fat_block_get(block_t **block, fat_bs_t *bs, service_id_t service_id, fat_cluster_t fcl, fat_cluster_t *clp, aoff64_t bn, int flags) { uint32_t clusters; uint32_t max_clusters; fat_cluster_t c; int rc; /* * This function can only operate on non-zero length files. */ if (fcl == FAT_CLST_RES0) return ELIMIT; if (!FAT_IS_FAT32(bs) && fcl == FAT_CLST_ROOT) { /* root directory special case */ assert(bn < RDS(bs)); rc = block_get(block, service_id, RSCNT(bs) + FATCNT(bs) * SF(bs) + bn, flags); return rc; } max_clusters = bn / SPC(bs); rc = fat_cluster_walk(bs, service_id, fcl, &c, &clusters, max_clusters); if (rc != EOK) return rc; assert(clusters == max_clusters); rc = block_get(block, service_id, CLBN2PBN(bs, c, bn), flags); if (clp) *clp = c; return rc; }
/** Read block from file located on a exFAT file system. * * @param block Pointer to a block pointer for storing result. * @param bs Buffer holding the boot sector of the file system. * @param nodep FAT node. * @param bn Block number. * @param flags Flags passed to libblock. * * @return EOK on success or a negative error code. */ int exfat_block_get(block_t **block, exfat_bs_t *bs, exfat_node_t *nodep, aoff64_t bn, int flags) { exfat_cluster_t firstc = nodep->firstc; exfat_cluster_t currc = 0; aoff64_t relbn = bn; int rc; if (!nodep->size) return ELIMIT; if (nodep->fragmented) { if (((((nodep->size - 1) / BPS(bs)) / SPC(bs)) == bn / SPC(bs)) && nodep->lastc_cached_valid) { /* * This is a request to read a block within the last cluster * when fortunately we have the last cluster number cached. */ return block_get(block, nodep->idx->service_id, DATA_FS(bs) + (nodep->lastc_cached_value-EXFAT_CLST_FIRST)*SPC(bs) + (bn % SPC(bs)), flags); } if (nodep->currc_cached_valid && bn >= nodep->currc_cached_bn) { /* * We can start with the cluster cached by the previous call to * fat_block_get(). */ firstc = nodep->currc_cached_value; relbn -= (nodep->currc_cached_bn / SPC(bs)) * SPC(bs); } } rc = exfat_block_get_by_clst(block, bs, nodep->idx->service_id, nodep->fragmented, firstc, &currc, relbn, flags); if (rc != EOK) return rc; /* * Update the "current" cluster cache. */ nodep->currc_cached_valid = true; nodep->currc_cached_bn = bn; nodep->currc_cached_value = currc; return rc; }
static struct block * block_get_byid(struct file *file, int id, unsigned char **p_ret) { struct block_index *blk_idx; int blk_num,max; blk_idx=(struct block_index *)(file->begin+0x1000); max=(blk_idx->size-sizeof(struct block_index))/sizeof(struct block_index_item); block_mem+=24; while (id >= max) { blk_idx=(struct block_index *)(file->begin+blk_idx->next*512); id-=max; } blk_num=blk_idx->list[id].blocknum; *p_ret=file->begin+blk_num*512; return block_get(p_ret); }
/** Get cluster from the FAT. * * @param bs Buffer holding the boot sector for the file system. * @param service_id Service ID for the file system. * @param clst Cluster which to get. * @param value Output argument holding the value of the cluster. * * @return EOK or a negative error code. */ int exfat_get_cluster(exfat_bs_t *bs, service_id_t service_id, exfat_cluster_t clst, exfat_cluster_t *value) { block_t *b; aoff64_t offset; int rc; offset = clst * sizeof(exfat_cluster_t); rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE); if (rc != EOK) return rc; *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))); rc = block_put(b); return rc; }
/** Set cluster in FAT. * * @param bs Buffer holding the boot sector for the file system. * @param service_id Service ID for the file system. * @param clst Cluster which is to be set. * @param value Value to set the cluster with. * * @return EOK on success or a negative error code. */ int exfat_set_cluster(exfat_bs_t *bs, service_id_t service_id, exfat_cluster_t clst, exfat_cluster_t value) { block_t *b; aoff64_t offset; int rc; offset = clst * sizeof(exfat_cluster_t); rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE); if (rc != EOK) return rc; *(uint32_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(value); b->dirty = true; /* need to sync block */ rc = block_put(b); return rc; }
void test_move_top_block(){ world_t* world = world_create(3); move_top_block(world, 1, 2); /* Test case 1 - move block on top of another */ assert(world->position_blocks_top[1] == NULL && world->position_blocks_bottom[1] == NULL); assert(world->position_blocks_top[2]->value == 1 && world->position_blocks_bottom[2]->value == 2); assert(equals(block_get(world, 2)->next, block_get(world, 1))); assert(equals(block_get(world, 1)->previous, block_get(world, 2))); assert(block_get_stack(block_get(world, 1)) == 2); /* Test case 2 - try to move slot without block*/ move_top_block(world, 1, 2); /* Test case 3 - block to empty space */ move_top_block(world, 2, 1); assert(equals(world->position_blocks_top[1], block_get(world, 1))); assert(equals(world->position_blocks_bottom[1], block_get(world, 1))); assert(equals(world->position_blocks_top[2], block_get(world, 2))); assert(equals(world->position_blocks_bottom[2], block_get(world, 2))); assert(block_get_stack(block_get(world, 1)) == 1); assert(block_get(world, 2)->next == NULL); assert(block_get(world, 2)->previous == NULL); assert(block_get(world, 1)->next == NULL); assert(block_get(world, 1)->previous == NULL); /* Tear down */ world_delete(&world); }
int process() { BlockMediumInfo bmi; const char* dev_name; BlockOperations* bops; void* iterator = NULL; void* cd_devid; int res; #if TEST_BLOCK_DUMP unsigned long n; int fhandle; char filename[12]; #endif #if TEST_GET_LAST_SESSION uint32_t last_session_address; #endif fd32_message("Searching for CD-ROM drives...\n"); /* Search for all devices with name hd<letter> an test if they respond to FD32_ATAPI_INFO */ while ((dev_name = block_enumerate(&iterator)) != NULL) { if (strncasecmp(dev_name, "cdrom", 5)) { continue; } if (block_get(dev_name, BLOCK_OPERATIONS_TYPE, &bops, &cd_devid) < 0) { fd32_message("Error: Failed to get device data for device %s!\n", dev_name); return 1; } res = bops->open(cd_devid); if(res<0) { fd32_message("Device %s could not be mounted. No medium?\nReturned %i\n", dev_name, res); continue; } res = bops->get_medium_info(cd_devid, &bmi); if(res < 0) { fd32_message("Error: Block medium info failed for device %s\nReturned %i\n", dev_name, res); return 1; } if(bmi.block_bytes != 2048) { fd32_message("Error: Strange sector size %u\n", bmi.block_bytes); return 1; } fd32_message("Disk contains %llu sectors\n", bmi.blocks_count); #if TEST_GET_LAST_SESSION res = req_cd_get_last_session(bops->request, cd_devid, &last_session_address); if(res < 0) { fd32_message("Error: Get last session failed for device %s\nReturned %i\n", dev_name, res); return 1; } fd32_message("Last session start address: %08xh\n", last_session_address); #endif #if TEST_BLOCK_DUMP if(sectors_to_read >= bmi.blocks_count) { ksprintf(filename, "%s.iso", dev_name); sectors_to_read = bmi.blocks_count; } else { ksprintf(filename, "%s.dat", dev_name); } fd32_message("Going to write %lu bytes to file %s...\n", sectors_to_read * 2048, filename); fhandle = fd32_open(filename, O_CREAT | O_TRUNC | O_WRONLY, FD32_ANONE, 0, NULL); if(fhandle < 0) { fd32_message("Error: Unable to open file %s\n", filename); return 1; } for(n=0; n < sectors_to_read; n++) { fd32_log_printf("[CDTEST] Write sector %lu/%lu\n", n, sectors_to_read); res = bops->read(cd_devid, buffer, n, 1, 0); if(res < 0) { fd32_message("Error: Block read failed for device %s\nReturned %i\n", dev_name, res); //fd32_close(fhandle); return 1; } res = fd32_write(fhandle, buffer, 2048); if(res<0) { fd32_message("Error: unable to write to file\n"); fd32_close(fhandle); return 1; } } fd32_close(fhandle); fd32_message("%lu sectors written to file %s\n", sectors_to_read, filename); #endif } return 0; }