예제 #1
0
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;
}
예제 #2
0
파일: fs.c 프로젝트: vonwenm/pbft
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]);
}
예제 #3
0
파일: fs.c 프로젝트: vonwenm/pbft
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);
}
예제 #4
0
   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 );
      }
   }
예제 #5
0
 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;
 }
예제 #6
0
파일: lnk.c 프로젝트: Sunmonds/wine
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;
}
예제 #7
0
파일: fs.c 프로젝트: vonwenm/pbft
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];
}
예제 #9
0
파일: fs.c 프로젝트: vonwenm/pbft
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;
}
예제 #10
0
   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];
   }
예제 #11
0
파일: fs.c 프로젝트: vonwenm/pbft
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);
}
예제 #12
0
파일: gopt.c 프로젝트: abbaspour/gopt
/**
 * 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;
}
예제 #13
0
파일: gopt.c 프로젝트: abbaspour/gopt
/**
 * 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;
   } 
}
예제 #14
0
파일: gopt.c 프로젝트: abbaspour/gopt
/**
 * 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;
}
예제 #15
0
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;
}
예제 #18
0
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;
}
예제 #19
0
 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];
 }
예제 #20
0
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;
}
예제 #21
0
파일: fs.c 프로젝트: vonwenm/pbft
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; 
}
예제 #22
0
파일: fs.c 프로젝트: vonwenm/pbft
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; 
}
예제 #23
0
파일: lnk.c 프로젝트: Sunmonds/wine
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();
    }
}
예제 #24
0
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;
}