/*- * 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; }
/*- * 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; }
/*- * 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; }
/*- * 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; }
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); }
/*- * 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; }