MCPcopy Create free account
hub / github.com/bobranten/Ext4Fsd / do_split

Function do_split

Ext4Fsd/ext3/htree.c:1707–1791  ·  view source on GitHub ↗

* Split a full leaf block to make room for a new dir entry. * Allocate a new block, and move entries so that they are approx. equally full. * Returns pointer to de in block into which the new entry will be inserted. */

Source from the content-addressed store, hash-verified

1705 * Returns pointer to de in block into which the new entry will be inserted.
1706 */
1707struct ext3_dir_entry_2 *
1708 do_split(struct ext2_icb *icb, struct inode *dir,
1709 struct buffer_head **bh,struct dx_frame *frame,
1710 struct dx_hash_info *hinfo, int *error)
1711{
1712 unsigned blocksize = dir->i_sb->s_blocksize;
1713 unsigned count, continued;
1714 struct buffer_head *bh2;
1715 u32 newblock;
1716 u32 hash2;
1717 struct dx_map_entry *map;
1718 char *data1 = (*bh)->b_data, *data2;
1719 unsigned split, move, size;
1720 struct ext3_dir_entry_2 *de = NULL, *de2;
1721 struct ext4_dir_entry_tail *t;
1722 int csum_size = 0;
1723 int err, i;
1724
1725 if (ext4_has_metadata_csum(dir->i_sb))
1726 csum_size = sizeof(struct ext4_dir_entry_tail);
1727
1728 bh2 = ext3_append (icb, dir, &newblock, error);
1729 if (!(bh2)) {
1730 brelse(*bh);
1731 *bh = NULL;
1732 goto errout;
1733 }
1734
1735 data2 = bh2->b_data;
1736
1737 /* create map in the end of data2 block */
1738 map = (struct dx_map_entry *) (data2 + blocksize);
1739 count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
1740 blocksize, hinfo, map);
1741 map -= count;
1742 dx_sort_map (map, count);
1743 /* Split the existing block in the middle, size-wise */
1744 size = 0;
1745 move = 0;
1746 for (i = count-1; i >= 0; i--) {
1747 /* is more than half of this entry in 2nd half of the block? */
1748 if (size + map[i].size/2 > blocksize/2)
1749 break;
1750 size += map[i].size;
1751 move++;
1752 }
1753 /* map index at which we will split */
1754 split = count - move;
1755 hash2 = map[split].hash;
1756 continued = hash2 == map[split - 1].hash;
1757 dxtrace(printk("Split block %i at %x, %i/%i\n",
1758 dx_get_block(frame->at), hash2, split, count-split));
1759
1760 /* Fancy dance to stay within two buffers */
1761 de2 = dx_move_dirents(data1, data2, map + split, count - split);
1762 de = dx_pack_dirents(data1,blocksize);
1763 de->rec_len = cpu_to_le16(data1 + (blocksize - csum_size) - (char *) de);
1764 de2->rec_len = cpu_to_le16(data2 + (blocksize - csum_size) - (char *) de2);

Callers 2

ext3_dx_add_entryFunction · 0.85
make_indexed_dirFunction · 0.85

Calls 14

ext4_has_metadata_csumFunction · 0.85
ext3_appendFunction · 0.85
brelseFunction · 0.85
dx_make_mapFunction · 0.85
dx_sort_mapFunction · 0.85
dx_get_blockFunction · 0.85
dx_move_direntsFunction · 0.85
dx_pack_direntsFunction · 0.85
initialize_dirent_tailFunction · 0.85
dx_show_leafFunction · 0.85
dx_insert_blockFunction · 0.85
ext4_dx_csum_setFunction · 0.85

Tested by

no test coverage detected