Example #1
0
/*-
 *      Routine:       ifree
 *
 *      Purpose:
 *              Libera un inodo y lo añade a la lista de inodos libres.
 *              Si este inodo referencia a algún bloque de datos, también
 *              lo libera y lo añade a su lista correspondiente
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *              inode debe apuntar a un inodo.
 *      Returns:
 *              -1 on error.
 *
 */
int
ifree(int dev, superblock_t * const sb, inode_t *inode)
{
  int i, block;

  DEBUG_VERBOSE(">> ifree(inode->n = %d)\n", inode->n);

  for (i=0; i < N_DIRECT_BLOCKS; i++)
    {
      block = inode_getblk(dev, sb, inode, i);
      if (!unassigned_p(block))
        freeblk(dev, sb, block);
    }
  if (!unassigned_p(inode->single_indirect_blocks))
    {
        for (i=N_DIRECT_BLOCKS;
             i < N_DIRECT_BLOCKS+N_SINGLE_INDIRECT_BLOCKS;
             i++)
          {
            block = inode_getblk(dev, sb, inode, i);
            if (!unassigned_p(block))
              freeblk(dev, sb, block);
          }
        freeblk(dev, sb, inode->single_indirect_blocks);
    }

  if (sb->free_inode_index == FREE_INODE_LIST_SIZE)
    {
      DEBUG_VERBOSE(">> ialloc >> Lista de inodos libres llena...");

      /* Si la lista está vacía y el nuevo inodo libre es anterior al
         primero de esta lista, insertarlo (reemplazando) en dicha posición. */
      if (sb->free_inode_list[0] > inode->n)
        {
          DEBUG_VERBOSE(" reemplazando primera entrada.");
          sb->free_inode_list[0] = inode->n;
        }
    }
  else
    {
      /* Si no, añadirlo a ella e incrementar el índice. */
      sb->free_inode_list[sb->free_inode_index] = inode->n;
      sb->free_inode_index++;
    }

  inode->type = I_FREE;
  iput(dev, sb, inode);

  /* Incrementar contador de inodos libres. */
  sb->free_inodes++;

  return 0;
}
Example #2
0
struct buffer_head * sysv_getblk(struct inode * inode, unsigned int block,
                                 int create, char * *start)
{
    struct super_block * sb = inode->i_sb;
    struct buffer_head * bh;

    if (block < 10)
        return inode_getblk(inode,block,create,start);
    block -= 10;
    if (block < sb->sv_ind_per_block) {
        bh = inode_getblk(inode,10,create,start);
        return block_getblk(inode, bh, block, create, start);
    }
    block -= sb->sv_ind_per_block;
    if (block < sb->sv_ind_per_block_2) {
        bh = inode_getblk(inode,11,create,start);
        bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_bits, create, start);
        return block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create, start);
    }
Example #3
0
struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
{
	struct buffer_head * bh;

	if (block<0) {
		printk("minix_getblk: block<0");
		return NULL;
	}
	if (block >= 7+512+512*512) {
		printk("minix_getblk: block>big");
		return NULL;
	}
	if (block < 7)
		return inode_getblk(inode,block,create);
	block -= 7;
	if (block < 512) {
		bh = inode_getblk(inode,7,create);
		return block_getblk(bh,block,create);
	}
	block -= 512;
	bh = inode_getblk(inode,8,create);
	bh = block_getblk(bh,block>>9,create);
	return block_getblk(bh,block & 511,create);
}
Example #4
0
/*-
 *      Routine:       inode_truncate
 *
 *      Purpose:
 *              Trunca un archivo a partir de su inodo.
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *              inode debe apuntar a un inodo válido.
 *              size debe ser no-negativo.
 *      Returns:
 *              -1 on error.
 *
 */
int
inode_truncate(int dev, superblock_t * const sb, inode_t *inode, int size)
{
  int blk, last_blk;
  int absolute_blk;

  if (size < 0)
    return -1;

  /* Para truncar al alza, tan sólo hay que tocar el campo size del inodo. */
  if (size >= inode->size)
    {
      if (size > inode->size)
        inode->size = size;

      return 0;
    }

  /* Para truncar de toda la vida, hay que liberar los bloques que quedan fuera
     tras meter las tijeras. */

  /* Calcular último bloque interno que hay que liberar. */
  last_blk = (inode->size-1) / sizeof(struct block);
  /* Calcular primer bloque interno que hay que liberar. */
  blk = size  ?  (size-1)/sizeof(struct block)  :  0;
  while (blk <= last_blk)
    {
      absolute_blk = inode_getblk(dev, sb, inode, blk);
      if (absolute_blk == -1)
        return -1;

      if (!unassigned_p(absolute_blk))
        {
          if (freeblk(dev, sb, absolute_blk) < 0)
            return -1;

          inode_freeblk(dev, sb, inode, blk);
        }

      blk++;
    }

  inode->size = size;

  return 0;
}