static unsigned int remove_extent(struct results_tree *res, struct extent *extent) { struct dupe_extents *p = extent->e_parent; struct rb_node *n; unsigned int result; again: p->de_score -= p->de_len; p->de_num_dupes--; result = p->de_num_dupes; list_del_init(&extent->e_list); list_del_init(&extent->e_file_extents); rb_erase(&extent->e_node, &p->de_extents_root); free_extent(extent); if (p->de_num_dupes == 1) { /* It doesn't make sense to have one extent in a dup * list. */ abort_on(RB_EMPTY_ROOT(&p->de_extents_root));/* logic error */ n = rb_first(&p->de_extents_root); extent = rb_entry(n, struct extent, e_node); goto again; }
struct inode* alloc_inode(void) { /* * Return a free inode from the pool. */ static int i; int end = i; struct inode *i_node; i = (i + 1) % NR_INODE_RECORDS; do { i_node = &inodes[i]; if (i_node->i_count == 0) { free_extent(i_node->extent); memset(i_node, 0, sizeof(*i_node)); i_node->i_count = 1; return i_node; } i = (i + 1) % NR_INODE_RECORDS; } while(i != end); panic("No free inodes in cache"); }
static void insert_extent_list_free(struct dupe_extents *dext, struct extent **e) { if (insert_extent_list(dext, *e)) { free_extent(*e); *e = NULL; } }
void free_extent(struct dir_extent *e) { if (e == NULL) return; if (e->in_use == 0) panic("Trying to free unused extent"); free_extent(e->next); e->in_use = 0; }
struct inode* get_inode(ino_t i) { struct inode *i_node; struct dir_extent *extent; if (i == 0) return NULL; /* Try to get inode from cache. */ i_node = find_inode(i); if (i_node != NULL) { dup_inode(i_node); return i_node; } /* * Inode wasn't in cache, try to load it. * FIXME: a fake extent of one logical block is created for * read_inode(). Reading a inode this way could be problematic if * additional extents are stored behind the block boundary. */ i_node = alloc_inode(); extent = alloc_extent(); extent->location = i / v_pri.logical_block_size_l; extent->length = 1; if (read_inode(i_node, extent, i % v_pri.logical_block_size_l, NULL) != OK) { free_extent(extent); put_inode(i_node); return NULL; } free_extent(extent); return i_node; }