void testfs_close_super_block(struct super_block *sb) { testfs_tx_start(sb, TX_UMOUNT); // write sb->sb of type dsuper_block to disk at offset 0. testfs_write_super_block(sb); // assume there are no entries in the inode hash table. // delete the 256 hash size inode hash table inode_hash_destroy(); if (sb->inode_freemap) { // write inode map to disk. write_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); // free in memory bitmap file. bitmap_destroy(sb->inode_freemap); sb->inode_freemap = NULL; } if (sb->block_freemap) { // write inode freemap to disk write_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); // destroy inode freemap bitmap_destroy(sb->block_freemap); sb->block_freemap = NULL; } testfs_tx_commit(sb, TX_UMOUNT); fflush(sb->dev); fclose(sb->dev); sb->dev = NULL; // free in memory data structure sb superblock free(sb); }
static int sfs_mapio(struct sfs_fs *sfs, enum uio_rw rw) { uint32_t j, mapsize; char *bitdata; int result; /* Number of blocks in the bitmap. */ mapsize = SFS_FS_BITBLOCKS(sfs); /* Pointer to our bitmap data in memory. */ bitdata = bitmap_getdata(sfs->sfs_freemap); /* For each sector in the bitmap... */ for (j=0; j<mapsize; j++) { /* Get a pointer to its data */ void *ptr = bitdata + j*SFS_BLOCKSIZE; /* and read or write it. The bitmap starts at sector 2. */ if (rw == UIO_READ) { result = sfs_rblock(sfs, ptr, SFS_MAP_LOCATION+j); } else { result = sfs_wblock(sfs, ptr, SFS_MAP_LOCATION+j); } /* If we failed, stop. */ if (result) { return result; } } return 0; }
void* bitmap_ts_getdata(struct bitmap_ts* b) { assert(b != NULL); lock_acquire(b->lk); void* ret = bitmap_getdata(b->bm); lock_release(b->lk); return ret; }
static void testfs_write_block_freemap(struct super_block *sb, int block_nr) { char *freemap; int nr; assert(sb->block_freemap); freemap = bitmap_getdata(sb->block_freemap); nr = block_nr / (BLOCK_SIZE * BITS_PER_WORD); write_blocks(sb, freemap + (nr * BLOCK_SIZE), sb->sb.block_freemap_start + nr, 1); }
void testfs_close_super_block(struct super_block *sb) { testfs_write_super_block(sb); inode_hash_destroy(); if (sb->inode_freemap) { write_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); bitmap_destroy(sb->inode_freemap); sb->inode_freemap = NULL; } if (sb->block_freemap) { write_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); bitmap_destroy(sb->block_freemap); sb->block_freemap = NULL; } fflush(sb->dev); fclose(sb->dev); sb->dev = NULL; free(sb); }
int testfs_init_super_block(const char *file, struct super_block **sbp) { struct super_block *sb = malloc(sizeof(struct super_block)); char block[BLOCK_SIZE]; int ret, sock; if (!sb) { return -ENOMEM; } if ((sock = open(file, O_RDWR)) < 0) { return errno; } else if ((sb->dev = fdopen(sock, "r+")) == NULL) { return errno; } read_blocks(sb, block, 0, 1); memcpy(&sb->sb, block, sizeof(struct dsuper_block)); ret = bitmap_create(BLOCK_SIZE * INODE_FREEMAP_SIZE * BITS_PER_WORD, &sb->inode_freemap); if (ret < 0) return ret; read_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); ret = bitmap_create(BLOCK_SIZE * BLOCK_FREEMAP_SIZE * BITS_PER_WORD, &sb->block_freemap); if (ret < 0) return ret; read_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); inode_hash_init(); *sbp = sb; return 0; }
static int sfs_init_freemap(struct device *dev, struct bitmap *freemap, uint32_t blkno, uint32_t nblks, void *blk_buffer) { size_t len; void *data = bitmap_getdata(freemap, &len); assert(data != NULL && len == nblks * SFS_BLKSIZE); while (nblks != 0) { int ret; if ((ret = sfs_init_read(dev, blkno, data)) != 0) { return ret; } blkno ++, nblks --, data += SFS_BLKSIZE; } return 0; }
static int file_sync_bitmap(struct file *f) { assert(f != NULL); int result; result = lseek(f->f_fd, SEEK_SET, 0); if (result) { result = DBELSEEK; DBLOG(result); goto done; } TRY(result, io_write(f->f_fd, bitmap_getdata(f->f_page_bitmap), PAGESIZE * FILE_BITMAP_PAGES), done); result = lseek(f->f_fd, SEEK_SET, 0); if (result) { result = DBELSEEK; DBLOG(result); goto done; } done: return result; }
/* returns negative value on error file is name of the disk that was given to testfs. this function initializes all the in memory data structures maintained by the sb block. */ int testfs_init_super_block(const char *file, int corrupt, struct super_block **sbp) { struct super_block *sb = malloc(sizeof(struct super_block)); char block[BLOCK_SIZE]; int ret, sock; if (!sb) { return -ENOMEM; } if ((sock = open(file, O_RDWR #ifndef DISABLE_OSYNC | O_SYNC #endif )) < 0) { return errno; } else if ((sb->dev = fdopen(sock, "r+")) == NULL) { return errno; } // sb->dev type = FILE // read from sb into block. read_blocks(sb, block, 0, 1); // copy only 24 bytes from block corresponding to dsuper_block _memcpy(&sb->sb, block, sizeof(struct dsuper_block)); // 64 * 1 * 8 // bitmap create will return a inode_bitmap structure. // and point sb->inode_freemap to that structure. // currently the inode bitmap is all 0. // at the end of this function, bitmap is created in memory ret = bitmap_create(BLOCK_SIZE * INODE_FREEMAP_SIZE * BITS_PER_WORD, &sb->inode_freemap); if (ret < 0) return ret; // bitmap_getdata returns v -> the byte array containing bit info // read_blocks reads sb->v into sb at offset freemap_start till // INODE_FREEMAP_SIZE // sb is only sent to read_blocks since we need the sb device handle. // data from sb->dev is used to populate arg 2 sb->inode_freemap read_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); ret = bitmap_create(BLOCK_SIZE * BLOCK_FREEMAP_SIZE * BITS_PER_WORD, &sb->block_freemap); if (ret < 0) return ret; read_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); sb->csum_table = malloc(CSUM_TABLE_SIZE * BLOCK_SIZE); if (!sb->csum_table) return -ENOMEM; read_blocks(sb, (char *) sb->csum_table, sb->sb.csum_table_start, CSUM_TABLE_SIZE); sb->tx_in_progress = TX_NONE; /* inode_hash_init() initializes inode_hash_table of size 256 bytes each entry of the inode table contains a first pointer. each node of the first pointer has a prev pointer and a next pointer. */ inode_hash_init(); *sbp = sb; return 0; }