Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hfs: clear offset and space out of valid records in b-tree node

Currently, hfs_brec_remove() executes moving records
towards the location of deleted record and it updates
offsets of moved records. However, the hfs_brec_remove()
logic ignores the "mess" of b-tree node's free space and
it doesn't touch the offsets out of records number.
Potentially, it could confuse fsck or driver logic or
to be a reason of potential corruption cases.

This patch reworks the logic of hfs_brec_remove()
by means of clearing freed space of b-tree node
after the records moving. And it clear the last
offset that keeping old location of free space
because now the offset before this one is keeping
the actual offset to the free space after the record
deletion.

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
cc: Yangtao Li <frank.li@vivo.com>
cc: linux-fsdevel@vger.kernel.org
Link: https://lore.kernel.org/r/20250815194918.38165-1-slava@dubeyko.com
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>

+23 -4
+23 -4
fs/hfs/brec.c
··· 179 179 struct hfs_btree *tree; 180 180 struct hfs_bnode *node, *parent; 181 181 int end_off, rec_off, data_off, size; 182 + int src, dst, len; 182 183 183 184 tree = fd->tree; 184 185 node = fd->bnode; ··· 209 208 } 210 209 hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs); 211 210 212 - if (rec_off == end_off) 213 - goto skip; 214 211 size = fd->keylength + fd->entrylength; 212 + 213 + if (rec_off == end_off) { 214 + src = fd->keyoffset; 215 + hfs_bnode_clear(node, src, size); 216 + goto skip; 217 + } 215 218 216 219 do { 217 220 data_off = hfs_bnode_read_u16(node, rec_off); ··· 224 219 } while (rec_off >= end_off); 225 220 226 221 /* fill hole */ 227 - hfs_bnode_move(node, fd->keyoffset, fd->keyoffset + size, 228 - data_off - fd->keyoffset - size); 222 + dst = fd->keyoffset; 223 + src = fd->keyoffset + size; 224 + len = data_off - src; 225 + 226 + hfs_bnode_move(node, dst, src, len); 227 + 228 + src = dst + len; 229 + len = data_off - src; 230 + 231 + hfs_bnode_clear(node, src, len); 232 + 229 233 skip: 234 + /* 235 + * Remove the obsolete offset to free space. 236 + */ 237 + hfs_bnode_write_u16(node, end_off, 0); 238 + 230 239 hfs_bnode_dump(node); 231 240 if (!fd->record) 232 241 hfs_brec_update_parent(fd);