diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 6796c1a80e99..e3df89284079 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c @@ -239,6 +239,9 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) struct hfs_bnode_desc node_desc; int num_recs, new_rec_off, new_off, old_rec_off; int data_start, data_end, size; + size_t rec_off_tbl_size; + size_t node_desc_size = sizeof(struct hfs_bnode_desc); + size_t rec_size = sizeof(__be16); tree = fd->tree; node = fd->bnode; @@ -265,18 +268,22 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) return next_node; } - size = tree->node_size / 2 - node->num_recs * 2 - 14; - old_rec_off = tree->node_size - 4; + rec_off_tbl_size = node->num_recs * rec_size; + size = tree->node_size / 2; + size -= node_desc_size; + size -= rec_off_tbl_size; + old_rec_off = tree->node_size - (2 * rec_size); + num_recs = 1; for (;;) { data_start = hfs_bnode_read_u16(node, old_rec_off); if (data_start > size) break; - old_rec_off -= 2; + old_rec_off -= rec_size; if (++num_recs < node->num_recs) continue; - /* panic? */ hfs_bnode_put(node); + hfs_bnode_unlink(new_node); hfs_bnode_put(new_node); if (next_node) hfs_bnode_put(next_node); @@ -287,7 +294,7 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) /* new record is in the lower half, * so leave some more space there */ - old_rec_off += 2; + old_rec_off += rec_size; num_recs--; data_start = hfs_bnode_read_u16(node, old_rec_off); } else { @@ -295,27 +302,28 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) hfs_bnode_get(new_node); fd->bnode = new_node; fd->record -= num_recs; - fd->keyoffset -= data_start - 14; - fd->entryoffset -= data_start - 14; + fd->keyoffset -= data_start - node_desc_size; + fd->entryoffset -= data_start - node_desc_size; } new_node->num_recs = node->num_recs - num_recs; node->num_recs = num_recs; - new_rec_off = tree->node_size - 2; - new_off = 14; + new_rec_off = tree->node_size - rec_size; + new_off = node_desc_size; size = data_start - new_off; num_recs = new_node->num_recs; data_end = data_start; while (num_recs) { hfs_bnode_write_u16(new_node, new_rec_off, new_off); - old_rec_off -= 2; - new_rec_off -= 2; + old_rec_off -= rec_size; + new_rec_off -= rec_size; data_end = hfs_bnode_read_u16(node, old_rec_off); new_off = data_end - size; num_recs--; } hfs_bnode_write_u16(new_node, new_rec_off, new_off); - hfs_bnode_copy(new_node, 14, node, data_start, data_end - data_start); + hfs_bnode_copy(new_node, node_desc_size, + node, data_start, data_end - data_start); /* update new bnode header */ node_desc.next = cpu_to_be32(new_node->next);