/** * data_nodes_cmp - compare 2 data nodes. * @priv: UBIFS file-system description object * @a: first data node * @a: second data node * * This function compares data nodes @a and @b. Returns %1 if @a has greater * inode or block number, and %-1 otherwise. */ static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b) { ino_t inuma, inumb; struct ubifs_info *c = priv; struct ubifs_scan_node *sa, *sb; cond_resched(); if (a == b) return 0; sa = list_entry(a, struct ubifs_scan_node, list); sb = list_entry(b, struct ubifs_scan_node, list); ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY); ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY); ubifs_assert(sa->type == UBIFS_DATA_NODE); ubifs_assert(sb->type == UBIFS_DATA_NODE); inuma = key_inum(c, &sa->key); inumb = key_inum(c, &sb->key); if (inuma == inumb) { unsigned int blka = key_block(c, &sa->key); unsigned int blkb = key_block(c, &sb->key); if (blka <= blkb) return -1; } else if (inuma <= inumb) return -1; return 1; }
static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key, char *buffer) { char *p = buffer; int type = key_type(c, key); if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) { switch (type) { case UBIFS_INO_KEY: sprintf(p, "(%lu, %s)", (unsigned long)key_inum(c, key), get_key_type(type)); break; case UBIFS_DENT_KEY: case UBIFS_XENT_KEY: sprintf(p, "(%lu, %s, %#08x)", (unsigned long)key_inum(c, key), get_key_type(type), key_hash(c, key)); break; case UBIFS_DATA_KEY: sprintf(p, "(%lu, %s, %u)", (unsigned long)key_inum(c, key), get_key_type(type), key_block(c, key)); break; case UBIFS_TRUN_KEY: sprintf(p, "(%lu, %s)", (unsigned long)key_inum(c, key), get_key_type(type)); break; default: sprintf(p, "(bad key type: %#08x, %#08x)", key->u32[0], key->u32[1]); } } else sprintf(p, "bad key format %d", c->key_fmt); }
/* * nondata_nodes_cmp - compare 2 non-data nodes. * @priv: UBIFS file-system description object * @a: first node * @a: second node * * This function compares nodes @a and @b. It makes sure that inode nodes go * first and sorted by length in descending order. Directory entry nodes go * after inode nodes and are sorted in ascending hash valuer order. */ static int nondata_nodes_cmp(void *priv, struct list_head *a, struct list_head *b) { ino_t inuma, inumb; struct ubifs_info *c = priv; struct ubifs_scan_node *sa, *sb; cond_resched(); if (a == b) return 0; sa = list_entry(a, struct ubifs_scan_node, list); sb = list_entry(b, struct ubifs_scan_node, list); ubifs_assert(key_type(c, &sa->key) != UBIFS_DATA_KEY && key_type(c, &sb->key) != UBIFS_DATA_KEY); ubifs_assert(sa->type != UBIFS_DATA_NODE && sb->type != UBIFS_DATA_NODE); /* Inodes go before directory entries */ if (sa->type == UBIFS_INO_NODE) { if (sb->type == UBIFS_INO_NODE) return sb->len - sa->len; return -1; } if (sb->type == UBIFS_INO_NODE) return 1; ubifs_assert(key_type(c, &sa->key) == UBIFS_DENT_KEY || key_type(c, &sa->key) == UBIFS_XENT_KEY); ubifs_assert(key_type(c, &sb->key) == UBIFS_DENT_KEY || key_type(c, &sb->key) == UBIFS_XENT_KEY); ubifs_assert(sa->type == UBIFS_DENT_NODE || sa->type == UBIFS_XENT_NODE); ubifs_assert(sb->type == UBIFS_DENT_NODE || sb->type == UBIFS_XENT_NODE); inuma = key_inum(c, &sa->key); inumb = key_inum(c, &sb->key); if (inuma == inumb) { uint32_t hasha = key_hash(c, &sa->key); uint32_t hashb = key_hash(c, &sb->key); if (hasha <= hashb) return -1; } else if (inuma <= inumb) return -1; return 1; }