예제 #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;
}
예제 #2
0
/*-
 *      Routine:       iput
 *
 *      Purpose:
 *              Guarda en disco un inodo.
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *              inode debe apuntar a un inode_t válido.
 *      Returns:
 *              0 on success.
 *              -1 on error.
 *
 */
int
iput(int dev, const superblock_t * const sb, inode_t * inode)
{
  /* int i; */

  if (!inode)
    return -1;

  DEBUG_VERBOSE(">> iput()\n");
  
  lseek(dev, sb->inode_zone_base + inode->n * sizeof(struct inode), SEEK_SET);

  if (write(dev, inode, sizeof(struct inode)) < sizeof(struct inode))
    return -1;

  /* DEBUG_VERBOSE(">>>> n = %d", inode->n); */
  /* DEBUG_VERBOSE(">>>> type = %x", inode->type); */
  /* DEBUG_VERBOSE(">>>> size = %d", inode->size); */
  /* DEBUG_VERBOSE(">>>> direct_blocks = {"); */
  /* for (i=0; i<10; i++) */
  /*   DEBUG_VERBOSE("\t%d", inode->direct_blocks[i]); */
  /* DEBUG_VERBOSE("}"); */

  return 0;
}
예제 #3
0
/*-
 *      Routine:       iget
 *
 *      Purpose:
 *              Obtiene el inodo correspondiente a un número de inodo.
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *              n debe ser un numero de inodo válido.
 *      Returns:
 *              Un puntero al inodo ya bloqueado.
 *              NULL on error.
 *
 */
inode_t *
iget(int dev, const superblock_t * const sb, int n)
{
  /* int i; */
  inode_t *inode;

  DEBUG_VERBOSE(">> iget(%d)", n);

  if (n < 0 || n >= sb->inode_count)
    return NULL;
  
  lseek(dev, sb->inode_zone_base + n * sizeof(struct inode), SEEK_SET);

  inode = malloc(sizeof(struct inode));
  if (!inode)
    return NULL;

  if (read(dev, inode, sizeof(struct inode)) < sizeof(struct inode))
    {
      free(inode);
      return NULL;
    }

  /* DEBUG_VERBOSE(">>>> n = %d", inode->n); */
  /* DEBUG_VERBOSE(">>>> type = %x", inode->type); */
  /* DEBUG_VERBOSE(">>>> size = %d", inode->size); */
  /* DEBUG_VERBOSE(">>>> direct_blocks = {"); */
  /* for (i=0; i<10; i++) */
  /*   DEBUG_VERBOSE("\t%d", inode->direct_blocks[i]); */
  /* DEBUG_VERBOSE("}\n"); */

  return inode;
}
예제 #4
0
/*-
 *      Routine:       namei
 *
 *      Purpose:
 *              Obtiene el inodo correspondiente a un path.
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *              El path debe ser válido.
 *      Returns:
 *              Un puntero al inodo ya bloqueado.
 *              NULL on error.
 *
 */
inode_t *
namei(int dev, superblock_t * const sb, char * path)
{
  char *p;
  inode_t *inode;
  dir_entry_t *de;

  DEBUG_VERBOSE(">> namei(%s)", path);

  /* En FUSE, todas las rutas son absolutas, así que comenzamos cogiendo
     el inodo de / y actualizando path para que apunte al primer caracter
     de la ruta relativo a /. */
  inode = iget(dev, sb, sb->first_inode);

  /* Caso especial de haber pedido el /. */
  if (strcmp(path, "/") == 0)
    return inode;

  path++;
  p = strchr(path, '/');
  while (p)
    {
      /* Marcar fin de string en path. */
      *p = 0;

      /* Sacar dirent del subdirectorio objetivo. */
      de = get_dir_entry_by_name(dev, sb, inode, path);
      free(inode);
      if (!de || de->inode < 0)
        {
          free(de);
          return NULL;
        }
      /* Abrir inodo del subdirectorio objetivo. */
      inode = iget(dev, sb, de->inode);
      free(de);

      path = p+1;
      p = strchr(path, '/');
    }

  /* Sacar dirent del subdirectorio objetivo. */
  de = get_dir_entry_by_name(dev, sb, inode, path);
  free(inode);
  if (!de || de->inode < 0)
    {
      free(de);
      return NULL;
    }

  /* Abrir inodo del subdirectorio objetivo. */
  inode = iget(dev, sb, de->inode);
  free(de);

  return inode;
}
예제 #5
0
bool
reuse_time_t::process_memref(const memref_t &memref)
{
    if (DEBUG_VERBOSE(3)) {
        std::cerr << " ::" << memref.data.pid << "." << memref.data.tid
                  << ":: " << trace_type_names[memref.data.type];
        if (memref.data.type != TRACE_TYPE_THREAD_EXIT) {
            std::cerr << " @ ";
            if (!type_is_instr(memref.data.type))
                std::cerr << (void *)memref.data.pc << " ";
            std::cerr << (void *)memref.data.addr << " x" << memref.data.size;
        }
        std::cerr << std::endl;
    }

    // Only care about data for now.
    if (type_is_instr(memref.instr.type)) {
        total_instructions++;
        return true;
    }

    // Ignore thread events and other tracing metadata.
    if (memref.data.type != TRACE_TYPE_READ &&
        memref.data.type != TRACE_TYPE_WRITE &&
        !type_is_prefetch(memref.data.type)) {
        return true;
    }

    time_stamp++;
    addr_t line = memref.data.addr >> line_size_bits;
    if (time_map.count(line) > 0) {
        int_least64_t reuse_time = time_stamp - time_map[line];
        if (DEBUG_VERBOSE(3)) {
            std::cerr << "Reuse " << reuse_time << std::endl;
        }
        reuse_time_histogram[reuse_time]++;
    }
    time_map[line] = time_stamp;
    return true;
}
DatagramSocket::DatagramSocket()
{
   if ( c_udp_proto_nbr <= 0 ) {
      // Not initialized, probably windows.
      c_udp_proto_nbr = getprotobyname("udp")->p_proto;

      // It didn't work here either.
      if ( c_udp_proto_nbr <= 0 ) {
         PANIC("Couldn't get protocol entry for protocol 'udp'", "");
      }
   }
   
   if ( ( fd = socket(AF_INET, SOCK_DGRAM, c_udp_proto_nbr) ) < 0 ) {
      mc2log << error
             <<"DatagramSocket::DatagramSocket() error creating socket"
             << endl << "FD " << fd << endl << " proto_ent->p_proto "
             << c_udp_proto_nbr << endl;
      PANIC("__socket: ", strerror(errno));
   }
   
   DEBUG_VERBOSE(mc2dbg << "Socket created, filedescriptor: " << fd << endl);
}
예제 #7
0
/*-
 *      Routine:       ialloc
 *
 *      Purpose:
 *              Asigna un nuevo inodo de la lista de inodos libres.
 *      Conditions:
 *              dev debe corresponder a un gnordofs válido.
 *              sb debe apuntar a un superbloque válido.
 *      Returns:
 *              Un puntero al inodo ya bloqueado.
 *              NULL on error.
 *
 */
inode_t *
ialloc(int dev, superblock_t * const sb)
{
  inode_t *inode;
  unsigned long in, i, j, *aux_list;

  DEBUG_VERBOSE(">> ialloc\n");

  if (!sb->free_inodes)
    {
      DEBUG_VERBOSE(">>>> NO QUEDAN INODOS LIBRES!\n");
      return NULL;
    }

  /* Si la lista está vacía, recorrer la zona de inodos en busca de inodos libres. */
  if (sb->free_inode_index == 0)
    {
      DEBUG_VERBOSE(">> ialloc >> Lista de inodos libres vacía. Rellenando...\n");

      aux_list = malloc(FREE_INODE_LIST_SIZE * sizeof(unsigned long));

      in = sb->free_inode_list[0];
      /* Comienza por el último que se asignó, que probablemente haya más después de él. */
      for (j = 0, i = in;
           j < FREE_INODE_LIST_SIZE && i < sb->inode_count;
           i++)
        {
          inode = iget(dev, sb, i);
          if (!inode)
            {
              DEBUG_VERBOSE(">> ialloc >> ERROR al rellenar la lista de inodos libres!\n");
              return NULL;
            }
          
          if (inode->type == I_FREE)
            {
              aux_list[j++] = i;
            }

          free(inode);
        }

      /* Si no se llenó con los que había del final, recorrer la lista hasta el último
         que se asignó. */
      for (i=0;
           j < FREE_INODE_LIST_SIZE && i < in;
           i++)
        {
          inode = iget(dev, sb, i);
          if (!inode)
            {
              DEBUG_VERBOSE(">> ialloc >> ERROR al rellenar la lista de inodos libres!\n");
              return NULL;
            }
          
          if (inode->type = I_FREE)
            {
              aux_list[j++] = i;
            }

          free(inode);
        }

      /* Sería un detalle que free_inode_index indicase cuántos inodos hay anotados en
         la dichosa lista. (¡¬¬) */
      sb->free_inode_index = j;
      /* Anotar en el superblock la lista en orden inverso. */
      for (i=0, j--; i <= j; i++)
        sb->free_inode_list[j-i] = aux_list[i];

      free(aux_list);

      DEBUG_VERBOSE(">> ialloc >> Lista de inodos libres con %d nuevas entradas...\n",
            sb->free_inode_index);
    }

  /* Obtener primer inodo libre de la lista de idem. */
  sb->free_inode_index--;
  in = sb->free_inode_list[sb->free_inode_index];

  inode = iget(dev, sb, in);

  if (inode)
    {
      /* Decrementar contador de inodos libres. */
      sb->free_inodes--;

      /* Marcar como no asignados cada uno de los elementos de la lista de bloques. */
      for (i=0; i<10; i++)
        inode->direct_blocks[i] = BLK_UNASSIGNED;
      inode->single_indirect_blocks = BLK_UNASSIGNED;
    }

  DEBUG_VERBOSE(">> ialloc >> inode = %d\n", inode->n);
  DEBUG_VERBOSE(">> ialloc >> sb->free_inode_index = %d\n", sb->free_inode_index);
  DEBUG_VERBOSE(">> ialloc >> sb->free_inodes = %d\n", sb->free_inodes);

  return inode;
}