Exemplo n.º 1
0
/* help to free_map_release double indirect index sectors,
 * from the beginning
 * to db[double_level_idx][single_level_idx] (exclusive) */
static void free_map_release_double_indirect (struct indirect_block *db,
		int double_level_end_idx, int single_level_end_idx) {
	int i;
	static struct indirect_block ib;

	for (i = 0; i < double_level_end_idx; i++) {
		if (single_level_end_idx <= 0  && i == (double_level_end_idx-1)) {
			cache_read(db->sectors[i], INVALID_SECTOR_ID, &ib, 0,
					BLOCK_SECTOR_SIZE);
		} else {
			cache_read(db->sectors[i], db->sectors[i+1], &ib, 0,
					BLOCK_SECTOR_SIZE);
		}
		free_map_release_all_single_indirect(&ib);
	}

	if (single_level_end_idx > 0) {
		cache_read(db->sectors[double_level_end_idx], INVALID_SECTOR_ID,
				&ib, 0, BLOCK_SECTOR_SIZE);
	}
	for (i = 0; i < single_level_end_idx; i++) {
		free_map_release_single_indirect(&ib, single_level_end_idx);
	}

	free_map_release_single_indirect(db, (single_level_end_idx>0)?
			(double_level_end_idx+1):double_level_end_idx);
}
Exemplo n.º 2
0
/* Reads SIZE bytes from INODE into BUFFER, starting at position OFFSET.
   Returns the number of bytes actually read, which may be less
   than SIZE if an error occurs or end of file is reached. */
off_t
inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset) 
{
  uint8_t *buffer = buffer_;
  off_t bytes_read = 0;
  //uint8_t *bounce = NULL;
  //printf("@@@@@@@@@@@@ file_read start @@@@@@@@@@@\n");
  struct inode_disk *inode_d;
  inode_d = malloc(sizeof(struct inode_disk));
  while (size > 0) 
    {
      cache_read(inode->sector, inode_d, DISK_SECTOR_SIZE, 0);
      /* Disk sector to read, starting byte offset within sector. */
      int sector_idx = byte_to_sector (inode, offset);
      //printf("@@@@@@@@@ sector_idx : %d @@@@@@@@@@\n",sector_idx);
      if(sector_idx == -1) 
        break;
      int sector_ofs = offset % DISK_SECTOR_SIZE;

      /* Bytes left in inode, bytes left in sector, lesser of the two. */
      off_t inode_left = inode_length (inode) - offset;
      int sector_left = DISK_SECTOR_SIZE - sector_ofs;
      int min_left = inode_left < sector_left ? inode_left : sector_left;

      /* Number of bytes to actually copy out of this sector. */
      int chunk_size = size < min_left ? size : min_left;
      if (chunk_size <= 0)
        break;
      cache_read(sector_idx, buffer + bytes_read, chunk_size, sector_ofs);
      /*
      if (sector_ofs == 0 && chunk_size == DISK_SECTOR_SIZE) 
        {
           Read full sector directly into caller's buffer. 
          disk_read (filesys_disk, sector_idx, buffer + bytes_read); 
        }
      else 
        {
           Read sector into bounce buffer, then partially copy
             into caller's buffer. 
          
          if (bounce == NULL) 
            {
              bounce = malloc (DISK_SECTOR_SIZE);
              if (bounce == NULL)
                break;
            }
          disk_read (filesys_disk, sector_idx, bounce);
          memcpy (buffer + bytes_read, bounce + sector_ofs, chunk_size);
        }
      */
      /* Advance. */
      size -= chunk_size;
      offset += chunk_size;
      bytes_read += chunk_size;
    }
  free(inode_d);
  //free (bounce);
  //printf("@@@@@@@@@@@@ file_read finish @@@@@@@@@@@\n");
  return bytes_read;
}
Exemplo n.º 3
0
/*
byte_to_sector(inode, pos)
inode에 해당하는 파일에서 pos번째 값을 가지고 있는 정보가 실제 disk에 어느 sector에 들어있는지 확인한다
이미 pos번째에 해당하는 섹터가 할당되어있다면 테이블에서 그 섹터를 찾아서 return해주면 되고,
그렇지 않다면 allocate_sector을 호출해서 섹터를 할당해주고 다시 byte_to_sector를 실행해준다.
*/
static int
byte_to_sector(const struct inode *inode, off_t pos) 
{
  //printf("@@@@@@@@@@@@@@ byte_to_sector start pos : %d  @@@@@@@@@@@@@@@\n",pos);
  ASSERT (inode != NULL);
  struct inode_disk *inode_d = malloc(sizeof(struct inode_disk));
  int sector;
  //printf("aaaaaaaaaa\n");
  cache_read(inode->sector, inode_d, 512, 0);
  if(bytes_to_sectors(pos) > bytes_to_sectors(inode_d->length))
    sector = -1;
  else
  {
  struct sector_table *dit = malloc(sizeof(struct sector_table));
  cache_read(inode_d->doubly_indirect, dit, 512, 0);
  //printf("cccccccccccc\n");
  struct sector_table *it = malloc(sizeof(struct sector_table));
  int index = (pos / (128 * 512));
  cache_read(dit->table[index], it, 512, 0);
  //printf("dddddddddddd\n");
  sector = it->table[(pos - index * (128 * 512)) / 512];
  free(it);
  free(dit);
  }
  free(inode_d);
  return sector;
}
Exemplo n.º 4
0
static void
deallocate_sectors(struct inode_disk *data)
{
  size_t i, j;
  size_t sectors = bytes_to_sectors(data->length);

  struct sector_table *doubly_indirect_table = calloc(1, sizeof(struct sector_table));
  cache_read(data->doubly_indirect, doubly_indirect_table, 512, 0);
  
  for(i = 0; i < 128; i++)
  {
    if(sectors == 0)
      break;
    struct sector_table *indirect_table = calloc(1, sizeof(struct sector_table));
    cache_read(data->indirect, indirect_table, 512, 0);
    
    for(j = 0; j < 128; j++)
    {
      if(sectors == 0)
        break;
      free_map_release(indirect_table->table[j], 1);
      sectors--;
    }
    free_map_release(data->indirect, 1);
    free(indirect_table);

  }
  //free_map_release(data->doubly_indirect, 1);
  free(doubly_indirect_table);
}
Exemplo n.º 5
0
/* allocate_sectors
inode와 sectors를 받아서
어떤 한 파일이 sectors개수만큼 disk에서 할당받도록 해준다
두가지 경우가 있는데
아예 처음부터 새로 할당을 시작하는 경우와
원래 가지고 있던 부분에서 추가해서 할당하는 경우

*/
static bool
allocate_sectors(struct inode_disk *disk_inode, int sector , int cnt)
{ 
  /* doubly indirect */
  int i, j;
  static char zeros[512];
  if(sector == 0) return true;
  struct sector_table *doubly_indirect_table;
  doubly_indirect_table = calloc(1, sizeof(struct sector_table));

  if(cnt == 0)
  {
    if(!free_map_allocate(1, &disk_inode->doubly_indirect))
    {
      return false;
    }
  }
  cache_read(disk_inode->doubly_indirect, doubly_indirect_table, 512, 0);
    
  for(i = 0; i < 128 && sector > 0; i++)
  {
    struct sector_table *indirect_table = calloc(1, sizeof(struct sector_table));

    if(cnt == 0)
    {
      if(!free_map_allocate(1, &doubly_indirect_table->table[i]))
        return false;
    }
  
    cache_read(doubly_indirect_table->table[i], indirect_table, 512, 0);
    
    for(j = 0; j < 128 && sector > 0; j++)
    {
      if(cnt == 0)
      {
        if(free_map_allocate(1, &indirect_table->table[j]))
        {
          cache_write(indirect_table->table[j], zeros, 512, 0);
        }
        else
        {
          free(indirect_table);
          free(disk_inode);
          return false;
        }       
      }
      else
        cnt--;
      
      sector--;
    }
    cache_write(doubly_indirect_table->table[i], indirect_table, 512, 0);
    free(indirect_table);

  }
  cache_write(disk_inode->doubly_indirect, doubly_indirect_table, 512, 0);
  free(doubly_indirect_table);
  return true;
}
Exemplo n.º 6
0
/*
 * Sum the array elements, a third way.
 */
long sumC(long *a, int numrows, int numcols)
{
    int i, j;
    long sum = 0;

    for (j = 0; j < numcols; j += 2)
        for (i = 0; i < numrows; i += 2)
            sum += cache_read(cache, &a[i * numcols + j]) + cache_read(cache, &a[(i+1) * numcols + j]) +
	   	   cache_read(cache, &a[i * numcols + (j+1)])  + cache_read(cache, &a[(i+1) * numcols + (j+1)]);

    return sum;
}
Exemplo n.º 7
0
/* Returns the disk sector that contains byte offset POS within
   INODE.
   Returns -1 if INODE does not contain data for a byte at offset
   POS. */
static disk_sector_t
byte_to_sector (const struct inode *inode, off_t pos)
{
  disk_sector_t sec_no = -1;
  disk_sector_t indirect_sector;
  struct inode_disk *disk;
  off_t offset;
  off_t indirect_offset;
  off_t double_indirect_offset;
  off_t entry_count;

  ASSERT (inode != NULL);

  if (pos >= inode_length (inode))
    return -1;

  offset = pos / DISK_SECTOR_SIZE;
  disk = (struct inode_disk *) malloc (sizeof *disk);
  ASSERT (disk != NULL);
  cache_read (inode->sector, disk, 0, sizeof (struct inode_disk));

  /* Read from direct block. */
  if (offset < INODE_DIRECT_BLOCKS)
    sec_no = disk->directs[offset];
  /* Read from indirect block. */
  else if (offset < INODE_DIRECT_BLOCKS + INODE_INDIRECT_BLOCKS)
    {
      indirect_offset = offset - INODE_DIRECT_BLOCKS;
      cache_read (disk->indirect, (void *) &sec_no,
                  indirect_offset * sizeof (disk_sector_t),
                  sizeof (disk_sector_t));
    }
  /* Read from double indirect block. */
  else if (offset < (INODE_DIRECT_BLOCKS + INODE_INDIRECT_BLOCKS
                     + INODE_DOUBLE_INDIRECT_BLOCKS))
    {
      entry_count = offset - (INODE_DIRECT_BLOCKS + INODE_INDIRECT_BLOCKS);
      double_indirect_offset = entry_count / INODE_INDIRECT_BLOCKS;
      indirect_offset = entry_count % INODE_INDIRECT_BLOCKS;

      cache_read (disk->double_indirect, (void *) &indirect_sector,
                  double_indirect_offset * sizeof (disk_sector_t),
                  sizeof (disk_sector_t));

      cache_read (indirect_sector, (void *) &sec_no,
                  indirect_offset * sizeof (disk_sector_t),
                  sizeof (disk_sector_t));
    }
  free (disk);

  return sec_no;
}
Exemplo n.º 8
0
/* Extends the INODE with LENGTH bytes. */
static bool
inode_extend (struct inode *inode, off_t length)
{
  struct inode_disk *disk;
  off_t free_length;
  size_t sectors;
  disk_sector_t sector;
  size_t i;

  lock_acquire (&inode->lock);
  disk = (struct inode_disk *) malloc (sizeof *disk);

  ASSERT (disk != NULL);

  cache_read (inode->sector, disk, 0, DISK_SECTOR_SIZE);

  free_length = disk->sector_count * DISK_SECTOR_SIZE - disk->length;
  sectors = bytes_to_sectors (length - free_length);

  for (i = 0; i < sectors; i++)
    {
      if (!free_map_allocate (1, &sector)
          || !inode_append (inode, sector))
        {
          lock_release (&inode->lock);
          return false;
        }
    }
  disk->length += length;
  cache_write (inode->sector, &disk->length, INODE_OFFSET_LENGTH, 4);
  lock_release (&inode->lock);

  free (disk);
  return true;
}
Exemplo n.º 9
0
/* Reads an inode from SECTOR
   and returns a `struct inode' that contains it.
   Returns a null pointer if memory allocation fails. */
struct inode *
inode_open (block_sector_t sector)
{
  struct list_elem *e;
  struct inode *inode;

  /* Check whether this inode is already open. */
  for (e = list_begin (&open_inodes); e != list_end (&open_inodes);
       e = list_next (e))
    {
      inode = list_entry (e, struct inode, elem);
      if (inode->sector == sector)
        {
          inode_reopen (inode);
          return inode;
        }
    }

  /* Allocate memory. */
  inode = malloc (sizeof *inode);
  if (inode == NULL)
    return NULL;

  /* Initialize. */
  list_push_front (&open_inodes, &inode->elem);
  inode->sector = sector;
  inode->open_cnt = 1;
  inode->deny_write_cnt = 0;
  inode->removed = false;
  cache_read (fs_cache, inode->sector, &inode->data, 0, BLOCK_SECTOR_SIZE);
  return inode;
}
Exemplo n.º 10
0
/* Reads SIZE bytes from INODE into BUFFER, starting at position OFFSET.
   Returns the number of bytes actually read, which may be less
   than SIZE if an error occurs or end of file is reached. */
off_t
inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset)
{
  uint8_t *buffer = buffer_;
  off_t bytes_read = 0;

  while (size > 0)
    {
      /* Disk sector to read, starting byte offset within sector. */
      block_sector_t sector_idx = byte_to_sector (inode, offset);
      int sector_ofs = offset % BLOCK_SECTOR_SIZE;

      /* Bytes left in inode, bytes left in sector, lesser of the two. */
      off_t inode_left = inode_length (inode) - offset;
      int sector_left = BLOCK_SECTOR_SIZE - sector_ofs;
      int min_left = inode_left < sector_left ? inode_left : sector_left;

      /* Number of bytes to actually copy out of this sector. */
      int chunk_size = size < min_left ? size : min_left;
      if (chunk_size <= 0)
        break;

      cache_read (fs_cache, sector_idx, buffer + bytes_read,
        sector_ofs, chunk_size);

      /* Advance. */
      size -= chunk_size;
      offset += chunk_size;
      bytes_read += chunk_size;
    }

  return bytes_read;
}
Exemplo n.º 11
0
int cache_stream_fill_buffer(stream_t *s){
  int len;
  int sector_size;
  if(!s->cache_pid) return stream_fill_buffer(s);

  if(s->pos!=((cache_vars_t*)s->cache_data)->read_filepos) mp_msg(MSGT_CACHE,MSGL_ERR,"!!! read_filepos differs!!! report this bug...\n");
  sector_size = ((cache_vars_t*)s->cache_data)->sector_size;
  if (sector_size > STREAM_MAX_SECTOR_SIZE) {
    mp_msg(MSGT_CACHE, MSGL_ERR, "Sector size %i larger than maximum %i\n", sector_size, STREAM_MAX_SECTOR_SIZE);
    sector_size = STREAM_MAX_SECTOR_SIZE;
  }

  len=cache_read(s->cache_data,s->buffer, sector_size);
  //printf("cache_stream_fill_buffer->read -> %d\n",len);

  if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; }
  s->eof=0;
  s->buf_pos=0;
  s->buf_len=len;
  s->pos+=len;
//  printf("[%d]",len);fflush(stdout);
  if (s->capture_file)
    stream_capture_do(s);
  return len;

}
Exemplo n.º 12
0
/* Returns whether INODE is directory or not. */
bool
inode_is_dir (const struct inode *inode)
{
  bool is_dir;
  cache_read (inode->sector, &is_dir, INODE_OFFSET_IS_DIR, sizeof (bool));

  return is_dir;
}
Exemplo n.º 13
0
disk_sector_t
inode_get_parent (const struct inode *inode)
{
  disk_sector_t parent;
  cache_read (inode->sector, &parent, INODE_OFFSET_PARENT,
              sizeof (disk_sector_t));
  return parent;
}
Exemplo n.º 14
0
/* Returns the length, in bytes, of INODE's data. */
off_t
inode_length (const struct inode *inode)
{
  off_t length;

  cache_read (inode->sector, (void *) &length, INODE_OFFSET_LENGTH,
              sizeof (off_t));
  return length;
}
Exemplo n.º 15
0
/* Returns INODE's type. */
enum file_t
inode_get_filetype(const struct inode *inode)
{
	/* fetch file type from disk */
	enum file_t filetype = FILE;
	cache_read(inode->sector, &filetype, INODE_OFFSET_TYPE, sizeof(enum file_t));

	return filetype;
}
Exemplo n.º 16
0
/* Returns the length, in bytes, of INODE's data. */
off_t
inode_length (const struct inode *inode)
{
	off_t file_length;

	/* read cache and save file length to file_length */
	cache_read (inode->sector, (void *)(&file_length), INODE_OFFSET_LENGTH, sizeof(off_t));

	return file_length;
}
Exemplo n.º 17
0
/* Returns the length, in bytes, of INODE's data. */
off_t
inode_length (const struct inode *inode)
{
  struct inode_disk *inode_d;
  inode_d = malloc(sizeof(struct inode_disk));
  cache_read(inode->sector, inode_d, DISK_SECTOR_SIZE, 0); 
  int len = inode_d->length;
  free(inode_d);
  return len;
}
Exemplo n.º 18
0
/* Returns the disk sector that contains byte offset POS within
   INODE.
   Returns -1 if INODE does not contain data for a byte at offset
   POS. */
static disk_sector_t
byte_to_sector (const struct inode *inode, off_t pos) 
{
  ASSERT (inode != NULL);
  if (pos < inode->data.length){
    pos /= DISK_SECTOR_SIZE;
    struct inode_disk *disk_inode = calloc(1, sizeof(struct inode_disk));
    if(disk_inode == NULL) return -1;
    disk_sector_t sector;
    cache_read(inode->data.inode_index[pos/(DIRECT_INODE*SINGLE_INDIRECT_INODE)], disk_inode, 0, DISK_SECTOR_SIZE);
    pos%=DIRECT_INODE*SINGLE_INDIRECT_INODE;
    sector = disk_inode->inode_index[pos/SINGLE_INDIRECT_INODE];
    cache_read(sector, disk_inode, 0, DISK_SECTOR_SIZE);
    sector = disk_inode->inode_index[pos%SINGLE_INDIRECT_INODE];
    free(disk_inode);
    return sector;
  }
  else
    return -1;
}
Exemplo n.º 19
0
/*
 * Sum the array elements, another way.
 */
long sumB(long *a, int numrows, int numcols)
{
    int i, j;
    long sum = 0;

    for (j = 0; j < numcols; j ++)
        for (i = 0; i < numrows; i++)
	    sum += cache_read(cache, &a[i * numcols + j]);

    return sum;
}
Exemplo n.º 20
0
/* Returns the block device sector that contains byte offset POS
   within INODE.
   Returns -1 if INODE does not contain data for a byte at offset
   POS. */
static block_sector_t
byte_to_sector (const struct inode *inode, off_t pos)
{
  ASSERT (inode != NULL);
  if (pos < inode->data.length)
  {
    off_t block_index = pos / BLOCK_SECTOR_SIZE;
    if (block_index < indirect_begin)
    {
      ASSERT (inode->data.direct[block_index] != 0);
      return inode->data.direct[block_index];
    }
    {
      off_t id1, id0;
      block_sector_t d1, d0;
      if (block_index >= dbl_indirect_begin)
      {
        off_t id2 = (block_index - dbl_indirect_begin) / DIRECT_ENTRY_CNT / DIRECT_ENTRY_CNT;
        id1 = (block_index - dbl_indirect_begin) / DIRECT_ENTRY_CNT % DIRECT_ENTRY_CNT;
        id0 = (block_index - dbl_indirect_begin) % DIRECT_ENTRY_CNT;
        block_sector_t d2;
        d2 = inode->data.dbl_indirect[id2];
        ASSERT (d2 != 0);
        cache_read (fs_cache, d2, &d1, sizeof(block_sector_t) * id1, sizeof(block_sector_t));
        ASSERT (d1 != 0);
      }
      else
      {
        id1 = (block_index - indirect_begin) / DIRECT_ENTRY_CNT;
        id0 = (block_index - indirect_begin) % DIRECT_ENTRY_CNT;
        d1 = inode->data.indirect[id1];
        ASSERT (d1 != 0);
      }
      cache_read (fs_cache, d1, &d0, sizeof(block_sector_t) * id0, sizeof(block_sector_t));
      ASSERT (d0 != 0);
      return d0;
    }
  }
  else
    return -1;
}
Exemplo n.º 21
0
/* Writes SIZE bytes from BUFFER into INODE, starting at OFFSET.
   Returns the number of bytes actually written, which may be
   less than SIZE if end of file is reached or an error occurs.
   (Normally a write at end of file would extend the inode, but
   growth is not yet implemented.) */
off_t
inode_write_at (struct inode *inode, const void *buffer_, off_t size_,
                off_t offset_)
{
  const uint8_t *buffer = buffer_;
  int bytes_written = 0;
  int size=(int) size_;
  int offset=(int)offset_;

  if (inode->deny_write_cnt)
    return 0;

  struct inode_disk id;
  lock_acquire(&inode->inode_lock);
  cache_read(inode->sector, INVALID_SECTOR_ID, &id, 0, BLOCK_SECTOR_SIZE);
  int phy_length = (int)id.length;
  if (offset + size > phy_length) {
	  if(!zero_padding(inode, &id, phy_length, offset+size)){
		  lock_release(&inode->inode_lock);
		  return 0;
	  }
  }


  while (size > 0)
    {
      /* Sector to write, starting byte offset within sector. */
      block_sector_t sector_idx = byte_to_sector_no_check (inode, offset);
      int sector_ofs = offset % BLOCK_SECTOR_SIZE;

      /* Bytes left in inode, bytes left in sector, lesser of the two. */
      off_t inode_left = id.length - offset;
      int sector_left = BLOCK_SECTOR_SIZE - sector_ofs;
      int min_left = inode_left < sector_left ? inode_left : sector_left;

      /* Number of bytes to actually write into this sector. */
      int chunk_size = size < min_left ? size : min_left;
      if (chunk_size <= 0)
        break;

      cache_write(sector_idx, (void *)(buffer+bytes_written),
    		  sector_ofs, chunk_size);

      /* Advance. */
      size -= chunk_size;
      offset += chunk_size;
      bytes_written += chunk_size;
    }

  inode->readable_length=id.length;
  lock_release(&inode->inode_lock);
  return bytes_written;
}
Exemplo n.º 22
0
void run_example() {
	std::cout << "Running cache read " << ITERATIONS_NUMBER << " times" << std::endl;

	react::stream_aggregator_t aggregator(std::cout);

	for (int i = 0; i < ITERATIONS_NUMBER; ++i) {
		react_activate(&aggregator);

		std::string data = cache_read();

		react_deactivate();
	}
}
Exemplo n.º 23
0
/* Returns the block device sector that contains byte offset POS
   within INODE without checking pos less than inode's readable_length
   Returns -1 if INODE does not contain data for a byte at offset
   POS. */
static block_sector_t
byte_to_sector_no_check (const struct inode *inode, off_t pos)
{
	ASSERT (inode != NULL);

	/* sector_pos starts from 0 */
	off_t sector_pos = pos/BLOCK_SECTOR_SIZE;

	struct inode_disk id;
	cache_read(inode->sector, INVALID_SECTOR_ID,
			&id, 0, BLOCK_SECTOR_SIZE);

	/*sector_pos in the range of direct index*/
	if (sector_pos < DIRECT_INDEX_NUM) {
		return id.direct_idx[sector_pos];
	}

	/*sector_pos in the range of single indirect index*/
	if (sector_pos < DIRECT_INDEX_NUM+INDEX_PER_SECTOR) {
		static struct indirect_block ib;
		cache_read(id.single_idx, INVALID_SECTOR_ID, &ib, 0,
				BLOCK_SECTOR_SIZE);
		return ib.sectors[sector_pos-DIRECT_INDEX_NUM];
	}

	/*sector_pos in the range of double indirect index*/
	off_t double_level_idx = (sector_pos-
			(DIRECT_INDEX_NUM+INDEX_PER_SECTOR)) / INDEX_PER_SECTOR;
	off_t single_level_idx = (sector_pos-
			(DIRECT_INDEX_NUM+INDEX_PER_SECTOR)) % INDEX_PER_SECTOR;
	static struct indirect_block db;
	cache_read(id.double_idx, INVALID_SECTOR_ID, &db, 0, BLOCK_SECTOR_SIZE);
	static struct indirect_block ib;
	cache_read(db.sectors[double_level_idx],
			INVALID_SECTOR_ID, &ib, 0, BLOCK_SECTOR_SIZE);
	return ib.sectors[single_level_idx];
}
Exemplo n.º 24
0
/* extend inode at sector sector with length bytes */
static bool
inode_extend (struct inode* inode, off_t ext_length)
{
	if(INODE_DEBUG || FILE_DEBUG) printf("INODE: extending inode %u by %i bytes\n", inode->sector, ext_length);

	lock_acquire(&inode->lock);

	bool success = true;

	/* local copy of disk inode */
	struct inode_disk* id = malloc(sizeof(struct inode_disk));
	cache_read(inode->sector, id, 0, sizeof(struct inode_disk));

	/* free space left in bytes */
	off_t free_space = id->sector_count * BLOCK_SECTOR_SIZE - id->length;

	/* needed sectors */
	size_t sectors = bytes_to_sectors (ext_length - free_space);

	/* add sector to inode */
	unsigned i;
	block_sector_t block_sector;
	for(i = 0; i < sectors; i++)
	{
		/* allocate one vector at a time */
		if(free_map_allocate (1, &block_sector))
		{
			/* add new block to inode */
			inode_add_block(inode, block_sector);
		}
		/* not enough space on disk - abort */
		else
		{
			printf("INODE: that should not happen.\n");
			success = false;
			break;
		}
	}
	
	/* increment length and write back */
	id->length += ext_length;
	cache_write(inode->sector, (void *) &id->length, INODE_OFFSET_LENGTH, 4);

	lock_release(&inode->lock);
	
	if(INODE_DEBUG || FILE_DEBUG) printf("INODE: completetd extending inode %u by %i bytes : %u\n", inode->sector, ext_length, (unsigned)success);

	return success;
}
Exemplo n.º 25
0
/*! Returns the block device sector that contains byte offset POS
    within INODE.
    Returns -1 if INODE does not contain data for a byte at offset
    POS. */
static block_sector_t byte_to_sector(const struct inode *inode, off_t pos) {
    struct i_inode_disk *index = NULL;
    
    ASSERT(inode != NULL);
    if (pos < inode->data.length) {
        int sector = pos / BLOCK_SECTOR_SIZE;
        if (sector < 124) return inode->data.block_list[sector]; // direct
        if (sector < 252) {
            // indirect block
            index = calloc(1, sizeof *index);
            
            index = cache_read(inode, inode->data.block_list[124]);
            block_sector_t ret = index->block_list[sector - 124];
            
            free(index);
            return ret;
        }
        if (sector < 16636) { // UGLY HARDCODED NUMBERS HERE AND THROUGHOUT
            // doubly indirect block
            index = calloc(1, sizeof *index);
            
            index = cache_read(inode, inode->data.block_list[125]);
            block_sector_t next = index->block_list[(sector - 252) / 128];
            
            index = cache_read(inode, next);
            block_sector_t ret = index->block_list[(sector - 252) % 128];
            
            free(index);
            return ret;
        }
        return -1;
    }
    else {
        return -1;
    }
}
Exemplo n.º 26
0
void inode_delete(disk_sector_t sector){
  struct inode_disk *disk_inode;
  disk_inode = calloc (1, sizeof *disk_inode);
  if(disk_inode != NULL){
    cache_read(sector, disk_inode, 0, DISK_SECTOR_SIZE);
    if(disk_inode->level == 0)
      free_map_release(disk_inode->inode_index, disk_inode->count);
    else{
      size_t i;
      for(i=0;i<disk_inode->count;i++)
        inode_delete(disk_inode->inode_index[i]);
    }
    free(disk_inode);
  }
  free_map_release(&sector, 1);
}
Exemplo n.º 27
0
/* Reads SIZE bytes from INODE into BUFFER, starting at position OFFSET.
   Returns the number of bytes actually read, which may be less
   than SIZE if an error occurs or end of file is reached. */
off_t
inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset) 
{
	if(INODE_DEBUG) printf("INODE: reading inode %u @ offset %i into buffer %x. Size: %i bytes\n", inode->sector, offset, (unsigned) buffer_, size);

	void *buffer = buffer_;
	off_t bytes_read = 0;

	while (size > 0)
	{
		/* Disk sector to read, starting byte offset within sector. */
		block_sector_t sector_idx = byte_to_sector (inode, offset);
	
		int sector_ofs = offset % BLOCK_SECTOR_SIZE;

		/* legal sector found */
		if(sector_idx != (block_sector_t) -1)
		{
			/* Bytes left in inode, bytes left in sector, lesser of the two. */
			off_t inode_left = inode_length (inode) - offset;
			int sector_left = BLOCK_SECTOR_SIZE - sector_ofs;
			int min_left = inode_left < sector_left ? inode_left : sector_left;

			/* Number of bytes to actually copy out of this sector. */
			int chunk_size = size < min_left ? size : min_left;
			if (chunk_size <= 0)
				break;

			/* read chunk from cache */
			cache_read(sector_idx, buffer + bytes_read, sector_ofs, chunk_size);

			/* Advance. */
			size -= chunk_size;
			offset += chunk_size;
			bytes_read += chunk_size;
		}
		else
		{
			/* EOF reached. */
			if(INODE_DEBUG) printf("INODE: end of file\n");
			break;
		}
	}

	if(INODE_DEBUG) printf("INODE: %i bytes read\n", bytes_read);
  return bytes_read;
}
Exemplo n.º 28
0
static int cache_fill_buffer(struct stream *cache, char *buffer, int max_len)
{
    struct priv *s = cache->priv;
    assert(s->cache_thread_running);

    pthread_mutex_lock(&s->mutex);

    if (cache->pos != s->read_filepos)
        mp_msg(MSGT_CACHE, MSGL_ERR,
               "!!! read_filepos differs !!! report this bug...\n");

    int t = cache_read(s, buffer, max_len);
    // wakeup the cache thread, possibly make it read more data ahead
    pthread_cond_signal(&s->wakeup);
    pthread_mutex_unlock(&s->mutex);
    return t;
}
Exemplo n.º 29
0
/* Reads an inode from SECTOR
   and returns a `struct inode' that contains it.
   Returns a null pointer if memory allocation fails. */
struct inode *
inode_open (block_sector_t sector)
{
  struct list_elem *e;
  struct inode *inode;

  /* Check whether this inode is already open. */
  lock_acquire(&open_inodes_lock);
  for (e = list_begin (&open_inodes); e != list_end (&open_inodes);
       e = list_next (e)) 
    {
      inode = list_entry (e, struct inode, elem);
      if (inode->sector == sector) 
        {
          inode_reopen (inode);
          lock_release(&open_inodes_lock);
          return inode; 
        }
    }
  lock_release(&open_inodes_lock);
  /* Allocate memory. */
  inode = malloc (sizeof *inode);
  if (inode == NULL)
    return NULL;

  /* Initialize. */
  ASSERT(!lock_held_by_current_thread (&open_inodes_lock));
  lock_acquire(&open_inodes_lock);
  list_push_front (&open_inodes, &inode->elem);
  lock_release(&open_inodes_lock);
  inode->sector = sector;
  inode->open_cnt = 1;
  inode->deny_write_cnt = 0;
  inode->removed = false;
  lock_init(&inode->dir_lock);
  lock_init(&inode->inode_lock);
  /* retrieve inode_disk from sector */
  struct inode_disk id;
  cache_read(inode->sector, INVALID_SECTOR_ID, &id, 0, BLOCK_SECTOR_SIZE);
  inode->readable_length = id.length;
  inode->is_dir = id.is_dir;
  return inode;
}
Exemplo n.º 30
0
static void free_inode_blocks_rec (int level, block_sector_t b)
{
  if (b == 0)
    return;

  if (level > 0)
  {
    size_t i;
    size_t unit = sizeof(block_sector_t);
    for (i = 0; i < DIRECT_ENTRY_CNT; i++)
    {
      block_sector_t nb;
      cache_read (fs_cache, b, &nb, unit * i, unit);
      free_inode_blocks_rec (level-1, nb);
    }
  }

  cache_remove (fs_cache, b, 1);
  free_map_release (b, 1);
}