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.

Merge tag 'hfs-v6.18-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs

Pull hfs updates from Viacheslav Dubeyko:
"This contains several fixes of syzbot reported issues, HFS/HFS+ fixes
of xfstests failures, and rework of HFS/HFS+ debug output subsystem.

- Kang Chen fixed a slab-out-of-bounds issue in hfsplus_uni2asc()
when hfsplus_uni2asc() is called from hfsplus_listxattr().

- Yang Chenzhi fixed a crash in hfsplus_bmap_alloc() if record offset
or length is larger than node_size.

- Yangtao Li corrected the error code from hfsplus_fill_super() if
Catalog File contains corrupted record for the case of hidden
directory's type.

- KMSAN uninit-value fixes: hfs_find_set_zero_bits() and
__hfsplus_ext_cache_extent() use kzalloc() instead of kmalloc(),
and in hfsplus_delete_cat() by proper initialization of struct
hfsplus_inode_info in the hfsplus_iget() logic.

- A slab-out-of-bounds issue could happen in hfsplus_strcasecmp() if
the length field of struct hfsplus_unistr is bigger than
HFSPLUS_MAX_STRLEN. Fixed by checking the length of comparing
strings, and if the strings' length is bigger than
HFSPLUS_MAX_STRLEN, then the length is corrected to this value.

- The generic/736 xfstest failed for HFS because the HFS volume
becomes corrupted after the test run.

The main reason was the absence of logic that corrects
mdb->drNxtCNID/HFS_SB(sb)->next_id (next unused CNID) after
deleting a record in Catalog File. That was fixed by implementing
the necessary logic in hfs_correct_next_unused_CNID()"

* tag 'hfs-v6.18-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs:
hfs/hfsplus: rework debug output subsystem
hfsplus: fix slab-out-of-bounds read in hfsplus_strcasecmp()
hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
hfs: clear offset and space out of valid records in b-tree node
hfs: add logic of correcting a next unused CNID
hfsplus: fix KMSAN uninit-value issue in hfsplus_delete_cat()
hfs: fix KMSAN uninit-value issue in hfs_find_set_zero_bits()
hfs: make proper initalization of struct hfs_find_data
hfsplus: fix KMSAN uninit-value issue in __hfsplus_ext_cache_extent()
hfs: validate record offset in hfsplus_bmap_alloc
hfsplus: return EIO when type of hidden directory mismatch in hfsplus_fill_super()
MAINTAINERS: update location of hfs&hfsplus trees

+442 -237
+4
MAINTAINERS
··· 10806 10806 M: Yangtao Li <frank.li@vivo.com> 10807 10807 L: linux-fsdevel@vger.kernel.org 10808 10808 S: Maintained 10809 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs.git 10809 10810 F: Documentation/filesystems/hfs.rst 10810 10811 F: fs/hfs/ 10812 + F: include/linux/hfs_common.h 10811 10813 10812 10814 HFSPLUS FILESYSTEM 10813 10815 M: Viacheslav Dubeyko <slava@dubeyko.com> ··· 10817 10815 M: Yangtao Li <frank.li@vivo.com> 10818 10816 L: linux-fsdevel@vger.kernel.org 10819 10817 S: Maintained 10818 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/hfs.git 10820 10819 F: Documentation/filesystems/hfsplus.rst 10821 10820 F: fs/hfsplus/ 10821 + F: include/linux/hfs_common.h 10822 10822 10823 10823 HGA FRAMEBUFFER DRIVER 10824 10824 M: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
+9 -3
fs/hfs/bfind.c
··· 21 21 22 22 fd->tree = tree; 23 23 fd->bnode = NULL; 24 - ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); 24 + ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); 25 25 if (!ptr) 26 26 return -ENOMEM; 27 27 fd->search_key = ptr; 28 28 fd->key = ptr + tree->max_key_len + 2; 29 - hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n", 29 + hfs_dbg("cnid %d, caller %ps\n", 30 30 tree->cnid, __builtin_return_address(0)); 31 31 switch (tree->cnid) { 32 32 case HFS_CAT_CNID: ··· 48 48 { 49 49 hfs_bnode_put(fd->bnode); 50 50 kfree(fd->search_key); 51 - hfs_dbg(BNODE_REFS, "find_exit: %d (%p)\n", 51 + hfs_dbg("cnid %d, caller %ps\n", 52 52 fd->tree->cnid, __builtin_return_address(0)); 53 53 mutex_unlock(&fd->tree->tree_lock); 54 54 fd->tree = NULL; ··· 114 114 u32 nidx, parent; 115 115 __be32 data; 116 116 int height, res; 117 + 118 + fd->record = -1; 119 + fd->keyoffset = -1; 120 + fd->keylength = -1; 121 + fd->entryoffset = -1; 122 + fd->entrylength = -1; 117 123 118 124 tree = fd->tree; 119 125 if (fd->bnode)
+2 -2
fs/hfs/bitmap.c
··· 158 158 } 159 159 } 160 160 161 - hfs_dbg(BITMAP, "alloc_bits: %u,%u\n", pos, *num_bits); 161 + hfs_dbg("pos %u, num_bits %u\n", pos, *num_bits); 162 162 HFS_SB(sb)->free_ablocks -= *num_bits; 163 163 hfs_bitmap_dirty(sb); 164 164 out: ··· 200 200 if (!count) 201 201 return 0; 202 202 203 - hfs_dbg(BITMAP, "clear_bits: %u,%u\n", start, count); 203 + hfs_dbg("start %u, count %u\n", start, count); 204 204 /* are all of the bits in range? */ 205 205 if ((start + count) > HFS_SB(sb)->fs_ablocks) 206 206 return -2;
+14 -14
fs/hfs/bnode.c
··· 200 200 { 201 201 struct page *src_page, *dst_page; 202 202 203 - hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); 203 + hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 204 204 if (!len) 205 205 return; 206 206 ··· 221 221 struct page *page; 222 222 void *ptr; 223 223 224 - hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); 224 + hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 225 225 if (!len) 226 226 return; 227 227 ··· 243 243 __be32 cnid; 244 244 int i, off, key_off; 245 245 246 - hfs_dbg(BNODE_MOD, "bnode: %d\n", node->this); 246 + hfs_dbg("node %d\n", node->this); 247 247 hfs_bnode_read(node, &desc, 0, sizeof(desc)); 248 - hfs_dbg(BNODE_MOD, "%d, %d, %d, %d, %d\n", 248 + hfs_dbg("next %d, prev %d, type %d, height %d, num_recs %d\n", 249 249 be32_to_cpu(desc.next), be32_to_cpu(desc.prev), 250 250 desc.type, desc.height, be16_to_cpu(desc.num_recs)); 251 251 252 252 off = node->tree->node_size - 2; 253 253 for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { 254 254 key_off = hfs_bnode_read_u16(node, off); 255 - hfs_dbg_cont(BNODE_MOD, " %d", key_off); 255 + hfs_dbg(" key_off %d", key_off); 256 256 if (i && node->type == HFS_NODE_INDEX) { 257 257 int tmp; 258 258 ··· 260 260 tmp = (hfs_bnode_read_u8(node, key_off) | 1) + 1; 261 261 else 262 262 tmp = node->tree->max_key_len + 1; 263 - hfs_dbg_cont(BNODE_MOD, " (%d,%d", 264 - tmp, hfs_bnode_read_u8(node, key_off)); 263 + hfs_dbg(" (%d,%d", 264 + tmp, hfs_bnode_read_u8(node, key_off)); 265 265 hfs_bnode_read(node, &cnid, key_off + tmp, 4); 266 - hfs_dbg_cont(BNODE_MOD, ",%d)", be32_to_cpu(cnid)); 266 + hfs_dbg(", cnid %d)", be32_to_cpu(cnid)); 267 267 } else if (i && node->type == HFS_NODE_LEAF) { 268 268 int tmp; 269 269 270 270 tmp = hfs_bnode_read_u8(node, key_off); 271 - hfs_dbg_cont(BNODE_MOD, " (%d)", tmp); 271 + hfs_dbg(" (%d)", tmp); 272 272 } 273 273 } 274 - hfs_dbg_cont(BNODE_MOD, "\n"); 274 + hfs_dbg("\n"); 275 275 } 276 276 277 277 void hfs_bnode_unlink(struct hfs_bnode *node) ··· 361 361 node->this = cnid; 362 362 set_bit(HFS_BNODE_NEW, &node->flags); 363 363 atomic_set(&node->refcnt, 1); 364 - hfs_dbg(BNODE_REFS, "new_node(%d:%d): 1\n", 364 + hfs_dbg("cnid %d, node %d, refcnt 1\n", 365 365 node->tree->cnid, node->this); 366 366 init_waitqueue_head(&node->lock_wq); 367 367 spin_lock(&tree->hash_lock); ··· 401 401 { 402 402 struct hfs_bnode **p; 403 403 404 - hfs_dbg(BNODE_REFS, "remove_node(%d:%d): %d\n", 404 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 405 405 node->tree->cnid, node->this, atomic_read(&node->refcnt)); 406 406 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; 407 407 *p && *p != node; p = &(*p)->next_hash) ··· 546 546 { 547 547 if (node) { 548 548 atomic_inc(&node->refcnt); 549 - hfs_dbg(BNODE_REFS, "get_node(%d:%d): %d\n", 549 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 550 550 node->tree->cnid, node->this, 551 551 atomic_read(&node->refcnt)); 552 552 } ··· 559 559 struct hfs_btree *tree = node->tree; 560 560 int i; 561 561 562 - hfs_dbg(BNODE_REFS, "put_node(%d:%d): %d\n", 562 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 563 563 node->tree->cnid, node->this, 564 564 atomic_read(&node->refcnt)); 565 565 BUG_ON(!atomic_read(&node->refcnt));
+27 -8
fs/hfs/brec.c
··· 94 94 end_rec_off = tree->node_size - (node->num_recs + 1) * 2; 95 95 end_off = hfs_bnode_read_u16(node, end_rec_off); 96 96 end_rec_off -= 2; 97 - hfs_dbg(BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", 97 + hfs_dbg("rec %d, size %d, end_off %d, end_rec_off %d\n", 98 98 rec, size, end_off, end_rec_off); 99 99 if (size > end_rec_off - end_off) { 100 100 if (new_node) ··· 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; ··· 192 191 mark_inode_dirty(tree->inode); 193 192 } 194 193 hfs_bnode_dump(node); 195 - hfs_dbg(BNODE_MOD, "remove_rec: %d, %d\n", 194 + hfs_dbg("rec %d, len %d\n", 196 195 fd->record, fd->keylength + fd->entrylength); 197 196 if (!--node->num_recs) { 198 197 hfs_bnode_unlink(node); ··· 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); ··· 261 242 if (IS_ERR(new_node)) 262 243 return new_node; 263 244 hfs_bnode_get(node); 264 - hfs_dbg(BNODE_MOD, "split_nodes: %d - %d - %d\n", 245 + hfs_dbg("this %d, new %d, next %d\n", 265 246 node->this, new_node->this, node->next); 266 247 new_node->next = node->next; 267 248 new_node->prev = node->this; ··· 397 378 newkeylen = (hfs_bnode_read_u8(node, 14) | 1) + 1; 398 379 else 399 380 fd->keylength = newkeylen = tree->max_key_len + 1; 400 - hfs_dbg(BNODE_MOD, "update_rec: %d, %d, %d\n", 381 + hfs_dbg("rec %d, keylength %d, newkeylen %d\n", 401 382 rec, fd->keylength, newkeylen); 402 383 403 384 rec_off = tree->node_size - (rec + 2) * 2;
+1 -1
fs/hfs/btree.c
··· 364 364 u32 nidx; 365 365 u8 *data, byte, m; 366 366 367 - hfs_dbg(BNODE_MOD, "btree_free_node: %u\n", node->this); 367 + hfs_dbg("node %u\n", node->this); 368 368 tree = node->tree; 369 369 nidx = node->this; 370 370 node = hfs_bnode_find(tree, 0);
+126 -3
fs/hfs/catalog.c
··· 87 87 int entry_size; 88 88 int err; 89 89 90 - hfs_dbg(CAT_MOD, "create_cat: %s,%u(%d)\n", 90 + hfs_dbg("name %s, cnid %u, i_nlink %d\n", 91 91 str->name, cnid, inode->i_nlink); 92 92 if (dir->i_size >= HFS_MAX_VALENCE) 93 93 return -ENOSPC; ··· 211 211 return hfs_brec_find(fd); 212 212 } 213 213 214 + static inline 215 + void hfs_set_next_unused_CNID(struct super_block *sb, 216 + u32 deleted_cnid, u32 found_cnid) 217 + { 218 + if (found_cnid < HFS_FIRSTUSER_CNID) { 219 + atomic64_cmpxchg(&HFS_SB(sb)->next_id, 220 + deleted_cnid + 1, HFS_FIRSTUSER_CNID); 221 + } else { 222 + atomic64_cmpxchg(&HFS_SB(sb)->next_id, 223 + deleted_cnid + 1, found_cnid + 1); 224 + } 225 + } 226 + 227 + /* 228 + * hfs_correct_next_unused_CNID() 229 + * 230 + * Correct the next unused CNID of Catalog Tree. 231 + */ 232 + static 233 + int hfs_correct_next_unused_CNID(struct super_block *sb, u32 cnid) 234 + { 235 + struct hfs_btree *cat_tree; 236 + struct hfs_bnode *node; 237 + s64 leaf_head; 238 + s64 leaf_tail; 239 + s64 node_id; 240 + 241 + hfs_dbg("cnid %u, next_id %lld\n", 242 + cnid, atomic64_read(&HFS_SB(sb)->next_id)); 243 + 244 + if ((cnid + 1) < atomic64_read(&HFS_SB(sb)->next_id)) { 245 + /* next ID should be unchanged */ 246 + return 0; 247 + } 248 + 249 + cat_tree = HFS_SB(sb)->cat_tree; 250 + leaf_head = cat_tree->leaf_head; 251 + leaf_tail = cat_tree->leaf_tail; 252 + 253 + if (leaf_head > leaf_tail) { 254 + pr_err("node is corrupted: leaf_head %lld, leaf_tail %lld\n", 255 + leaf_head, leaf_tail); 256 + return -ERANGE; 257 + } 258 + 259 + node = hfs_bnode_find(cat_tree, leaf_tail); 260 + if (IS_ERR(node)) { 261 + pr_err("fail to find leaf node: node ID %lld\n", 262 + leaf_tail); 263 + return -ENOENT; 264 + } 265 + 266 + node_id = leaf_tail; 267 + 268 + do { 269 + int i; 270 + 271 + if (node_id != leaf_tail) { 272 + node = hfs_bnode_find(cat_tree, node_id); 273 + if (IS_ERR(node)) 274 + return -ENOENT; 275 + } 276 + 277 + hfs_dbg("node %lld, leaf_tail %lld, leaf_head %lld\n", 278 + node_id, leaf_tail, leaf_head); 279 + 280 + hfs_bnode_dump(node); 281 + 282 + for (i = node->num_recs - 1; i >= 0; i--) { 283 + hfs_cat_rec rec; 284 + u16 off, len, keylen; 285 + int entryoffset; 286 + int entrylength; 287 + u32 found_cnid; 288 + 289 + len = hfs_brec_lenoff(node, i, &off); 290 + keylen = hfs_brec_keylen(node, i); 291 + if (keylen == 0) { 292 + pr_err("fail to get the keylen: " 293 + "node_id %lld, record index %d\n", 294 + node_id, i); 295 + return -EINVAL; 296 + } 297 + 298 + entryoffset = off + keylen; 299 + entrylength = len - keylen; 300 + 301 + if (entrylength > sizeof(rec)) { 302 + pr_err("unexpected record length: " 303 + "entrylength %d\n", 304 + entrylength); 305 + return -EINVAL; 306 + } 307 + 308 + hfs_bnode_read(node, &rec, entryoffset, entrylength); 309 + 310 + if (rec.type == HFS_CDR_DIR) { 311 + found_cnid = be32_to_cpu(rec.dir.DirID); 312 + hfs_dbg("found_cnid %u\n", found_cnid); 313 + hfs_set_next_unused_CNID(sb, cnid, found_cnid); 314 + hfs_bnode_put(node); 315 + return 0; 316 + } else if (rec.type == HFS_CDR_FIL) { 317 + found_cnid = be32_to_cpu(rec.file.FlNum); 318 + hfs_dbg("found_cnid %u\n", found_cnid); 319 + hfs_set_next_unused_CNID(sb, cnid, found_cnid); 320 + hfs_bnode_put(node); 321 + return 0; 322 + } 323 + } 324 + 325 + hfs_bnode_put(node); 326 + 327 + node_id = node->prev; 328 + } while (node_id >= leaf_head); 329 + 330 + return -ENOENT; 331 + } 214 332 215 333 /* 216 334 * hfs_cat_delete() ··· 343 225 struct hfs_readdir_data *rd; 344 226 int res, type; 345 227 346 - hfs_dbg(CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); 228 + hfs_dbg("name %s, cnid %u\n", str ? str->name : NULL, cnid); 347 229 sb = dir->i_sb; 348 230 res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); 349 231 if (res) ··· 389 271 dir->i_size--; 390 272 inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); 391 273 mark_inode_dirty(dir); 274 + 275 + res = hfs_correct_next_unused_CNID(sb, cnid); 276 + if (res) 277 + goto out; 278 + 392 279 res = 0; 393 280 out: 394 281 hfs_find_exit(&fd); ··· 417 294 int entry_size, type; 418 295 int err; 419 296 420 - hfs_dbg(CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", 297 + hfs_dbg("cnid %u - (ino %lu, name %s) - (ino %lu, name %s)\n", 421 298 cnid, src_dir->i_ino, src_name->name, 422 299 dst_dir->i_ino, dst_name->name); 423 300 sb = src_dir->i_sb;
+10 -9
fs/hfs/extent.c
··· 209 209 { 210 210 int i; 211 211 212 - hfs_dbg(EXTENT, " "); 212 + hfs_dbg("extent: "); 213 213 for (i = 0; i < 3; i++) 214 - hfs_dbg_cont(EXTENT, " %u:%u", 215 - be16_to_cpu(extent[i].block), 216 - be16_to_cpu(extent[i].count)); 217 - hfs_dbg_cont(EXTENT, "\n"); 214 + hfs_dbg(" block %u, count %u", 215 + be16_to_cpu(extent[i].block), 216 + be16_to_cpu(extent[i].count)); 217 + hfs_dbg("\n"); 218 218 } 219 219 220 220 static int hfs_add_extent(struct hfs_extent *extent, u16 offset, ··· 411 411 goto out; 412 412 } 413 413 414 - hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); 414 + hfs_dbg("ino %lu, start %u, len %u\n", inode->i_ino, start, len); 415 415 if (HFS_I(inode)->alloc_blocks == HFS_I(inode)->first_blocks) { 416 416 if (!HFS_I(inode)->first_blocks) { 417 - hfs_dbg(EXTENT, "first extents\n"); 417 + hfs_dbg("first_extent: start %u, len %u\n", 418 + start, len); 418 419 /* no extents yet */ 419 420 HFS_I(inode)->first_extents[0].block = cpu_to_be16(start); 420 421 HFS_I(inode)->first_extents[0].count = cpu_to_be16(len); ··· 457 456 return res; 458 457 459 458 insert_extent: 460 - hfs_dbg(EXTENT, "insert new extent\n"); 459 + hfs_dbg("insert new extent\n"); 461 460 res = hfs_ext_write_extent(inode); 462 461 if (res) 463 462 goto out; ··· 482 481 u32 size; 483 482 int res; 484 483 485 - hfs_dbg(INODE, "truncate: %lu, %Lu -> %Lu\n", 484 + hfs_dbg("ino %lu, phys_size %llu -> i_size %llu\n", 486 485 inode->i_ino, (long long)HFS_I(inode)->phys_size, 487 486 inode->i_size); 488 487 if (inode->i_size > HFS_I(inode)->phys_size) {
+4 -35
fs/hfs/hfs_fs.h
··· 9 9 #ifndef _LINUX_HFS_FS_H 10 10 #define _LINUX_HFS_FS_H 11 11 12 - #ifdef pr_fmt 13 - #undef pr_fmt 14 - #endif 15 - 16 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 - 18 12 #include <linux/slab.h> 19 13 #include <linux/types.h> 20 14 #include <linux/mutex.h> ··· 18 24 19 25 #include <asm/byteorder.h> 20 26 #include <linux/uaccess.h> 27 + #include <linux/hfs_common.h> 21 28 22 29 #include "hfs.h" 23 - 24 - #define DBG_BNODE_REFS 0x00000001 25 - #define DBG_BNODE_MOD 0x00000002 26 - #define DBG_CAT_MOD 0x00000004 27 - #define DBG_INODE 0x00000008 28 - #define DBG_SUPER 0x00000010 29 - #define DBG_EXTENT 0x00000020 30 - #define DBG_BITMAP 0x00000040 31 - 32 - //#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD|DBG_CAT_MOD|DBG_BITMAP) 33 - //#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE) 34 - //#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) 35 - #define DBG_MASK (0) 36 - 37 - #define hfs_dbg(flg, fmt, ...) \ 38 - do { \ 39 - if (DBG_##flg & DBG_MASK) \ 40 - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ 41 - } while (0) 42 - 43 - #define hfs_dbg_cont(flg, fmt, ...) \ 44 - do { \ 45 - if (DBG_##flg & DBG_MASK) \ 46 - pr_cont(fmt, ##__VA_ARGS__); \ 47 - } while (0) 48 - 49 30 50 31 /* 51 32 * struct hfs_inode_info ··· 81 112 the extents b-tree */ 82 113 struct hfs_btree *cat_tree; /* Information about 83 114 the catalog b-tree */ 84 - u32 file_count; /* The number of 115 + atomic64_t file_count; /* The number of 85 116 regular files in 86 117 the filesystem */ 87 - u32 folder_count; /* The number of 118 + atomic64_t folder_count; /* The number of 88 119 directories in the 89 120 filesystem */ 90 - u32 next_id; /* The next available 121 + atomic64_t next_id; /* The next available 91 122 file id number */ 92 123 u32 clumpablks; /* The number of allocation 93 124 blocks to try to add when
+18 -7
fs/hfs/inode.c
··· 183 183 { 184 184 struct super_block *sb = dir->i_sb; 185 185 struct inode *inode = new_inode(sb); 186 + s64 next_id; 187 + s64 file_count; 188 + s64 folder_count; 189 + 186 190 if (!inode) 187 191 return NULL; 188 192 ··· 194 190 INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list); 195 191 spin_lock_init(&HFS_I(inode)->open_dir_lock); 196 192 hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name); 197 - inode->i_ino = HFS_SB(sb)->next_id++; 193 + next_id = atomic64_inc_return(&HFS_SB(sb)->next_id); 194 + BUG_ON(next_id > U32_MAX); 195 + inode->i_ino = (u32)next_id; 198 196 inode->i_mode = mode; 199 197 inode->i_uid = current_fsuid(); 200 198 inode->i_gid = current_fsgid(); ··· 208 202 HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60; 209 203 if (S_ISDIR(mode)) { 210 204 inode->i_size = 2; 211 - HFS_SB(sb)->folder_count++; 205 + folder_count = atomic64_inc_return(&HFS_SB(sb)->folder_count); 206 + BUG_ON(folder_count > U32_MAX); 212 207 if (dir->i_ino == HFS_ROOT_CNID) 213 208 HFS_SB(sb)->root_dirs++; 214 209 inode->i_op = &hfs_dir_inode_operations; ··· 218 211 inode->i_mode &= ~HFS_SB(inode->i_sb)->s_dir_umask; 219 212 } else if (S_ISREG(mode)) { 220 213 HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks; 221 - HFS_SB(sb)->file_count++; 214 + file_count = atomic64_inc_return(&HFS_SB(sb)->file_count); 215 + BUG_ON(file_count > U32_MAX); 222 216 if (dir->i_ino == HFS_ROOT_CNID) 223 217 HFS_SB(sb)->root_files++; 224 218 inode->i_op = &hfs_file_inode_operations; ··· 249 241 { 250 242 struct super_block *sb = inode->i_sb; 251 243 252 - hfs_dbg(INODE, "delete_inode: %lu\n", inode->i_ino); 244 + hfs_dbg("ino %lu\n", inode->i_ino); 253 245 if (S_ISDIR(inode->i_mode)) { 254 - HFS_SB(sb)->folder_count--; 246 + BUG_ON(atomic64_read(&HFS_SB(sb)->folder_count) > U32_MAX); 247 + atomic64_dec(&HFS_SB(sb)->folder_count); 255 248 if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID)) 256 249 HFS_SB(sb)->root_dirs--; 257 250 set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags); 258 251 hfs_mark_mdb_dirty(sb); 259 252 return; 260 253 } 261 - HFS_SB(sb)->file_count--; 254 + 255 + BUG_ON(atomic64_read(&HFS_SB(sb)->file_count) > U32_MAX); 256 + atomic64_dec(&HFS_SB(sb)->file_count); 262 257 if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID)) 263 258 HFS_SB(sb)->root_files--; 264 259 if (S_ISREG(inode->i_mode)) { ··· 436 425 hfs_cat_rec rec; 437 426 int res; 438 427 439 - hfs_dbg(INODE, "hfs_write_inode: %lu\n", inode->i_ino); 428 + hfs_dbg("ino %lu\n", inode->i_ino); 440 429 res = hfs_ext_write_extent(inode); 441 430 if (res) 442 431 return res;
+13 -7
fs/hfs/mdb.c
··· 150 150 151 151 /* These parameters are read from and written to the MDB */ 152 152 HFS_SB(sb)->free_ablocks = be16_to_cpu(mdb->drFreeBks); 153 - HFS_SB(sb)->next_id = be32_to_cpu(mdb->drNxtCNID); 153 + atomic64_set(&HFS_SB(sb)->next_id, be32_to_cpu(mdb->drNxtCNID)); 154 154 HFS_SB(sb)->root_files = be16_to_cpu(mdb->drNmFls); 155 155 HFS_SB(sb)->root_dirs = be16_to_cpu(mdb->drNmRtDirs); 156 - HFS_SB(sb)->file_count = be32_to_cpu(mdb->drFilCnt); 157 - HFS_SB(sb)->folder_count = be32_to_cpu(mdb->drDirCnt); 156 + atomic64_set(&HFS_SB(sb)->file_count, be32_to_cpu(mdb->drFilCnt)); 157 + atomic64_set(&HFS_SB(sb)->folder_count, be32_to_cpu(mdb->drDirCnt)); 158 158 159 159 /* TRY to get the alternate (backup) MDB. */ 160 160 sect = part_start + part_size - 2; ··· 172 172 pr_warn("continuing without an alternate MDB\n"); 173 173 } 174 174 175 - HFS_SB(sb)->bitmap = kmalloc(8192, GFP_KERNEL); 175 + HFS_SB(sb)->bitmap = kzalloc(8192, GFP_KERNEL); 176 176 if (!HFS_SB(sb)->bitmap) 177 177 goto out; 178 178 ··· 273 273 /* These parameters may have been modified, so write them back */ 274 274 mdb->drLsMod = hfs_mtime(); 275 275 mdb->drFreeBks = cpu_to_be16(HFS_SB(sb)->free_ablocks); 276 - mdb->drNxtCNID = cpu_to_be32(HFS_SB(sb)->next_id); 276 + BUG_ON(atomic64_read(&HFS_SB(sb)->next_id) > U32_MAX); 277 + mdb->drNxtCNID = 278 + cpu_to_be32((u32)atomic64_read(&HFS_SB(sb)->next_id)); 277 279 mdb->drNmFls = cpu_to_be16(HFS_SB(sb)->root_files); 278 280 mdb->drNmRtDirs = cpu_to_be16(HFS_SB(sb)->root_dirs); 279 - mdb->drFilCnt = cpu_to_be32(HFS_SB(sb)->file_count); 280 - mdb->drDirCnt = cpu_to_be32(HFS_SB(sb)->folder_count); 281 + BUG_ON(atomic64_read(&HFS_SB(sb)->file_count) > U32_MAX); 282 + mdb->drFilCnt = 283 + cpu_to_be32((u32)atomic64_read(&HFS_SB(sb)->file_count)); 284 + BUG_ON(atomic64_read(&HFS_SB(sb)->folder_count) > U32_MAX); 285 + mdb->drDirCnt = 286 + cpu_to_be32((u32)atomic64_read(&HFS_SB(sb)->folder_count)); 281 287 282 288 /* write MDB to disk */ 283 289 mark_buffer_dirty(HFS_SB(sb)->mdb_bh);
+4
fs/hfs/super.c
··· 319 319 int silent = fc->sb_flags & SB_SILENT; 320 320 int res; 321 321 322 + atomic64_set(&sbi->file_count, 0); 323 + atomic64_set(&sbi->folder_count, 0); 324 + atomic64_set(&sbi->next_id, 0); 325 + 322 326 /* load_nls_default does not fail */ 323 327 if (sbi->nls_disk && !sbi->nls_io) 324 328 sbi->nls_io = load_nls_default();
+4 -4
fs/hfsplus/attributes.c
··· 139 139 { 140 140 int err = 0; 141 141 142 - hfs_dbg(ATTR_MOD, "find_attr: %s,%d\n", name ? name : NULL, cnid); 142 + hfs_dbg("name %s, cnid %d\n", name ? name : NULL, cnid); 143 143 144 144 if (!HFSPLUS_SB(sb)->attr_tree) { 145 145 pr_err("attributes file doesn't exist\n"); ··· 201 201 int entry_size; 202 202 int err; 203 203 204 - hfs_dbg(ATTR_MOD, "create_attr: %s,%ld\n", 204 + hfs_dbg("name %s, ino %ld\n", 205 205 name ? name : NULL, inode->i_ino); 206 206 207 207 if (!HFSPLUS_SB(sb)->attr_tree) { ··· 310 310 struct super_block *sb = inode->i_sb; 311 311 struct hfs_find_data fd; 312 312 313 - hfs_dbg(ATTR_MOD, "delete_attr: %s,%ld\n", 313 + hfs_dbg("name %s, ino %ld\n", 314 314 name ? name : NULL, inode->i_ino); 315 315 316 316 if (!HFSPLUS_SB(sb)->attr_tree) { ··· 356 356 int err = 0; 357 357 struct hfs_find_data fd; 358 358 359 - hfs_dbg(ATTR_MOD, "delete_all_attrs: %d\n", cnid); 359 + hfs_dbg("cnid %d\n", cnid); 360 360 361 361 if (!HFSPLUS_SB(dir->i_sb)->attr_tree) { 362 362 pr_err("attributes file doesn't exist\n");
+9 -3
fs/hfsplus/bfind.c
··· 18 18 19 19 fd->tree = tree; 20 20 fd->bnode = NULL; 21 - ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); 21 + ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); 22 22 if (!ptr) 23 23 return -ENOMEM; 24 24 fd->search_key = ptr; 25 25 fd->key = ptr + tree->max_key_len + 2; 26 - hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n", 26 + hfs_dbg("cnid %d, caller %ps\n", 27 27 tree->cnid, __builtin_return_address(0)); 28 28 mutex_lock_nested(&tree->tree_lock, 29 29 hfsplus_btree_lock_class(tree)); ··· 34 34 { 35 35 hfs_bnode_put(fd->bnode); 36 36 kfree(fd->search_key); 37 - hfs_dbg(BNODE_REFS, "find_exit: %d (%p)\n", 37 + hfs_dbg("cnid %d, caller %ps\n", 38 38 fd->tree->cnid, __builtin_return_address(0)); 39 39 mutex_unlock(&fd->tree->tree_lock); 40 40 fd->tree = NULL; ··· 157 157 u32 nidx, parent; 158 158 __be32 data; 159 159 int height, res; 160 + 161 + fd->record = -1; 162 + fd->keyoffset = -1; 163 + fd->keylength = -1; 164 + fd->entryoffset = -1; 165 + fd->entrylength = -1; 160 166 161 167 tree = fd->tree; 162 168 if (fd->bnode)
+5 -5
fs/hfsplus/bitmap.c
··· 31 31 if (!len) 32 32 return size; 33 33 34 - hfs_dbg(BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); 34 + hfs_dbg("size %u, offset %u, len %u\n", size, offset, len); 35 35 mutex_lock(&sbi->alloc_mutex); 36 36 mapping = sbi->alloc_file->i_mapping; 37 37 page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); ··· 90 90 else 91 91 end = pptr + ((size + 31) & (PAGE_CACHE_BITS - 1)) / 32; 92 92 } 93 - hfs_dbg(BITMAP, "bitmap full\n"); 93 + hfs_dbg("bitmap full\n"); 94 94 start = size; 95 95 goto out; 96 96 97 97 found: 98 98 start = offset + (curr - pptr) * 32 + i; 99 99 if (start >= size) { 100 - hfs_dbg(BITMAP, "bitmap full\n"); 100 + hfs_dbg("bitmap full\n"); 101 101 goto out; 102 102 } 103 103 /* do any partial u32 at the start */ ··· 155 155 *max = offset + (curr - pptr) * 32 + i - start; 156 156 sbi->free_blocks -= *max; 157 157 hfsplus_mark_mdb_dirty(sb); 158 - hfs_dbg(BITMAP, "-> %u,%u\n", start, *max); 158 + hfs_dbg("start %u, max %u\n", start, *max); 159 159 out: 160 160 mutex_unlock(&sbi->alloc_mutex); 161 161 return start; ··· 174 174 if (!count) 175 175 return 0; 176 176 177 - hfs_dbg(BITMAP, "block_free: %u,%u\n", offset, count); 177 + hfs_dbg("offset %u, count %u\n", offset, count); 178 178 /* are all of the bits in range? */ 179 179 if ((offset + count) > sbi->total_blocks) 180 180 return -ENOENT;
+14 -55
fs/hfsplus/bnode.c
··· 18 18 #include "hfsplus_fs.h" 19 19 #include "hfsplus_raw.h" 20 20 21 - static inline 22 - bool is_bnode_offset_valid(struct hfs_bnode *node, int off) 23 - { 24 - bool is_valid = off < node->tree->node_size; 25 - 26 - if (!is_valid) { 27 - pr_err("requested invalid offset: " 28 - "NODE: id %u, type %#x, height %u, " 29 - "node_size %u, offset %d\n", 30 - node->this, node->type, node->height, 31 - node->tree->node_size, off); 32 - } 33 - 34 - return is_valid; 35 - } 36 - 37 - static inline 38 - int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) 39 - { 40 - unsigned int node_size; 41 - 42 - if (!is_bnode_offset_valid(node, off)) 43 - return 0; 44 - 45 - node_size = node->tree->node_size; 46 - 47 - if ((off + len) > node_size) { 48 - int new_len = (int)node_size - off; 49 - 50 - pr_err("requested length has been corrected: " 51 - "NODE: id %u, type %#x, height %u, " 52 - "node_size %u, offset %d, " 53 - "requested_len %d, corrected_len %d\n", 54 - node->this, node->type, node->height, 55 - node->tree->node_size, off, len, new_len); 56 - 57 - return new_len; 58 - } 59 - 60 - return len; 61 - } 62 21 63 22 /* Copy a specified range of bytes from the raw data of a node */ 64 23 void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) ··· 173 214 struct page **src_page, **dst_page; 174 215 int l; 175 216 176 - hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); 217 + hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 177 218 if (!len) 178 219 return; 179 220 ··· 231 272 void *src_ptr, *dst_ptr; 232 273 int l; 233 274 234 - hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); 275 + hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 235 276 if (!len) 236 277 return; 237 278 ··· 351 392 __be32 cnid; 352 393 int i, off, key_off; 353 394 354 - hfs_dbg(BNODE_MOD, "bnode: %d\n", node->this); 395 + hfs_dbg("node %d\n", node->this); 355 396 hfs_bnode_read(node, &desc, 0, sizeof(desc)); 356 - hfs_dbg(BNODE_MOD, "%d, %d, %d, %d, %d\n", 397 + hfs_dbg("next %d, prev %d, type %d, height %d, num_recs %d\n", 357 398 be32_to_cpu(desc.next), be32_to_cpu(desc.prev), 358 399 desc.type, desc.height, be16_to_cpu(desc.num_recs)); 359 400 360 401 off = node->tree->node_size - 2; 361 402 for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { 362 403 key_off = hfs_bnode_read_u16(node, off); 363 - hfs_dbg(BNODE_MOD, " %d", key_off); 404 + hfs_dbg(" key_off %d", key_off); 364 405 if (i && node->type == HFS_NODE_INDEX) { 365 406 int tmp; 366 407 ··· 369 410 tmp = hfs_bnode_read_u16(node, key_off) + 2; 370 411 else 371 412 tmp = node->tree->max_key_len + 2; 372 - hfs_dbg_cont(BNODE_MOD, " (%d", tmp); 413 + hfs_dbg(" (%d", tmp); 373 414 hfs_bnode_read(node, &cnid, key_off + tmp, 4); 374 - hfs_dbg_cont(BNODE_MOD, ",%d)", be32_to_cpu(cnid)); 415 + hfs_dbg(", cnid %d)", be32_to_cpu(cnid)); 375 416 } else if (i && node->type == HFS_NODE_LEAF) { 376 417 int tmp; 377 418 378 419 tmp = hfs_bnode_read_u16(node, key_off); 379 - hfs_dbg_cont(BNODE_MOD, " (%d)", tmp); 420 + hfs_dbg(" (%d)", tmp); 380 421 } 381 422 } 382 - hfs_dbg_cont(BNODE_MOD, "\n"); 423 + hfs_dbg("\n"); 383 424 } 384 425 385 426 void hfs_bnode_unlink(struct hfs_bnode *node) ··· 415 456 416 457 /* move down? */ 417 458 if (!node->prev && !node->next) 418 - hfs_dbg(BNODE_MOD, "hfs_btree_del_level\n"); 459 + hfs_dbg("btree delete level\n"); 419 460 if (!node->parent) { 420 461 tree->root = 0; 421 462 tree->depth = 0; ··· 470 511 node->this = cnid; 471 512 set_bit(HFS_BNODE_NEW, &node->flags); 472 513 atomic_set(&node->refcnt, 1); 473 - hfs_dbg(BNODE_REFS, "new_node(%d:%d): 1\n", 514 + hfs_dbg("cnid %d, node %d, refcnt 1\n", 474 515 node->tree->cnid, node->this); 475 516 init_waitqueue_head(&node->lock_wq); 476 517 spin_lock(&tree->hash_lock); ··· 510 551 { 511 552 struct hfs_bnode **p; 512 553 513 - hfs_dbg(BNODE_REFS, "remove_node(%d:%d): %d\n", 554 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 514 555 node->tree->cnid, node->this, atomic_read(&node->refcnt)); 515 556 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; 516 557 *p && *p != node; p = &(*p)->next_hash) ··· 656 697 { 657 698 if (node) { 658 699 atomic_inc(&node->refcnt); 659 - hfs_dbg(BNODE_REFS, "get_node(%d:%d): %d\n", 700 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 660 701 node->tree->cnid, node->this, 661 702 atomic_read(&node->refcnt)); 662 703 } ··· 669 710 struct hfs_btree *tree = node->tree; 670 711 int i; 671 712 672 - hfs_dbg(BNODE_REFS, "put_node(%d:%d): %d\n", 713 + hfs_dbg("cnid %d, node %d, refcnt %d\n", 673 714 node->tree->cnid, node->this, 674 715 atomic_read(&node->refcnt)); 675 716 BUG_ON(!atomic_read(&node->refcnt));
+5 -5
fs/hfsplus/brec.c
··· 92 92 end_rec_off = tree->node_size - (node->num_recs + 1) * 2; 93 93 end_off = hfs_bnode_read_u16(node, end_rec_off); 94 94 end_rec_off -= 2; 95 - hfs_dbg(BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", 95 + hfs_dbg("rec %d, size %d, end_off %d, end_rec_off %d\n", 96 96 rec, size, end_off, end_rec_off); 97 97 if (size > end_rec_off - end_off) { 98 98 if (new_node) ··· 193 193 mark_inode_dirty(tree->inode); 194 194 } 195 195 hfs_bnode_dump(node); 196 - hfs_dbg(BNODE_MOD, "remove_rec: %d, %d\n", 196 + hfs_dbg("rec %d, len %d\n", 197 197 fd->record, fd->keylength + fd->entrylength); 198 198 if (!--node->num_recs) { 199 199 hfs_bnode_unlink(node); ··· 246 246 if (IS_ERR(new_node)) 247 247 return new_node; 248 248 hfs_bnode_get(node); 249 - hfs_dbg(BNODE_MOD, "split_nodes: %d - %d - %d\n", 249 + hfs_dbg("this %d - new %d - next %d\n", 250 250 node->this, new_node->this, node->next); 251 251 new_node->next = node->next; 252 252 new_node->prev = node->this; ··· 383 383 newkeylen = hfs_bnode_read_u16(node, 14) + 2; 384 384 else 385 385 fd->keylength = newkeylen = tree->max_key_len + 2; 386 - hfs_dbg(BNODE_MOD, "update_rec: %d, %d, %d\n", 386 + hfs_dbg("rec %d, keylength %d, newkeylen %d\n", 387 387 rec, fd->keylength, newkeylen); 388 388 389 389 rec_off = tree->node_size - (rec + 2) * 2; ··· 395 395 end_off = hfs_bnode_read_u16(parent, end_rec_off); 396 396 if (end_rec_off - end_off < diff) { 397 397 398 - hfs_dbg(BNODE_MOD, "splitting index node\n"); 398 + hfs_dbg("splitting index node\n"); 399 399 fd->bnode = parent; 400 400 new_node = hfs_bnode_split(fd); 401 401 if (IS_ERR(new_node))
+8 -2
fs/hfsplus/btree.c
··· 393 393 len = hfs_brec_lenoff(node, 2, &off16); 394 394 off = off16; 395 395 396 + if (!is_bnode_offset_valid(node, off)) { 397 + hfs_bnode_put(node); 398 + return ERR_PTR(-EIO); 399 + } 400 + len = check_and_correct_requested_length(node, off, len); 401 + 396 402 off += node->page_offset; 397 403 pagep = node->page + (off >> PAGE_SHIFT); 398 404 data = kmap_local_page(*pagep); ··· 434 428 kunmap_local(data); 435 429 nidx = node->next; 436 430 if (!nidx) { 437 - hfs_dbg(BNODE_MOD, "create new bmap node\n"); 431 + hfs_dbg("create new bmap node\n"); 438 432 next_node = hfs_bmap_new_bmap(node, idx); 439 433 } else 440 434 next_node = hfs_bnode_find(tree, nidx); ··· 460 454 u32 nidx; 461 455 u8 *data, byte, m; 462 456 463 - hfs_dbg(BNODE_MOD, "btree_free_node: %u\n", node->this); 457 + hfs_dbg("node %u\n", node->this); 464 458 BUG_ON(!node->this); 465 459 tree = node->tree; 466 460 nidx = node->this;
+3 -3
fs/hfsplus/catalog.c
··· 259 259 int entry_size; 260 260 int err; 261 261 262 - hfs_dbg(CAT_MOD, "create_cat: %s,%u(%d)\n", 262 + hfs_dbg("name %s, cnid %u, i_nlink %d\n", 263 263 str->name, cnid, inode->i_nlink); 264 264 err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); 265 265 if (err) ··· 336 336 int err, off; 337 337 u16 type; 338 338 339 - hfs_dbg(CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); 339 + hfs_dbg("name %s, cnid %u\n", str ? str->name : NULL, cnid); 340 340 err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); 341 341 if (err) 342 342 return err; ··· 441 441 int entry_size, type; 442 442 int err; 443 443 444 - hfs_dbg(CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", 444 + hfs_dbg("cnid %u - ino %lu, name %s - ino %lu, name %s\n", 445 445 cnid, src_dir->i_ino, src_name->name, 446 446 dst_dir->i_ino, dst_name->name); 447 447 err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd);
+1 -1
fs/hfsplus/dir.c
··· 204 204 fd.entrylength); 205 205 type = be16_to_cpu(entry.type); 206 206 len = NLS_MAX_CHARSET_SIZE * HFSPLUS_MAX_STRLEN; 207 - err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len); 207 + err = hfsplus_uni2asc_str(sb, &fd.key->cat.name, strbuf, &len); 208 208 if (err) 209 209 goto out; 210 210 if (type == HFSPLUS_FOLDER) {
+13 -14
fs/hfsplus/extents.c
··· 275 275 mutex_unlock(&hip->extents_lock); 276 276 277 277 done: 278 - hfs_dbg(EXTENT, "get_block(%lu): %llu - %u\n", 278 + hfs_dbg("ino %lu, iblock %llu - dblock %u\n", 279 279 inode->i_ino, (long long)iblock, dblock); 280 280 281 281 mask = (1 << sbi->fs_shift) - 1; ··· 298 298 { 299 299 int i; 300 300 301 - hfs_dbg(EXTENT, " "); 301 + hfs_dbg("extent "); 302 302 for (i = 0; i < 8; i++) 303 - hfs_dbg_cont(EXTENT, " %u:%u", 304 - be32_to_cpu(extent[i].start_block), 305 - be32_to_cpu(extent[i].block_count)); 306 - hfs_dbg_cont(EXTENT, "\n"); 303 + hfs_dbg(" start_block %u, block_count %u", 304 + be32_to_cpu(extent[i].start_block), 305 + be32_to_cpu(extent[i].block_count)); 306 + hfs_dbg("\n"); 307 307 } 308 308 309 309 static int hfsplus_add_extent(struct hfsplus_extent *extent, u32 offset, ··· 359 359 if (count <= block_nr) { 360 360 err = hfsplus_block_free(sb, start, count); 361 361 if (err) { 362 - pr_err("can't free extent\n"); 363 - hfs_dbg(EXTENT, " start: %u count: %u\n", 362 + pr_err("can't free extent: start %u, count %u\n", 364 363 start, count); 365 364 } 366 365 extent->block_count = 0; ··· 369 370 count -= block_nr; 370 371 err = hfsplus_block_free(sb, start + count, block_nr); 371 372 if (err) { 372 - pr_err("can't free extent\n"); 373 - hfs_dbg(EXTENT, " start: %u count: %u\n", 373 + pr_err("can't free extent: start %u, count %u\n", 374 374 start, count); 375 375 } 376 376 extent->block_count = cpu_to_be32(count); ··· 476 478 goto out; 477 479 } 478 480 479 - hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); 481 + hfs_dbg("ino %lu, start %u, len %u\n", inode->i_ino, start, len); 480 482 481 483 if (hip->alloc_blocks <= hip->first_blocks) { 482 484 if (!hip->first_blocks) { 483 - hfs_dbg(EXTENT, "first extents\n"); 485 + hfs_dbg("first_extent: start %u, len %u\n", 486 + start, len); 484 487 /* no extents yet */ 485 488 hip->first_extents[0].start_block = cpu_to_be32(start); 486 489 hip->first_extents[0].block_count = cpu_to_be32(len); ··· 520 521 return res; 521 522 522 523 insert_extent: 523 - hfs_dbg(EXTENT, "insert new extent\n"); 524 + hfs_dbg("insert new extent\n"); 524 525 res = hfsplus_ext_write_extent_locked(inode); 525 526 if (res) 526 527 goto out; ··· 545 546 u32 alloc_cnt, blk_cnt, start; 546 547 int res; 547 548 548 - hfs_dbg(INODE, "truncate: %lu, %llu -> %llu\n", 549 + hfs_dbg("ino %lu, phys_size %llu -> i_size %llu\n", 549 550 inode->i_ino, (long long)hip->phys_size, inode->i_size); 550 551 551 552 if (inode->i_size > hip->phys_size) {
+49 -36
fs/hfsplus/hfsplus_fs.h
··· 11 11 #ifndef _LINUX_HFSPLUS_FS_H 12 12 #define _LINUX_HFSPLUS_FS_H 13 13 14 - #ifdef pr_fmt 15 - #undef pr_fmt 16 - #endif 17 - 18 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19 - 20 14 #include <linux/fs.h> 21 15 #include <linux/mutex.h> 22 16 #include <linux/buffer_head.h> 23 17 #include <linux/blkdev.h> 24 18 #include <linux/fs_context.h> 19 + #include <linux/hfs_common.h> 25 20 #include "hfsplus_raw.h" 26 - 27 - #define DBG_BNODE_REFS 0x00000001 28 - #define DBG_BNODE_MOD 0x00000002 29 - #define DBG_CAT_MOD 0x00000004 30 - #define DBG_INODE 0x00000008 31 - #define DBG_SUPER 0x00000010 32 - #define DBG_EXTENT 0x00000020 33 - #define DBG_BITMAP 0x00000040 34 - #define DBG_ATTR_MOD 0x00000080 35 - 36 - #if 0 37 - #define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD) 38 - #define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE) 39 - #define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) 40 - #endif 41 - #define DBG_MASK (0) 42 - 43 - #define hfs_dbg(flg, fmt, ...) \ 44 - do { \ 45 - if (DBG_##flg & DBG_MASK) \ 46 - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ 47 - } while (0) 48 - 49 - #define hfs_dbg_cont(flg, fmt, ...) \ 50 - do { \ 51 - if (DBG_##flg & DBG_MASK) \ 52 - pr_cont(fmt, ##__VA_ARGS__); \ 53 - } while (0) 54 21 55 22 /* Runtime config options */ 56 23 #define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */ ··· 488 521 const struct hfsplus_unistr *s2); 489 522 int hfsplus_strcmp(const struct hfsplus_unistr *s1, 490 523 const struct hfsplus_unistr *s2); 491 - int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, 492 - char *astr, int *len_p); 524 + int hfsplus_uni2asc_str(struct super_block *sb, 525 + const struct hfsplus_unistr *ustr, char *astr, 526 + int *len_p); 527 + int hfsplus_uni2asc_xattr_str(struct super_block *sb, 528 + const struct hfsplus_attr_unistr *ustr, 529 + char *astr, int *len_p); 493 530 int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, 494 531 int max_unistr_len, const char *astr, int len); 495 532 int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); ··· 546 575 BUG(); 547 576 } 548 577 return class; 578 + } 579 + 580 + static inline 581 + bool is_bnode_offset_valid(struct hfs_bnode *node, int off) 582 + { 583 + bool is_valid = off < node->tree->node_size; 584 + 585 + if (!is_valid) { 586 + pr_err("requested invalid offset: " 587 + "NODE: id %u, type %#x, height %u, " 588 + "node_size %u, offset %d\n", 589 + node->this, node->type, node->height, 590 + node->tree->node_size, off); 591 + } 592 + 593 + return is_valid; 594 + } 595 + 596 + static inline 597 + int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) 598 + { 599 + unsigned int node_size; 600 + 601 + if (!is_bnode_offset_valid(node, off)) 602 + return 0; 603 + 604 + node_size = node->tree->node_size; 605 + 606 + if ((off + len) > node_size) { 607 + int new_len = (int)node_size - off; 608 + 609 + pr_err("requested length has been corrected: " 610 + "NODE: id %u, type %#x, height %u, " 611 + "node_size %u, offset %d, " 612 + "requested_len %d, corrected_len %d\n", 613 + node->this, node->type, node->height, 614 + node->tree->node_size, off, len, new_len); 615 + 616 + return new_len; 617 + } 618 + 619 + return len; 549 620 } 550 621 551 622 /* compatibility */
+31 -10
fs/hfsplus/super.c
··· 68 68 if (!(inode->i_state & I_NEW)) 69 69 return inode; 70 70 71 + atomic_set(&HFSPLUS_I(inode)->opencnt, 0); 72 + HFSPLUS_I(inode)->first_blocks = 0; 73 + HFSPLUS_I(inode)->clump_blocks = 0; 74 + HFSPLUS_I(inode)->alloc_blocks = 0; 75 + HFSPLUS_I(inode)->cached_start = U32_MAX; 76 + HFSPLUS_I(inode)->cached_blocks = 0; 77 + memset(HFSPLUS_I(inode)->first_extents, 0, sizeof(hfsplus_extent_rec)); 78 + memset(HFSPLUS_I(inode)->cached_extents, 0, sizeof(hfsplus_extent_rec)); 79 + HFSPLUS_I(inode)->extent_state = 0; 80 + mutex_init(&HFSPLUS_I(inode)->extents_lock); 81 + HFSPLUS_I(inode)->rsrc_inode = NULL; 82 + HFSPLUS_I(inode)->create_date = 0; 83 + HFSPLUS_I(inode)->linkid = 0; 84 + HFSPLUS_I(inode)->flags = 0; 85 + HFSPLUS_I(inode)->fs_blocks = 0; 86 + HFSPLUS_I(inode)->userflags = 0; 87 + HFSPLUS_I(inode)->subfolders = 0; 71 88 INIT_LIST_HEAD(&HFSPLUS_I(inode)->open_dir_list); 72 89 spin_lock_init(&HFSPLUS_I(inode)->open_dir_lock); 73 - mutex_init(&HFSPLUS_I(inode)->extents_lock); 74 - HFSPLUS_I(inode)->flags = 0; 75 - HFSPLUS_I(inode)->extent_state = 0; 76 - HFSPLUS_I(inode)->rsrc_inode = NULL; 77 - atomic_set(&HFSPLUS_I(inode)->opencnt, 0); 90 + HFSPLUS_I(inode)->phys_size = 0; 78 91 79 92 if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID || 80 93 inode->i_ino == HFSPLUS_ROOT_CNID) { ··· 163 150 { 164 151 int err; 165 152 166 - hfs_dbg(INODE, "hfsplus_write_inode: %lu\n", inode->i_ino); 153 + hfs_dbg("ino %lu\n", inode->i_ino); 167 154 168 155 err = hfsplus_ext_write_extent(inode); 169 156 if (err) ··· 178 165 179 166 static void hfsplus_evict_inode(struct inode *inode) 180 167 { 181 - hfs_dbg(INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino); 168 + hfs_dbg("ino %lu\n", inode->i_ino); 182 169 truncate_inode_pages_final(&inode->i_data); 183 170 clear_inode(inode); 184 171 if (HFSPLUS_IS_RSRC(inode)) { ··· 197 184 if (!wait) 198 185 return 0; 199 186 200 - hfs_dbg(SUPER, "hfsplus_sync_fs\n"); 187 + hfs_dbg("starting...\n"); 201 188 202 189 /* 203 190 * Explicitly write out the special metadata inodes. ··· 228 215 vhdr->folder_count = cpu_to_be32(sbi->folder_count); 229 216 vhdr->file_count = cpu_to_be32(sbi->file_count); 230 217 218 + hfs_dbg("free_blocks %u, next_cnid %u, folder_count %u, file_count %u\n", 219 + sbi->free_blocks, sbi->next_cnid, 220 + sbi->folder_count, sbi->file_count); 221 + 231 222 if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) { 232 223 memcpy(sbi->s_backup_vhdr, sbi->s_vhdr, sizeof(*sbi->s_vhdr)); 233 224 write_backup = 1; ··· 256 239 257 240 if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) 258 241 blkdev_issue_flush(sb->s_bdev); 242 + 243 + hfs_dbg("finished: err %d\n", error); 259 244 260 245 return error; 261 246 } ··· 307 288 { 308 289 struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); 309 290 310 - hfs_dbg(SUPER, "hfsplus_put_super\n"); 291 + hfs_dbg("starting...\n"); 311 292 312 293 cancel_delayed_work_sync(&sbi->sync_work); 313 294 ··· 329 310 kfree(sbi->s_vhdr_buf); 330 311 kfree(sbi->s_backup_vhdr_buf); 331 312 call_rcu(&sbi->rcu, delayed_free); 313 + 314 + hfs_dbg("finished\n"); 332 315 } 333 316 334 317 static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) ··· 545 524 if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { 546 525 hfs_find_exit(&fd); 547 526 if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) { 548 - err = -EINVAL; 527 + err = -EIO; 549 528 goto out_put_root; 550 529 } 551 530 inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id));
+43 -5
fs/hfsplus/unicode.c
··· 40 40 p1 = s1->unicode; 41 41 p2 = s2->unicode; 42 42 43 + if (len1 > HFSPLUS_MAX_STRLEN) { 44 + len1 = HFSPLUS_MAX_STRLEN; 45 + pr_err("invalid length %u has been corrected to %d\n", 46 + be16_to_cpu(s1->length), len1); 47 + } 48 + 49 + if (len2 > HFSPLUS_MAX_STRLEN) { 50 + len2 = HFSPLUS_MAX_STRLEN; 51 + pr_err("invalid length %u has been corrected to %d\n", 52 + be16_to_cpu(s2->length), len2); 53 + } 54 + 43 55 while (1) { 44 56 c1 = c2 = 0; 45 57 ··· 85 73 len2 = be16_to_cpu(s2->length); 86 74 p1 = s1->unicode; 87 75 p2 = s2->unicode; 76 + 77 + if (len1 > HFSPLUS_MAX_STRLEN) { 78 + len1 = HFSPLUS_MAX_STRLEN; 79 + pr_err("invalid length %u has been corrected to %d\n", 80 + be16_to_cpu(s1->length), len1); 81 + } 82 + 83 + if (len2 > HFSPLUS_MAX_STRLEN) { 84 + len2 = HFSPLUS_MAX_STRLEN; 85 + pr_err("invalid length %u has been corrected to %d\n", 86 + be16_to_cpu(s2->length), len2); 87 + } 88 88 89 89 for (len = min(len1, len2); len > 0; len--) { 90 90 c1 = be16_to_cpu(*p1); ··· 143 119 return NULL; 144 120 } 145 121 146 - int hfsplus_uni2asc(struct super_block *sb, 147 - const struct hfsplus_unistr *ustr, 148 - char *astr, int *len_p) 122 + static int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, 123 + int max_len, char *astr, int *len_p) 149 124 { 150 125 const hfsplus_unichr *ip; 151 126 struct nls_table *nls = HFSPLUS_SB(sb)->nls; ··· 157 134 ip = ustr->unicode; 158 135 159 136 ustrlen = be16_to_cpu(ustr->length); 160 - if (ustrlen > HFSPLUS_MAX_STRLEN) { 161 - ustrlen = HFSPLUS_MAX_STRLEN; 137 + if (ustrlen > max_len) { 138 + ustrlen = max_len; 162 139 pr_err("invalid length %u has been corrected to %d\n", 163 140 be16_to_cpu(ustr->length), ustrlen); 164 141 } ··· 277 254 out: 278 255 *len_p = (char *)op - astr; 279 256 return res; 257 + } 258 + 259 + inline int hfsplus_uni2asc_str(struct super_block *sb, 260 + const struct hfsplus_unistr *ustr, char *astr, 261 + int *len_p) 262 + { 263 + return hfsplus_uni2asc(sb, ustr, HFSPLUS_MAX_STRLEN, astr, len_p); 264 + } 265 + 266 + inline int hfsplus_uni2asc_xattr_str(struct super_block *sb, 267 + const struct hfsplus_attr_unistr *ustr, 268 + char *astr, int *len_p) 269 + { 270 + return hfsplus_uni2asc(sb, (const struct hfsplus_unistr *)ustr, 271 + HFSPLUS_ATTR_MAX_STRLEN, astr, len_p); 280 272 } 281 273 282 274 /*
+5 -5
fs/hfsplus/xattr.c
··· 64 64 u32 used_bmp_bytes; 65 65 u64 tmp; 66 66 67 - hfs_dbg(ATTR_MOD, "init_hdr_attr_file: clump %u, node_size %u\n", 67 + hfs_dbg("clump %u, node_size %u\n", 68 68 clump_size, node_size); 69 69 70 70 /* The end of the node contains list of record offsets */ ··· 132 132 struct page *page; 133 133 int old_state = HFSPLUS_EMPTY_ATTR_TREE; 134 134 135 - hfs_dbg(ATTR_MOD, "create_attr_file: ino %d\n", HFSPLUS_ATTR_CNID); 135 + hfs_dbg("ino %d\n", HFSPLUS_ATTR_CNID); 136 136 137 137 check_attr_tree_state_again: 138 138 switch (atomic_read(&sbi->attr_tree_state)) { ··· 735 735 goto end_listxattr; 736 736 737 737 xattr_name_len = NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN; 738 - if (hfsplus_uni2asc(inode->i_sb, 739 - (const struct hfsplus_unistr *)&fd.key->attr.key_name, 740 - strbuf, &xattr_name_len)) { 738 + if (hfsplus_uni2asc_xattr_str(inode->i_sb, 739 + &fd.key->attr.key_name, strbuf, 740 + &xattr_name_len)) { 741 741 pr_err("unicode conversion failed\n"); 742 742 res = -EIO; 743 743 goto end_listxattr;
+20
include/linux/hfs_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * HFS/HFS+ common definitions, inline functions, 4 + * and shared functionality. 5 + */ 6 + 7 + #ifndef _HFS_COMMON_H_ 8 + #define _HFS_COMMON_H_ 9 + 10 + #ifdef pr_fmt 11 + #undef pr_fmt 12 + #endif 13 + 14 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 + 16 + #define hfs_dbg(fmt, ...) \ 17 + pr_debug("pid %d:%s:%d %s(): " fmt, \ 18 + current->pid, __FILE__, __LINE__, __func__, ##__VA_ARGS__) \ 19 + 20 + #endif /* _HFS_COMMON_H_ */