Пример #1
0
ino_t
minixfs_new_inode (void)
{
  char *bh = bptr (I_MAP_BOFFS);
  ino_t inum;
  unsigned long bits = sblock->s_ninodes;

  spin_lock (&global_lock);

 repeat:
  inum = find_first_zero_bit ((unsigned long *) bh, bits);
  if (inum < bits)
    {
      assert (sblock_info->s_free_inodes_count > 0);
      minixfs_debug ("eligible bit found at position %Lu", inum);

      if (set_bit (inum, bh))
	{
	  /* shouldn't happen */
	  minixfs_warning ("bit already set for inode %Lu", inum);
	  goto repeat;
	}
      record_global_poke (bh);
    }
  else
    {
      assert (sblock_info->s_free_inodes_count == 0);
      minixfs_debug ("no more free inodes");
      inum = 0;
      goto sync_out;
    }

  if (inum < MINIXFS_FIRST_INO)
    {
      minixfs_error ("reserved inode");
      inum = 0;
      goto sync_out;
    }

  sblock_info->s_free_inodes_count--;

 sync_out:
  spin_unlock (&global_lock);
  alloc_sync (0);

  return inum;
}
Пример #2
0
static inline void
_free_zone_run_flush (struct free_zone_run *fzr, unsigned long count)
{
  fzr->node->dn_stat.st_blocks -= count <<
    (log2_stat_blocks_per_fs_block + log2_fs_blocks_per_zone);
  fzr->node->dn_stat_dirty = 1;

  minixfs_debug ("flushing freed zones %u-%u (node %Ld)", fzr->first_zone,
		 (zone_t) (fzr->first_zone + count), fzr->node->cache_id);
  minixfs_free_zones (fzr->first_zone, count);
}
Пример #3
0
/* Free any direct zones starting with zone at node index END.  */
static void
trunc_direct_V1 (struct node *node, zone_t end,
 struct free_zone_run *fzr)
{
  uint16_t *zones =
    (uint16_t *) (node->dn->info.i_zone_V1);

  minixfs_debug ("truncating direct zones starting at node index %u "
 "(node %Ld)", end, node->cache_id);

  while (end < MINIXFS_NDIR_ZONES)
    free_zone_run_free_ptr (fzr, (zone_t *) (zones + (int) end++));
}
Пример #4
0
/* Free node NP; the on disk copy has already been synced with
   diskfs_node_update (where NP->dn_stat.st_mode was 0).  Its
   mode used to be OLD_MODE.  */
void
diskfs_free_node (struct node *np, mode_t old_mode)
{
  char *bh;
  ino_t inum = np->cache_id;
  block_t imap_block;

  assert (!diskfs_readonly);

  spin_lock (&global_lock);

  if (inum < MINIXFS_FIRST_INO || inum > sblock->s_ninodes)
    {
      minixfs_error ("trying to free a reserved or nonexistent inode: %Lu",
		     inum);
      spin_unlock (&global_lock);
      return;
    }

  minixfs_debug ("freeing inode %Lu", inum);

  imap_block = inum >> LOG2_BITS_PER_BLOCK;
  if (imap_block >= sblock->s_imap_blocks) 
    {
      minixfs_error ("nonexistent imap in superblock: %u", imap_block);
      spin_unlock (&global_lock);
      return;
    }
  
  bh = bptr (I_MAP_BOFFS + imap_block);
  if (! clear_bit (inum & (BITS_PER_BLOCK - 1), bh))
    minixfs_warning ("bit already cleared for inode %Lu", inum);
  else
    {
      record_global_poke (bh);
      sblock_info->s_free_inodes_count++;
    }

  spin_unlock (&global_lock);
  alloc_sync (0);
}