/* * fat_free_clusters - starts at given cluster and marks all as free until an * end of chain marker is found */ int fat_free_clusters(uint32_t cluster) { int estart; uint32_t j; blockno_t current_block = MAX_BLOCK; while(1) { if(fatfs.active_fat_start + ((cluster * fatfs.fat_entry_len) / 512) != current_block) { if(current_block != MAX_BLOCK) { block_write(current_block, fatfs.sysbuf); } if(block_read(fatfs.active_fat_start + ((cluster * fatfs.fat_entry_len) / 512), fatfs.sysbuf)) { return -1; } current_block = fatfs.active_fat_start + ((cluster * fatfs.fat_entry_len)/512); } estart = (cluster * fatfs.fat_entry_len) & 0x1ff; j = fatfs.sysbuf[estart]; fatfs.sysbuf[estart] = 0; j += fatfs.sysbuf[estart + 1] << 8; fatfs.sysbuf[estart+1] = 0; if(fatfs.type == PART_TYPE_FAT32) { j += fatfs.sysbuf[estart + 2] << 16; fatfs.sysbuf[estart+2] = 0; j += fatfs.sysbuf[estart + 3] << 24; fatfs.sysbuf[estart+3] = 0; } cluster = j; if(cluster >= fatfs.end_cluster_marker) { break; } } block_write(current_block, fatfs.sysbuf); return 0; }
/** * @brief write data of buffer into a block, from the beginning of block * @param last the last block used for writing (0 for searching from start) * @param nbyte * @return last block used in file */ int write_starting_from_block(int last, char *buffer, int *n_byte) { int next, nbyte = *n_byte; char *buff = (char *) malloc(BLOCK_SIZE); int i = 0; // write in (BLOCK_SIZE - 4) chunks while (nbyte > BLOCK_SIZE - 4) { next = get_first_empty_block_from(last + 1); memcpy(buff, buffer + (i * (BLOCK_SIZE - 4)), BLOCK_SIZE - 4); memcpy(buff + ((i + 1) * BLOCK_SIZE - 4), &next, 4); block_write(last, buff); last = next; nbyte -= (BLOCK_SIZE - 4); i++; } // write the remainder data (less than BLOCK_SIZE - 4) next = -1; memset(buff, 0, BLOCK_SIZE); memcpy(buff, buffer + (i * (BLOCK_SIZE - 4)), nbyte); memcpy(buff + ((i + 1) * BLOCK_SIZE - 4), &next, 4); block_write(last, buff); return last; }
size_t level_two(struct inode *inode, struct indirect_inode* first_level_block, size_t new_sectors) { struct indirect_inode second_level_block; char filler[BLOCK_SECTOR_SIZE]; if (inode->double_indirect_index == 0) { free_map_allocate(1, &outer_block->pointers[inode->indirect_index]); } else { block_read(fs_device, outer_block->pointers[inode->indirect_index], &second_level_block); } while (inode->double_indirect_index < INDIRECT_POINTERS && new_sectors != 0) { free_map_allocate(1, &second_level_block.pointers[inode->double_indirect_index]); block_write(fs_device, second_level_block.pointers[inode->double_indirect_index], filler); inode->double_indirect_index++; new_sectors--; } block_write(fs_device, outer_block->pointers[inode->indirect_index], &second_level_block); if (inode->double_indirect_index == INDIRECT_POINTERS) { inode->double_indirect_index = 0; inode->indirect_index++; } return new_sectors; }
int fs_write(int fildes, void *buffer, size_t nbyte) { // check file is opened if (meta->fcb_list[fildes].is_opened == 0) return -1; // check that there is free space left on hard-disk if (meta->vcb.free_block_count < (nbyte / BLOCK_SIZE) + 1) return -1; // update size of FCB meta->fcb_list[fildes].size += nbyte; // if this is the first time to write to file // then we must find an empty block and write to it if (meta->fcb_list[fildes].first_block == 0) { int last = get_first_empty_block(); meta->fcb_list[fildes].first_block = last; last = write_starting_from_block(last - 1, buffer, &nbyte); meta->fcb_list[fildes].last_block = last; meta->fcb_list[fildes].last_block_used = nbyte; } // else we must find last block of previous write else { char *buff = (char *) malloc(BLOCK_SIZE); // if the new data does not need allocation of new block if (meta->fcb_list[fildes].last_block_used + 4 + nbyte <= BLOCK_SIZE) { block_read(meta->fcb_list[fildes].last_block, buff); memcpy(buff + (meta->fcb_list[fildes].last_block_used), buffer, nbyte); block_write(meta->fcb_list[fildes].last_block, buff); meta->fcb_list[fildes].last_block_used += nbyte; } // there are new blocks to be assigned to the file else { int last = meta->fcb_list[fildes].last_block; block_read(last, buff); memcpy(buff + (meta->fcb_list[fildes].last_block_used), buffer, (BLOCK_SIZE - 4 - meta->fcb_list[fildes].last_block_used)); int next = get_first_empty_block(); memcpy(buff + (BLOCK_SIZE - 4), &next, 4); block_write(last, buff); last = next; nbyte -= (BLOCK_SIZE - 4 - meta->fcb_list[fildes].last_block_used); last = write_starting_from_block(last, buffer, &nbyte); meta->fcb_list[fildes].last_block = last; meta->fcb_list[fildes].last_block_used = nbyte; } } metadata_rewrite(); }
/* Initializes an inode with LENGTH bytes of data and writes the new inode to sector SECTOR on the file system device. Returns true if successful. Returns false if memory or disk allocation fails. */ bool inode_create (block_sector_t sector, off_t length) { struct inode_disk *disk_inode = NULL; bool success = false; ASSERT (length >= 0); /* If this assertion fails, the inode structure is not exactly one sector in size, and you should fix that. */ ASSERT (sizeof *disk_inode == BLOCK_SECTOR_SIZE); disk_inode = calloc (1, sizeof *disk_inode); if (disk_inode != NULL) { size_t sectors = bytes_to_sectors (length); disk_inode->length = length; disk_inode->magic = INODE_MAGIC; if (free_map_allocate (sectors, &disk_inode->start)) { block_write (fs_device, sector, disk_inode); if (sectors > 0) { static char zeros[BLOCK_SECTOR_SIZE]; size_t i; for (i = 0; i < sectors; i++) block_write (fs_device, disk_inode->start + i, zeros); } success = true; } free (disk_inode); } return success; }
void get_status(void) { char c; set_alrm(5); /* 5 second timeout to fetch status */ tty_flush(); c = '\024'; block_write(&c, 1); /* send Control-T to printer */ init_input(0); while (status == INVALID) proc_some_input(); /* wait for something back */ switch (status) { case IDLE: /* this is what we're looking for ... */ clear_alrm(); return; case WAITING: /* printer thinks it's in the middle of a job */ block_write(&eofc, 1); /* send EOF to printer */ sleep(5); exit(EXIT_REPRINT); case BUSY: case UNKNOWN: sleep(15); exit(EXIT_REPRINT); } }
// Writes all the bitmaps to disk void fs_bitmaps_write_all() { bitmap_handling = 1; int i = 0; for (; i < FS_BLOCK_GROUP_COUNT; i++) { block_write((void *)&g_inode_bmps[i], gbdt[i].bg_inode_bitmap); block_write((void *)&g_block_bmps[i], gbdt[i].bg_block_bitmap); } bitmap_handling = 0; }
static int sec_send(int fd, char *from, int length) { int bytes; void *buf; bytes = (*mech->encode)(app_data, from, length, data_prot, &buf); bytes = htonl(bytes); block_write(fd, &bytes, sizeof(bytes)); block_write(fd, buf, ntohl(bytes)); free(buf); return length; }
static int sec_send(struct connectdata *conn, int fd, char *from, int length) { int bytes; void *buf; bytes = (conn->mech->encode)(conn->app_data, from, length, conn->data_prot, &buf, conn); bytes = htonl(bytes); block_write(fd, &bytes, sizeof(bytes)); block_write(fd, buf, ntohl(bytes)); free(buf); return length; }
static void swap_write (block_sector_t sec_no_start, void *buffer, int size) { //printf ("[Debug] swap_write ()!\n"); block_sector_t sec_no = sec_no_start; uint32_t size_lb = (uint32_t) size & ~(uint32_t) (BLOCK_SECTOR_SIZE-1); char b[BLOCK_SECTOR_SIZE]; int s; int cnt = 0; for (s = 0; s < size_lb; s += BLOCK_SECTOR_SIZE, ++cnt) block_write (swap_block, sec_no++, buffer + s); memcpy (b, buffer + s, size - s); block_write (swap_block, sec_no++, b); //printf ("[Debug] cnt : %d\n", cnt); }
static void fsi_store_fsdata(fs_t* fs) { blocks_t* bks = fs->blocks; // store free block bitmap to block 0 block_write(bks,0,fs->blk_bmap); // store free inode bitmap to block 1 block_write(bks,1,fs->inode_bmap); // store inode table to blocks 2-9 for (int i = 0; i < ITAB_NUM_BLKS; i++) { block_write(bks,i+2,&((char*)fs->inode_tab)[i*BLOCK_SIZE]); } }
//Swap out memory to the disk. The src_addr points to a page worth of user //memory. This will be read into the swap space. The disk_block pointer //will get set to the location at which the memory was stored. void swap_out (uint32_t *src_addr, block_sector_t *disk_block) { lock_acquire(&st->swap_table_lock); //Find available space on disk in the swap space block_sector_t block_offset = bitmap_scan_and_flip(st->map, 0, PGSIZE/BLOCK_SECTOR_SIZE, false); if (block_offset == BITMAP_ERROR) { lock_release(&st->swap_table_lock); PANIC ("BITMAP error in scanning swap space for block offset"); } //Update disk_block to the location on disk where the memory is being stored lock_release(&st->swap_table_lock); //write the memory from the src_addr onto the block int i = 0; for (i = 0; i<PGSIZE; i += BLOCK_SECTOR_SIZE) { block_write (st->swap_block, i/BLOCK_SECTOR_SIZE + block_offset, src_addr + i/sizeof(uint32_t)); } *disk_block = block_offset; }
int sys_write (unsigned int fd, char *buf, int count) { struct file *file; struct m_inode *inode; // 如果文件句柄值大于程序最多打开文件数NR_OPEN,或者需要写入的字节计数小于0,或者该句柄 // 的文件结构指针为空,则返回出错码并退出。 if (fd >= NR_OPEN || count < 0 || !(file = current->filp[fd])) return -EINVAL; // 若需读取的字节数count 等于0,则返回0,退出 if (!count) return 0; // 取文件对应的i 节点。若是管道文件,并且是写管道文件模式,则进行写管道操作,若成功则返回 // 写入的字节数,否则返回出错码,退出。 inode = file->f_inode; if (inode->i_pipe) return (file->f_mode & 2) ? write_pipe (inode, buf, count) : -EIO; // 如果是字符型文件,则进行写字符设备操作,返回写入的字符数,退出。 if (S_ISCHR (inode->i_mode)) return rw_char (WRITE, inode->i_zone[0], buf, count, &file->f_pos); // 如果是块设备文件,则进行块设备写操作,并返回写入的字节数,退出。 if (S_ISBLK (inode->i_mode)) return block_write (inode->i_zone[0], &file->f_pos, buf, count); // 若是常规文件,则执行文件写操作,并返回写入的字节数,退出。 if (S_ISREG (inode->i_mode)) return file_write (inode, file, buf, count); // 否则,显示对应节点的文件模式,返回出错码,退出。 printk ("(Write)inode->i_mode=%06o\n\r", inode->i_mode); return -EINVAL; }
/* Closes INODE and writes it to disk. If this was the last reference to INODE, frees its memory. If INODE was also a removed inode, frees its blocks. */ void inode_close (struct inode *inode) { /* Ignore null pointer. */ if (inode == NULL) return; /* Release resources if this was the last opener. */ if (--inode->open_cnt == 0) { /* Remove from inode list and release lock. */ list_remove (&inode->elem); /* Deallocate blocks if removed. */ if (inode->removed) { int num_sectors = bytes_to_sectors (inode->length); inode_release_allocated_sectors (inode, num_sectors); uint8_t buf[BLOCK_SECTOR_SIZE]; memset (buf, 0, BLOCK_SECTOR_SIZE); block_write (fs_device, inode->sector, buf); free_map_release (inode->sector, 1); } free (inode); } }
BOOLEANC dict_save_block( DICTIONARY *dict , char *toc_id , FILE *fo ) { DICT_TOC_ENTRY *dt_entry; int index, ret_code; char *block; index = dict_toc_index( dict , toc_id ); if ( index == -1 ) { signal_error( "dict_save_block: id not found " , toc_id , 1 ); return( FALSE ); } /* endif */ dt_entry = &(dict->toc[index]); block = (char*)(dt_entry->ptr); if ( block == NULL ) { signal_error( "dict_save_block: NULL block " , toc_id , 1 ); return( FALSE ); } /* endif */ /* dt_entry->offset = fseek( fo , 0 , SEEK_END ); */ dt_entry->checksum = compute_checksum( dt_entry->size , block ); ret_code = block_write( fo , dt_entry->ptr , dt_entry->size ); if ( ret_code == -1 ) { signal_error( "dict_save_block: block_write failed " , toc_id , 1 ); return( FALSE ); } /* endif */ if ( trace > 3 ) { fprintf( ft , "\nStored block\nTOC entry: id:%s offset:%lx size:%lx ptr:%p checksum:%lx type:%d\n" , dict->toc[index].id , dict->toc[index].offset , dict->toc[index].size , dict->toc[index].ptr , dict->toc[index].checksum , dict->toc[index].type ); } /* endif */ return( TRUE ); }
// When the cache is full, evict a cache_block using second chance algorithm. struct cache_block * cache_evict() { lock_acquire(&evict_lock); struct cache_block *cb; bool loop = true; while (loop) { struct list_elem *e; for (e = list_begin(&cache_list); e != list_end(&cache_list); e = list_next(e)) { cb = list_entry(e, struct cache_block, elem); if (cb->access) { cb->access = false; } else { if (cb->dirty) { block_write(fs_device, cb->sector_no, &cb->data); } lock_release(&evict_lock); return cb; } } } }
/* Initializes an inode with LENGTH bytes of data and wirtes the new inode to sector SECTOR on the file system device. Returns true if successful. Returns false if memeory or disk allocation fails. */ bool inode_create (block_sector_t sector, off_t length){ struct inode_disk *disk_inode = NULL; bool success = false; ASSERT (length >= 0); /* If this assertion fails, the inode structure is not exactly one sector in size, and you should fix that */ ASSERT (sizeof *disk_inode == BLOCK_SECTOR_SIZE); disk_inode = calloc(1, sizeof *disk_inode); if (disk_inode != NULL){ size_t sectors = bytes_to_sectors (length); disk_inode->length = length; disk_inode->magic = INODE_MAGIC; if (free_map_allocate (sectors, &disk_inode->start)) { block_write(fs_device, sector, disk_inode); success = file_growth(disk_inode, sectors); free(disk_inode); } } return success; }
static uint32_t _cache_evict (void) { static uint32_t clock_hand = 0; while (true) { clock_hand++; if (clock_hand == CACHE_SIZE) clock_hand = 0; if (cache[clock_hand].accessed) cache[clock_hand].accessed = false; else { lock_acquire (&cache[clock_hand].cs_lock); while (cache[clock_hand].rw_count != 0) cond_wait (&cache[clock_hand].no_rw_cond, &cache[clock_hand].cs_lock); if (cache[clock_hand].dirty) block_write (cache[clock_hand].block, cache[clock_hand].sector, cache[clock_hand].data); lock_release (&cache[clock_hand].cs_lock); _cache_slot_init (clock_hand); return clock_hand; } } }
/* flush data from buffer cache to disk */ void bc_flush_entry(struct buffer_head *p_flush_entry) { /* write data of buffer cache to disk */ block_write(fs_device, p_flush_entry->sector, p_flush_entry->data); /* updata dirty value */ p_flush_entry->dirty = false; }
/*! Initializes an inode with LENGTH bytes of data and writes the new inode to sector SECTOR on the file system device. Returns true if successful. Returns false if memory or disk allocation fails. */ bool inode_create(block_sector_t sector, off_t length) { struct inode_disk *disk_inode = NULL; bool success = true; int i; ASSERT(length >= 0); /* If this assertion fails, the inode structure is not exactly one sector in size, and you should fix that. */ ASSERT(sizeof *disk_inode == BLOCK_SECTOR_SIZE); disk_inode = calloc(1, sizeof *disk_inode); if (disk_inode != NULL) { disk_inode->length = 0; disk_inode->magic = INODE_MAGIC; for (i = 0; i < 126; i++) { disk_inode->block_list[i] = -1; } success = grow(disk_inode, length); if (success) { lock_acquire(filesys_lock_list + sector); block_write(fs_device, sector, disk_inode); lock_release(filesys_lock_list + sector); } free(disk_inode); return success; } // no memory for disk inode return false; }
struct cached_block * evict_cache_block (void) { struct cached_block *cb; if (e == NULL) e = list_begin (&cache_list); while (true) { cb = list_entry (e, struct cached_block, elem); if (cb->open > 0) continue; else if (cb->accessed) cb->accessed = false; else { if (cb->dirty) block_write (fs_device, cb->sector, cb->data); break; } e = list_next (e); if (e == list_end (&cache_list)) e = list_begin (&cache_list); } return cb; }
//adds a page to swap space, gets called with the physical memory position size_t add_swap (void * addr) { //init swap if necessary if (swap == NULL) //init the swap table init_swap (); //lock the swap table lock_acquire(&swap_lock); //find a free entry in the bitmap table size_t free = bitmap_scan (swap_table, 0, 1, false); //if the swap table is full panic the kernel if (free == BITMAP_ERROR) PANIC ("Swaptable is full\n"); int i; //get frame and the memory position and write it to swap for (i = 0; i< SECPP; i++) //write block to swap, free * SECPP is the correct block position and + i because a page has a different size, same for addr block_write (swap, free * SECPP + i, addr + BLOCK_SECTOR_SIZE * i); //set the corresponding entry in the swap_table to true bitmap_set (swap_table, free, true); //release the lock for the swap table lock_release(&swap_lock); return free; }
int fs_format(fs_t* fs) { if (fs == NULL) { printf("[fs] argument is null.\n"); return -1; } // erase all blocks char null_block[BLOCK_SIZE]; memset(null_block,0,sizeof(null_block)); for (int i = 0; i < block_num_blocks(fs->blocks); i++) { block_write(fs->blocks,i,null_block); } // reserve file system meta data blocks BMAP_SET(fs->blk_bmap,0); BMAP_SET(fs->blk_bmap,1); for (int i = 0; i < ITAB_NUM_BLKS; i++) { BMAP_SET(fs->blk_bmap,i+2); } // reserve inodes 0 (will never be used) and 1 (the root) BMAP_SET(fs->inode_bmap,0); BMAP_SET(fs->inode_bmap,1); fsi_inode_init(&fs->inode_tab[1],FS_DIR); // save the file system metadata fsi_store_fsdata(fs); return 0; }
// Release (erase) a data block static void data_release_block(unsigned int block_n) { unsigned int block_group = (block_n - 1) / sb->s_blocks_per_group; // Write the bitmap in the disk bitmap_write(bm_blocks, block_n - 1, 0); block_write(&g_block_bmps[block_group], bgroup_blockbmp(bgroup_get(block_group))); }
int memory_write(stream_t* stream, void* m, size_t n) { int i = 0; printf("Memory: 0x%X\n", (unsigned int)m); for(; i < BLOCKS(stream, n); i++) block_write(stream, MEMORY_BLOCK(stream, m, i)); return 0; }
void setdir(struct inode * inode, bool isdir) { struct inode_disk *inode_disk = (struct inode_disk*)calloc(1,512); block_read(fs_device,inode->sector,inode_disk); inode_disk->is_dir = isdir; block_write(fs_device,inode->sector,inode_disk); free(inode_disk); }
void *sfs_init(struct fuse_conn_info *conn) { log_msg("Testing- log started- sfs_init()\n"); log_msg("\nsfs_init()\n"); log_conn(conn); log_fuse_context(fuse_get_context()); disk_open(SFS_DATA->diskfile); char *readbuf; char *writebuf; int status=block_read(0,&readbuf); struct super_block* sb; //writebuf=&sb; if(status==0){//first time in sfs_init sb = (struct super_block*)malloc(sizeof(struct super_block)); log_msg("Testing- first time in sfs_init\n"); sb->size=131072; sb->nblocks=256; sb->ninode=0; //log_msg("%d\n",sb.nblocks); writebuf=sb; int write_status=block_write(0,&writebuf); //log_msg("%d", write_status); if(write_status>0){ log_msg("Testing- write successful %d\n",write_status); struct super_block* testbuf; int x=block_read(0,&testbuf); log_msg("Read status %d\n",x); log_msg("Block read %d\n",testbuf->size); log_msg("Block read %d\n",testbuf->nblocks); log_msg("Block read %d\n",testbuf->ninode); } } disk_close(); //log_msg(hello_path); //char *test="abcd"; // char *test2; //int output=block_write(0,&test); //output = block_read(0, &test2); // log_msg("Block read :%s", test2); //log_msg(output); //disk_close(); log_msg("Testing- exiting sfs_init()\n"); return SFS_DATA; }
struct cache_list_entry * get_element_to_be_evicted() { bool no_free_entry = true; struct cache_list_entry *cache_entry=NULL, *reserve=NULL; struct list_elem *cache_list_elem; for (cache_list_elem = list_begin(&cache_list); cache_list_elem != list_end(&cache_list); cache_list_elem = list_next(cache_list_elem)){ cache_entry = list_entry(cache_list_elem, struct cache_list_entry, cache_elem); if (cache_entry->currently_using_this_cache > 0){ continue; } if (cache_entry->is_accessed){ cache_entry->is_accessed = false; reserve = cache_entry; //save this for worst case scenario } else{ if (cache_entry->is_dirty){ block_write(fs_device, cache_entry->sector_in_cache, &cache_entry->block); } no_free_entry = false; break; } } if(no_free_entry){ for (cache_list_elem = list_begin(&cache_list); cache_list_elem != list_end(&cache_list); cache_list_elem = list_next(cache_list_elem)){ cache_entry = list_entry(cache_list_elem, struct cache_list_entry, cache_elem); if(cache_entry==reserve){ cache_entry->is_accessed = false; if (cache_entry->is_dirty){ block_write(fs_device, cache_entry->sector_in_cache, &cache_entry->block); } } } } return cache_entry; }
/*! Takes a page and writes it into the given swap entry file. */ void swap_write_page(struct swap* swap_entry, void *upage) { ASSERT(swap_entry->in_use); uint32_t i; for (i = 0; i < PAGE_SECTORS; i++) { block_write(swap_disk, swap_entry->start_sector + i, upage + i * BLOCK_SECTOR_SIZE); } }
/* write a sector back to disc */ int fat_flush(int fd) { uint32_t cluster; #ifdef TRACE printf("fat_flush\n"); #endif /* only write to disk if we need to */ if(file_num[fd].flags & FAT_FLAG_DIRTY) { if(file_num[fd].sector == 0) { /* this is a new file that's never been saved before, it needs a new cluster * assigned to it, the data stored, then the meta info flushed */ cluster = fat_get_free_cluster(); if(cluster == 0xFFFFFFFF) { return -1; } else if(cluster == 0) { return -1; } else { // file_num[fd].cluster = cluster; file_num[fd].full_first_cluster = cluster; file_num[fd].flags |= FAT_FLAG_FS_DIRTY; file_num[fd].sector = cluster * fatfs.sectors_per_cluster + fatfs.cluster0; file_num[fd].sectors_left = fatfs.sectors_per_cluster - 1; file_num[fd].cluster = cluster; // file_num[fd].sector = cluster * fatfs.sectors_per_cluster + fatfs.cluster0; } if(block_write(file_num[fd].sector, file_num[fd].buffer)) { /* write failed, don't clear the dirty flag */ return -1; } file_num[fd].flags &= ~FAT_FLAG_DIRTY; fat_flush_fileinfo(fd); // block_pc_snapshot_all("writenfs.img"); // exit(-9); } else { if(block_write(file_num[fd].sector, file_num[fd].buffer)) { /* write failed, don't clear the dirty flag */ return -1; } file_num[fd].flags &= ~FAT_FLAG_DIRTY; } } return 0; }