uint64_t leveldb_validate_block::actual_timespan(const uint64_t interval) { // Warning: conversion from 'uint64_t' to 'uint32_t', // possible loss of data in fetch_block parameterization. BITCOIN_ASSERT(interval <= UINT32_MAX); // height - interval and height - 1, return time difference return fetch_block(height_ - 1).timestamp - fetch_block(height_ - (uint32_t)interval).timestamp; }
struct block *File_fetch_block(struct inode *f, int bnum) { struct file_data *fdata; fdata = (struct file_data*)(f->iu.data); if (bnum < NUM_INLINE_BLOCKS) { return fetch_block(fdata->in_blocks[bnum]); } assert(fdata->out_block >= 0); fdata = (struct file_data*)(fetch_block(fdata->out_block)); return fetch_block(fdata->in_blocks[bnum-NUM_INLINE_BLOCKS]); }
nfsstat FS_truncate(struct inode *file, int new_size) { int bnum; struct block *b; struct file_data *fdata = (struct file_data*)(file->iu.data); assert(file->attr.type == NFREG); if (file->attr.size > new_size) { /* Try to free extra blocks */ for (bnum = (new_size+Page_size-1)/Page_size; bnum < file->attr.blocks; bnum++) { b = File_fetch_block(file, bnum); if (b != fs->zero_block) FS_free_block(b); } Byz_modify2(&(file->attr), sizeof(file->attr)); file->attr.size = new_size; file->attr.blocks = (new_size+Page_size-1)/Page_size; if (file->attr.blocks <= NUM_INLINE_BLOCKS && fdata->out_block >= 0) { /* Free indirect block */ FS_free_block(fetch_block(fdata->out_block)); Byz_modify1(&(fdata->out_block)); fdata->out_block = -1; } file->attr.ctime.seconds = cur_time.tv_sec; file->attr.ctime.useconds = cur_time.tv_usec; return NFS_OK; } return FS_append_zeros(file, new_size); }
void server::set_data_directory( const fc::path& dir ) { my->_data_dir = dir / "htdocs"; fc::create_directories( my->_data_dir / "block" ); my->_name_index.open( dir / "name_index" ); my->_block_database.open( dir / "block_database" ); my->_key_data.open( dir / "key_data" ); my->_key_to_name.open( dir / "key_to_name" ); uint32_t last_block = 0; if( my->_block_database.last( last_block ) ) { my->_current_block = fetch_block( last_block ); my->_current_block_id = my->_current_block.id(); } else { ilog( "generating genesis block" ); // generate genesis block... my->_current_block.timestamp = fc::time_point::now(); my->_current_block.number = 0; my->_current_block.difficulty = 1000; my->_current_block.sign( my->_trustee_key ); my->_current_block_id = my->_current_block.id(); my->_block_database.store( 0, my->_current_block ); } }
std::streamsize read(char* strm_ptr, std::streamsize n) { // there is an upper limit of how many bytes we can read // based on the file size n = std::min<std::streamsize>(n, m_file_size - m_file_pos); std::streamsize ret = 0; while(n > 0) { // the block number containing the offset. auto block_number = m_file_pos / READ_CACHING_BLOCK_SIZE; // the offset inside the block auto block_offset = m_file_pos % READ_CACHING_BLOCK_SIZE; // number of bytes I can read inside this block before I hit the next block size_t n_bytes = (block_number + 1) * READ_CACHING_BLOCK_SIZE - m_file_pos; n_bytes = std::min<size_t>(n_bytes, n); bool success = fetch_block(strm_ptr + ret, block_number, block_offset, n_bytes); if (success == false) { log_and_throw(std::string("Unable to read ") + m_filename); } n -= n_bytes; ret += n_bytes; // advance the file position m_file_pos += n_bytes; } return ret; }
static int dump_location(void) { const LOCATION_INFO *loc; const char *p; loc = fetch_block(); if (!loc) return -1; p = (const char*)loc; printf("Location\n"); printf("--------\n\n"); printf("Total size = %d\n", loc->dwTotalSize); printf("Header size = %d\n", loc->dwHeaderSize); printf("Flags = %08x\n", loc->dwFlags); /* dump information about the local volume the link points to */ printf("Local volume ofs = %08x ", loc->dwVolTableOfs); if (loc->dwVolTableOfs && loc->dwVolTableOfs + sizeof(LOCAL_VOLUME_INFO) < loc->dwTotalSize) { const LOCAL_VOLUME_INFO *vol = (const LOCAL_VOLUME_INFO *)&p[loc->dwVolTableOfs]; printf("size %d type %d serial %08x label %d ", vol->dwSize, vol->dwType, vol->dwVolSerial, vol->dwVolLabelOfs); if(vol->dwVolLabelOfs) printf("(\"%s\")", &p[loc->dwVolTableOfs + vol->dwVolLabelOfs]); } printf("\n"); /* dump information about the network volume the link points to */ printf("Network volume ofs = %08x ", loc->dwNetworkVolTableOfs); if (loc->dwNetworkVolTableOfs && loc->dwNetworkVolTableOfs + sizeof(NETWORK_VOLUME_INFO) < loc->dwTotalSize) { const NETWORK_VOLUME_INFO *vol = (const NETWORK_VOLUME_INFO *)&p[loc->dwNetworkVolTableOfs]; printf("size %d name %d ", vol->dwSize, vol->dwShareNameOfs); if(vol->dwShareNameOfs) printf("(\"%s\")", &p[loc->dwNetworkVolTableOfs + vol->dwShareNameOfs]); } printf("\n"); /* dump out the path the link points to */ printf("LocalPath ofs = %08x ", loc->dwLocalPathOfs); if( loc->dwLocalPathOfs && (loc->dwLocalPathOfs < loc->dwTotalSize) ) printf("(\"%s\")", &p[loc->dwLocalPathOfs]); printf("\n"); printf("Net Path ofs = %08x\n", loc->dwNetworkVolTableOfs); printf("Final Path = %08x ", loc->dwFinalPathOfs); if( loc->dwFinalPathOfs && (loc->dwFinalPathOfs < loc->dwTotalSize) ) printf("(\"%s\")", &p[loc->dwFinalPathOfs]); printf("\n"); printf("\n"); return 0; }
struct dir_entry *Directory_entry(struct inode *d, int num) { struct dir_data *ddata; assert(num < d->attr.size); ddata = (struct dir_data*)(d->iu.data); if (num < NUM_INLINE_DIR_ENTRIES) { return ddata->entries+num; } else { num -= NUM_INLINE_DIR_ENTRIES; if (num < NUM_INDIRECT_DIR_ENTRIES) { ddata = (struct dir_data*)fetch_block(dir_block(d)); return ddata->entries+num; } num -= NUM_INDIRECT_DIR_ENTRIES; ddata = (struct dir_data*)fetch_block(dir_block1(d)); return ddata->entries+num; } }
uint64_t leveldb_validate_block::median_time_past() { // read last 11 block times into array and select median value std::vector<uint64_t> times; for (int i = height_ - 1; i >= 0 && i >= (int)height_ - 11; --i) times.push_back(fetch_block(i).timestamp); BITCOIN_ASSERT( (height_ < 11 && times.size() == height_) || times.size() == 11); std::sort(times.begin(), times.end()); return times[times.size() / 2]; }
int FS_lookup_internal(struct inode *dir, char *name) { struct dir_data *d; int num_entries; int i; assert(dir->attr.type == NFDIR); num_entries = dir->attr.size; #ifndef READ_ONLY_OPT /* Update time of last accesss */ Byz_modify2(&(dir->attr.atime), sizeof(dir->attr.atime)); dir->attr.atime.seconds = cur_time.tv_sec; dir->attr.atime.useconds = cur_time.tv_usec; #endif /* First search inline entries */ d = (struct dir_data*)(dir->iu.data); for (i = 0; i < NUM_INLINE_DIR_ENTRIES; i++) { if (i >= num_entries) return -1; if (!strcmp(name, d->entries[i].name)) return i; } /* Search non-inline blocks */ d = (struct dir_data*)fetch_block(dir_block(dir)); num_entries -= NUM_INLINE_DIR_ENTRIES; for (i = 0; i < NUM_INDIRECT_DIR_ENTRIES; i++) { if (i >= num_entries) return -1; if (!strcmp(name, d->entries[i].name)) return i+NUM_INLINE_DIR_ENTRIES; } d = (struct dir_data*)fetch_block(dir_block1(dir)); num_entries -= NUM_INDIRECT_DIR_ENTRIES; for (i = 0; i < num_entries; i++) { if (!strcmp(name, d->entries[i].name)) return i+NUM_INLINE_DIR_ENTRIES+NUM_INDIRECT_DIR_ENTRIES; } return -1; }
signed_name_record server::fetch_record( const std::string& name ) { auto pending_itr = my->_pending.find( name ); if( pending_itr != my->_pending.end() ) return pending_itr->second; auto hist= fetch_history( name ); FC_ASSERT( hist.updates.size() > 0 ); auto old_block = fetch_block( hist.updates.back().block_num ); return fetch_record( hist.updates.back() ); FC_ASSERT( old_block.records.size() > hist.updates.back().record_num ); return old_block.records[hist.updates.back().record_num]; }
void File_store_block(struct inode *f, int bnum, struct block *b) { struct file_data *fdata; fdata = (struct file_data*)(f->iu.data); if (bnum < NUM_INLINE_BLOCKS) { Byz_modify1(&(fdata->in_blocks[bnum])); fdata->in_blocks[bnum] = bnum_block(b); return; } assert(fdata->out_block >= 0); fdata = (struct file_data*)(fetch_block(fdata->out_block)); Byz_modify1(&(fdata->in_blocks[bnum-NUM_INLINE_BLOCKS])); fdata->in_blocks[bnum-NUM_INLINE_BLOCKS] = bnum_block(b); }
/** * Invoked when we see a label in the code * Invoked when we see a label in the code, hence basic block structure have to be changed * @param l label name found */ void found_label(char *l) { struct block *new_block; short found = 1; // if after goto current is g not here, but this is not the case all times // since it can be after goto, but current be here(when g is allocated before) if(!after_goto) current_block->end = linenum - 2; // we have seen this, or there was a 'goto x' where this label comes after it. if((new_block = fetch_block(l)) == NULL) { // no such a thing found = 0; new_block = (struct block*) malloc(sizeof(struct block)); new_block->index = lastid++; new_block->next = NULL; new_block->end = LINE_END; new_block->to = BLOCK_NONE; new_block->to2 = BLOCK_NONE; sprintf(new_block->id, "%s", l); } new_block->begin = linenum - 1; if(!after_goto) { current_block->to = new_block->index; current_block->top = new_block; } else { after_goto = 0; } current_block->to2 = BLOCK_NONE; current_block->to2p = NULL; current_block = gotoend(); if(!found) { current_block->next = new_block; } current_block = new_block; }
/** * Invoked when we see a goto in the code * Invoked when we see a goto in the code, hence basic block structure have to be changed * Note that goto differs from if/label, since it is a terminator, not a beginner of basic-blocks. * @param g goto name found(is where goto goes) */ void found_goto(char *g) { short found = 1; // where goto g goes struct block *label_block; struct block *swap_block; // where goto g continues, there should be a label, to aviod unreachable code if(!after_goto) current_block->end = linenum - 1; if((label_block = fetch_block(g)) == NULL) { found = 0; label_block = (struct block*) malloc(sizeof(struct block)); label_block->index = lastid++; label_block->next = NULL; label_block->end = LINE_END; label_block->to = BLOCK_NONE; label_block->to2 = BLOCK_NONE; sprintf(label_block->id,"%s", g); } current_block->to = label_block->index; current_block->top = label_block; current_block->to2 = BLOCK_NONE; current_block->to2p = NULL; // goto differs from if/label, cuz goto is finished not starter current_block->end = linenum - 1; after_goto = 1; current_block = gotoend(); if(!found) { current_block->next = label_block; current_block = label_block; return; } }
/** * Invoked when we see a if in the code * Invoked when we see a if in the code, hence basic block structure have to be changed * @param i if name found(is where if goes) */ void found_if(char *i) { struct block *cont_block = (struct block*) malloc(sizeof(struct block)); /* Continued Block (!cond)*/ struct block *go_block; /* Goto Block(cond) */ short found = 1; if(!after_goto) current_block->end = linenum - 1; cont_block->begin = linenum; cont_block->end = LINE_END; cont_block->index = lastid++; cont_block->to = BLOCK_NONE; cont_block->to2 = BLOCK_NONE; sprintf(cont_block->id, "_if_%s", i); current_block->to = cont_block->index; current_block->top = cont_block; if((go_block = fetch_block(i)) == NULL) { found = 0; go_block = (struct block*) malloc(sizeof(struct block)); go_block->index = lastid++; go_block->next = NULL; go_block->end = LINE_END; go_block->to = BLOCK_NONE; go_block->to2 = BLOCK_NONE; sprintf(go_block->id,"%s", i); } current_block->to2 = go_block->index; current_block->to2p = go_block; current_block = gotoend(); if(!found) { current_block->next = go_block; current_block = go_block; } current_block->next = cont_block; current_block = cont_block; }
int sfs_remove(char *file){ int index = -1; for (int i = 0; i < MAX_FD; i++){ if (strcmp(file, root[i].fname) == 0){ index = i; //matching file with index i } } //If there is no file with that name if (index < 0){ printf("No file to remove\n"); return 0; //If there is a file with that name } else { int inode_indx = root[index].inode; int block_location; if (inode_table[inode_indx].size > 0){ //if there are some blocks to free //Number of blocks the file spans across: int nmb_of_blocks = (inode_table[inode_indx].size / BLOCK_SIZE) + 1; for (int i = 0; i<nmb_of_blocks; i++){ block_location = fetch_block(inode_indx,i); free_bitmap(block_location); } } //CLOSE IF FILE IS OPEN for (int i = 0; i < MAX_FD; i++){ //check if we have a file opened linked to the same inode if (inode_indx == fd_table[i].inode) { //if we find an open file with same inode as the matched file sfs_fclose(i); } } //REMOVE FROM ROOT DIRECTORY root[index] = (dir){"", -1}; //REINITIALIZE INODE inode_table[inode_indx] = (inode){0, 1, 1, 0, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -1}; //FLUSH flush_to_disk(inode_indx, 0); return 0; } }
uint64_t leveldb_validate_block::actual_timespan(const uint64_t interval) { // height - interval and height - 1, return time difference return fetch_block(height_ - 1).timestamp - fetch_block(height_ - interval).timestamp; }
uint32_t leveldb_validate_block::previous_block_bits() { // Read block d - 1 and return bits return fetch_block(height_ - 1).bits; }
static int handle_read(void* data, struct fuse_data* fd, const struct fuse_in_header* hdr) { const struct fuse_read_in* req = reinterpret_cast<const struct fuse_read_in*>(data); struct fuse_out_header outhdr; struct iovec vec[3]; int vec_used; int result; if (hdr->nodeid != PACKAGE_FILE_ID) return -ENOENT; uint64_t offset = req->offset; uint32_t size = req->size; // The docs on the fuse kernel interface are vague about what to // do when a read request extends past the end of the file. We // can return a short read -- the return structure does include a // length field -- but in testing that caused the program using // the file to segfault. (I speculate that this is due to the // reading program accessing it via mmap; maybe mmap dislikes when // you return something short of a whole page?) To fix this we // zero-pad reads that extend past the end of the file so we're // always returning exactly as many bytes as were requested. // (Users of the mapped file have to know its real length anyway.) outhdr.len = sizeof(outhdr) + size; outhdr.error = 0; outhdr.unique = hdr->unique; vec[0].iov_base = &outhdr; vec[0].iov_len = sizeof(outhdr); uint32_t block = offset / fd->block_size; result = fetch_block(fd, block); if (result != 0) return result; // Two cases: // // - the read request is entirely within this block. In this // case we can reply immediately. // // - the read request goes over into the next block. Note that // since we mount the filesystem with max_read=block_size, a // read can never span more than two blocks. In this case we // copy the block to extra_block and issue a fetch for the // following block. uint32_t block_offset = offset - (block * fd->block_size); if (size + block_offset <= fd->block_size) { // First case: the read fits entirely in the first block. vec[1].iov_base = fd->block_data + block_offset; vec[1].iov_len = size; vec_used = 2; } else { // Second case: the read spills over into the next block. memcpy(fd->extra_block, fd->block_data + block_offset, fd->block_size - block_offset); vec[1].iov_base = fd->extra_block; vec[1].iov_len = fd->block_size - block_offset; result = fetch_block(fd, block+1); if (result != 0) return result; vec[2].iov_base = fd->block_data; vec[2].iov_len = size - vec[1].iov_len; vec_used = 3; } if (writev(fd->ffd, vec, vec_used) < 0) { printf("*** READ REPLY FAILED: %s ***\n", strerror(errno)); } return NO_STATUS; }
signed_name_record server::fetch_record( const name_index& index ) { auto old_block = fetch_block( index.block_num ); FC_ASSERT( old_block.records.size() > index.record_num ); return old_block.records[index.record_num]; }
int sfs_fread(int fileID, char *buf, int length){ if (check_open(fileID) == 0){ printf("Can't write, file not opened\n"); return -1; } //SETTING UP META INFO FOR EASY ACCESS int blk_inode = fd_table[fileID].inode; //inode index of file we are reading from int read_ptr = fd_table[fileID].rptr; //read pointer in bytes int blk_offset = read_ptr % BLOCK_SIZE; //offset in bytes of the wptr within the first block int blk_index = read_ptr / BLOCK_SIZE; //inode pointer of first block we start to read from int block_nmb; /*printf("===================================\n"); printf("Read Pointer is at : %d\n", read_ptr); printf("Length taken as argument: %d\n", length); printf("File size: %d\n", inode_table[blk_inode].size);*/ if (inode_table[blk_inode].size == 0){ printf("File is empty, nothing to read\n"); free(buffer); return 0; } if ((read_ptr + length) > inode_table[blk_inode].size) { length = inode_table[blk_inode].size - read_ptr; } buffer = (void*) malloc(BLOCK_SIZE); int nmb_of_bytes_read = 0; block_nmb = fetch_block(blk_inode, blk_index); //====================if the data we want to read is less than a block======================== if ((blk_offset + length) < BLOCK_SIZE){ read_blocks(block_nmb,1,buffer); memcpy(buf, (buffer+blk_offset), length); //copy to buf only starting from offset nmb_of_bytes_read += length; //====================if the data we want to read is more than a block======================== }else{ // (1) READING REST OF FIRST BLOCK WHERE RPTR IS TO BUFFER read_blocks(block_nmb,1,buffer); memcpy(buf, (buffer+blk_offset), (BLOCK_SIZE - blk_offset)); //copy to buf only starting from offset blk_index++; nmb_of_bytes_read += BLOCK_SIZE - blk_offset; // (2) READING THE FULL BLOCKS int nmb_of_fullblocks = (length - (BLOCK_SIZE - blk_offset)) / BLOCK_SIZE; for (int i = 0; i < nmb_of_fullblocks; i++){ block_nmb = fetch_block(blk_inode, blk_index); read_blocks(block_nmb,1,buffer); memcpy((buf + nmb_of_bytes_read),buffer,BLOCK_SIZE); nmb_of_bytes_read += BLOCK_SIZE; blk_index++; } // (3) READING THE LAST BLOCK block_nmb = fetch_block(blk_inode, blk_index); read_blocks(block_nmb,1,buffer); memcpy(buf + nmb_of_bytes_read, buffer, length - nmb_of_bytes_read); nmb_of_bytes_read += length - nmb_of_bytes_read; } //printf("Number of bytes read: %d\n", nmb_of_bytes_read); //printf("\nIn buf:\n%s\n", buf); //END THE READ //printf("String Length:%lu\n", strlen(buf)); //printf("Length:%d\n", length); free(buffer); return length; }
nfsstat FS_link(struct inode *dir, char *name, struct inode *child) { int num_entries; struct dir_data *d; assert(dir->attr.type == NFDIR); if (strlen(name) > MAX_NAME_LEN) { return NFSERR_NAMETOOLONG; } if (FS_lookup(dir, name) != 0) { return NFSERR_EXIST; } #if 0 /* Need to check acces control */ if (~write_access ()) { return (NFSERR_PERM); } #endif num_entries = dir->attr.size; if (num_entries == MAX_DIR_ENTRIES) { return NFSERR_FBIG; } /* Associate "child" with "name" in "dir" */ if (num_entries < NUM_INLINE_DIR_ENTRIES) { d = (struct dir_data*)(dir->iu.data); Byz_modify2(d->entries+num_entries, strlen(name)+1+sizeof(int)); d->entries[num_entries].inum = inum_inode(child); strcpy(d->entries[num_entries].name, name); } else { num_entries -= NUM_INLINE_DIR_ENTRIES; if (num_entries < NUM_INDIRECT_DIR_ENTRIES) { if (num_entries == 0) { /* Need to allocate first block */ struct block *b = FS_alloc_block(); if (b == 0) return NFSERR_NOSPC; Byz_modify2(&(dir->attr), sizeof(dir->attr)); dir_block(dir) = bnum_block(b); dir->attr.blocks = 1; } d = (struct dir_data*)fetch_block(dir_block(dir)); Byz_modify2(d->entries+num_entries, strlen(name)+1+sizeof(int)); d->entries[num_entries].inum = inum_inode(child); strcpy(d->entries[num_entries].name, name); } else { num_entries -= NUM_INDIRECT_DIR_ENTRIES; if (num_entries == 0) { /* Need to allocate second block */ struct block *b = FS_alloc_block(); if (b == 0) return NFSERR_NOSPC; Byz_modify2(&(dir->attr), sizeof(dir->attr)); dir_block1(dir) = bnum_block(b); dir->attr.blocks = 2; } d = (struct dir_data*)fetch_block(dir_block1(dir)); Byz_modify2(d->entries+num_entries, strlen(name)+1+sizeof(int)); d->entries[num_entries].inum = inum_inode(child); strcpy(d->entries[num_entries].name, name); } } Byz_modify2(&(dir->attr), sizeof(dir->attr)); dir->attr.size++; /* Update time of last modification and last status change for dir */ dir->attr.mtime.seconds = cur_time.tv_sec; dir->attr.mtime.useconds = cur_time.tv_usec; dir->attr.ctime = dir->attr.mtime; Byz_modify2(&(child->attr), sizeof(child->attr)); incr_refcnt(child); /* Update time of last status change for child */ child->attr.ctime = dir->attr.ctime; return NFS_OK; }
nfsstat FS_unlink(struct inode *dir, char *name, int remove_dir) { struct inode *child; int child_num; int child_inum; struct dir_entry *d1, *d2; int refcnt; assert(dir->attr.type == NFDIR); if (strlen(name) > MAX_NAME_LEN) { return NFSERR_NAMETOOLONG; } child_num = FS_lookup_internal(dir, name); if (child_num == -1) { return NFSERR_NOENT; } child_inum = Directory_entry(dir, child_num)->inum; child = fetch_inode(child_inum); if (!remove_dir && child->attr.type == NFDIR) { return NFSERR_ISDIR; } if (remove_dir && child->attr.type != NFDIR) { return NFSERR_NOTDIR; } if (!strcmp(name, ".") || !strcmp(name, "..")) { return NFSERR_ACCES; } #if 0 /* TODO: Need to check acces control */ if (~write_access ()) { return (NFSERR_PERM); } #endif if (remove_dir && child->attr.size != 2 && child->attr.nlink == 2) { return NFSERR_NOTEMPTY; } d1 = Directory_entry(dir, child_num); d2 = Directory_entry(dir, dir->attr.size-1); if (d1 != d2) { Byz_modify2(d1, sizeof(struct dir_entry)); bcopy((char*)d2, (char*)d1, sizeof(struct dir_entry)); } Byz_modify2(&(dir->attr), sizeof(dir->attr)); dir->attr.size--; if (dir->attr.blocks > 0) { if (dir->attr.size <= NUM_INLINE_DIR_ENTRIES) { /* Can free first indirect block */ FS_free_block(fetch_block(dir_block(dir))); dir_block(dir) = -1; dir->attr.blocks = 0; } else { if (dir->attr.blocks > 1 && dir->attr.size <= NUM_INLINE_DIR_ENTRIES+NUM_INDIRECT_DIR_ENTRIES) { /* Can free second indirect block */ FS_free_block(fetch_block(dir_block1(dir))); dir_block1(dir) = -1; dir->attr.blocks = 1; } } } dir->attr.ctime.seconds = cur_time.tv_sec; dir->attr.ctime.useconds = cur_time.tv_usec; dir->attr.mtime = dir->attr.ctime; Byz_modify2(&(child->attr), sizeof(child->attr)); refcnt = decr_refcnt(child); if (refcnt == 0) { /* Free child and its associated storage */ if (child->attr.type == NFREG) FS_truncate(child, 0); FS_free_inode(child); return NFS_OK; } else { /* Update time of last status change for child */ child->attr.ctime = dir->attr.ctime; } /* If it is a directory "." points to self so refcnt == 1 means it can be removed. We checked for emptyness before. */ if (refcnt == 1 && child->attr.type == NFDIR) { /* Decrement reference count of parent */ struct inode *parent = FS_lookup(child, ".."); if (parent != dir) { Byz_modify1(&(parent->attr.nlink)); } decr_refcnt(parent); FS_free_inode(child); } return NFS_OK; }
void lnk_dump(void) { const LINK_HEADER* hdr; const DATABLOCK_HEADER* bhdr; DWORD dwFlags; offset = 0; hdr = fetch_block(); if (!hdr) return; printf("Header\n"); printf("------\n\n"); printf("Size: %04x\n", hdr->dwSize); printf("GUID: %s\n", get_guid_str(&hdr->MagicGuid)); printf("FileAttr: %08x\n", hdr->dwFileAttr); printf("FileLength: %08x\n", hdr->dwFileLength); printf("nIcon: %d\n", hdr->nIcon); printf("Startup: %d\n", hdr->fStartup); printf("HotKey: %08x\n", hdr->wHotKey); printf("Unknown5: %08x\n", hdr->Unknown5); printf("Unknown6: %08x\n", hdr->Unknown6); /* dump out all the flags */ printf("Flags: %04x ( ", hdr->dwFlags); dwFlags=hdr->dwFlags; #define FLAG(x) do \ { \ if (dwFlags & SLDF_##x) \ { \ printf("%s ", #x); \ dwFlags&=~SLDF_##x; \ } \ } while (0) FLAG(HAS_ID_LIST); FLAG(HAS_LINK_INFO); FLAG(HAS_NAME); FLAG(HAS_RELPATH); FLAG(HAS_WORKINGDIR); FLAG(HAS_ARGS); FLAG(HAS_ICONLOCATION); FLAG(UNICODE); FLAG(FORCE_NO_LINKINFO); FLAG(HAS_EXP_SZ); FLAG(RUN_IN_SEPARATE); FLAG(HAS_LOGO3ID); FLAG(HAS_DARWINID); FLAG(RUNAS_USER); FLAG(HAS_EXP_ICON_SZ); FLAG(NO_PIDL_ALIAS); FLAG(FORCE_UNCNAME); FLAG(RUN_WITH_SHIMLAYER); FLAG(FORCE_NO_LINKTRACK); FLAG(ENABLE_TARGET_METADATA); FLAG(DISABLE_KNOWNFOLDER_RELATIVE_TRACKING); FLAG(RESERVED); #undef FLAG if (dwFlags) printf("+%04x", dwFlags); printf(")\n"); printf("Length: %04x\n", hdr->dwFileLength); printf("\n"); if (hdr->dwFlags & SLDF_HAS_ID_LIST) dump_pidl(); if (hdr->dwFlags & SLDF_HAS_LINK_INFO) dump_location(); if (hdr->dwFlags & SLDF_HAS_NAME) dump_string("Description", hdr->dwFlags & SLDF_UNICODE); if (hdr->dwFlags & SLDF_HAS_RELPATH) dump_string("Relative path", hdr->dwFlags & SLDF_UNICODE); if (hdr->dwFlags & SLDF_HAS_WORKINGDIR) dump_string("Working directory", hdr->dwFlags & SLDF_UNICODE); if (hdr->dwFlags & SLDF_HAS_ARGS) dump_string("Arguments", hdr->dwFlags & SLDF_UNICODE); if (hdr->dwFlags & SLDF_HAS_ICONLOCATION) dump_string("Icon path", hdr->dwFlags & SLDF_UNICODE); bhdr=fetch_block(); while (bhdr) { if (!bhdr->cbSize) break; switch (bhdr->dwSignature) { case EXP_SZ_LINK_SIG: dump_sz_block(bhdr, "exp.link"); break; case EXP_SPECIAL_FOLDER_SIG: dump_special_folder_block(bhdr); break; case EXP_SZ_ICON_SIG: dump_sz_block(bhdr, "icon"); break; case EXP_DARWIN_ID_SIG: dump_darwin_id(bhdr); break; default: dump_raw_block(bhdr); } bhdr=fetch_block(); } }
int sfs_fwrite(int fileID, char *buf, int length){ if (check_open(fileID) == 0){ printf("Can't write, file not opened\n"); return -1; } //SETTING UP META INFO FOR EASY ACCESS buffer = (void*) malloc(BLOCK_SIZE); int blk_inode = fd_table[fileID].inode; //inode index of file we are writing in int current_size = inode_table[blk_inode].size; //file size in bytes int write_ptr = fd_table[fileID].wptr; //write pointer in bytes int blk_offset = write_ptr % BLOCK_SIZE; //offset in bytes of the wptr within the first block int blk_index = write_ptr / BLOCK_SIZE; //inode pointer of first block we start to write in //get block number where wptr is located within sfs int block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } //GETTING THE BLOCK WHERE WPTR IS read_blocks(block_nmb,1,buffer); //read what's already on the block /*printf("WPTR AT: %d\n", write_ptr); printf("File size before read: %d\n", current_size); printf("current_size: %d\n", current_size); printf("Write pointer + length: %d\n", write_ptr + length);*/ //UPDATING INODE SIZE if (current_size < write_ptr + length) { inode_table[blk_inode].size = write_ptr + length; } fd_table[fileID].wptr = write_ptr + length; //==========================if the data WILL NOT overflow to next block======================== if (blk_offset + length < BLOCK_SIZE) { memcpy((buffer+blk_offset),buf,length); //write the whole block with added data in buffer //WRITE THE BLOCK ON DISK write_blocks(block_nmb, 1, buffer); //==========================if the data WILL overflow to next block============================= } else { int nmb_of_bytes_copied = 0; //WRITING THE FIRST BLOCK memcpy(buffer+blk_offset,buf,(BLOCK_SIZE-blk_offset)); //write the whole block with added data in buffer nmb_of_bytes_copied += BLOCK_SIZE - blk_offset; //(1) WRITE THE FIRST BLOCK ON DISK write_blocks(block_nmb, 1, buffer); blk_index++; //(2) WRITE THE FULL BLOCKS int nmb_of_fullblocks = (length - (BLOCK_SIZE-blk_offset)) / BLOCK_SIZE; for (int i = 0; i < nmb_of_fullblocks; i++){ memcpy(buffer,(buf+nmb_of_bytes_copied),BLOCK_SIZE); nmb_of_bytes_copied += BLOCK_SIZE; block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } write_blocks(block_nmb, 1, buffer); blk_index++; } //(3) WRITE LAST BLOCK memcpy(buffer,(buf+nmb_of_bytes_copied),(length-nmb_of_bytes_copied)); block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } write_blocks(block_nmb, 1, buffer); } //printf("Length written: %d\n", length); //printf("File size after read: %d\n", inode_table[blk_inode].size); //END THE WRITE free(buffer); flush_to_disk(blk_inode, 2); //flushing with option 2 return length; }