if (node_len != len)
return 0;
+ if (type == UBIFS_DATA_NODE && !c->always_chk_crc)
+ if (c->no_chk_data_crc)
+ return 0;
+
crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
node_crc = le32_to_cpu(ch->crc);
if (crc != node_crc)
* @bu: bulk-read parameters and results
*
* Lookup consecutive data node keys for the same inode that reside
- * consecutively in the same LEB.
+ * consecutively in the same LEB. This function returns zero in case of success
+ * and a negative error code in case of failure.
+ *
+ * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function
+ * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares
+ * maxumum possible amount of nodes for bulk-read.
*/
int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu)
{
* An enormous hole could cause bulk-read to encompass too many
* page cache pages, so limit the number here.
*/
- if (bu->blk_cnt >= UBIFS_MAX_BULK_READ)
+ if (bu->blk_cnt > UBIFS_MAX_BULK_READ)
bu->blk_cnt = UBIFS_MAX_BULK_READ;
/*
* Ensure that bulk-read covers a whole number of page cache
goto out_err;
}
- err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0);
+ err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0);
if (err) {
ubifs_err("expected node type %d", UBIFS_DATA_NODE);
goto out;
{
struct ubifs_znode *zn, *zi, *zp;
int i, keep, move, appending = 0;
- union ubifs_key *key = &zbr->key;
+ union ubifs_key *key = &zbr->key, *key1;
ubifs_assert(n >= 0 && n <= c->fanout);
zn->level = znode->level;
/* Decide where to split */
- if (znode->level == 0 && n == c->fanout &&
- key_type(c, key) == UBIFS_DATA_KEY) {
- union ubifs_key *key1;
-
- /*
- * If this is an inode which is being appended - do not split
- * it because no other zbranches can be inserted between
- * zbranches of consecutive data nodes anyway.
- */
- key1 = &znode->zbranch[n - 1].key;
- if (key_inum(c, key1) == key_inum(c, key) &&
- key_type(c, key1) == UBIFS_DATA_KEY &&
- key_block(c, key1) == key_block(c, key) - 1)
- appending = 1;
+ if (znode->level == 0 && key_type(c, key) == UBIFS_DATA_KEY) {
+ /* Try not to split consecutive data keys */
+ if (n == c->fanout) {
+ key1 = &znode->zbranch[n - 1].key;
+ if (key_inum(c, key1) == key_inum(c, key) &&
+ key_type(c, key1) == UBIFS_DATA_KEY)
+ appending = 1;
+ } else
+ goto check_split;
+ } else if (appending && n != c->fanout) {
+ /* Try not to split consecutive data keys */
+ appending = 0;
+check_split:
+ if (n >= (c->fanout + 1) / 2) {
+ key1 = &znode->zbranch[0].key;
+ if (key_inum(c, key1) == key_inum(c, key) &&
+ key_type(c, key1) == UBIFS_DATA_KEY) {
+ key1 = &znode->zbranch[n].key;
+ if (key_inum(c, key1) != key_inum(c, key) ||
+ key_type(c, key1) != UBIFS_DATA_KEY) {
+ keep = n;
+ move = c->fanout - keep;
+ zi = znode;
+ goto do_split;
+ }
+ }
+ }
}
if (appending) {
zbr->znode->parent = zn;
}
+do_split:
+
__set_bit(DIRTY_ZNODE, &zn->flags);
atomic_long_inc(&c->dirty_zn_cnt);
/* Insert new znode (produced by spitting) into the parent */
if (zp) {
- i = n;
+ if (n == 0 && zi == znode && znode->iip == 0)
+ correct_parent_keys(c, znode);
+
/* Locate insertion point */
n = znode->iip + 1;
- if (appending && n != c->fanout)
- appending = 0;
-
- if (i == 0 && zi == znode && znode->iip == 0)
- correct_parent_keys(c, znode);
/* Tail recursion */
zbr->key = zn->zbranch[0].key;
struct ubifs_dent_node *xent, *pxent = NULL;
struct qstr nm = { .name = NULL };
- dbg_tnc("ino %lu", inum);
+ dbg_tnc("ino %lu", (unsigned long)inum);
/*
* Walk all extended attribute entries and remove them together with
}
xattr_inum = le64_to_cpu(xent->inum);
- dbg_tnc("xent '%s', ino %lu", xent->name, xattr_inum);
+ dbg_tnc("xent '%s', ino %lu", xent->name,
+ (unsigned long)xattr_inum);
nm.name = xent->name;
nm.len = le16_to_cpu(xent->nlen);