diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 15:09:13 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 15:09:13 -0400 |
| commit | df34d04a6f09ba41037e58c3df6d6fbed0ffcde9 (patch) | |
| tree | 13c81a36713fafc7abd74cb337860a1feb279968 /fs | |
| parent | 9ffc66941df278c9f4df979b6bcf6c6ddafedd16 (diff) | |
| parent | a17e7d2010b44103e3b8e00d0c8c510606457bc6 (diff) | |
Merge tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs
Pull befs fixes from Luis de Bethencourt:
"I recently took maintainership of the befs file system [0]. This is
the first time I send you a git pull request, so please let me know if
all the below is OK.
Salah Triki and myself have been cleaning the code and fixing a few
small bugs.
Sorry I couldn't send this sooner in the merge window, I was waiting
to have my GPG key signed by kernel members at ELCE in Berlin a few
days ago."
[0] https://lkml.org/lkml/2016/7/27/502
* tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs: (39 commits)
befs: befs: fix style issues in datastream.c
befs: improve documentation in datastream.c
befs: fix typos in datastream.c
befs: fix typos in btree.c
befs: fix style issues in super.c
befs: fix comment style
befs: add check for ag_shift in superblock
befs: dump inode_size superblock information
befs: remove unnecessary initialization
befs: fix typo in befs_sb_info
befs: add flags field to validate superblock state
befs: fix typo in befs_find_key
befs: remove unused BEFS_BT_PARMATCH
fs: befs: remove ret variable
fs: befs: remove in vain variable assignment
fs: befs: remove unnecessary *befs_sb variable
fs: befs: remove useless initialization to zero
fs: befs: remove in vain variable assignment
fs: befs: Insert NULL inode to dentry
fs: befs: Remove useless calls to brelse in befs_find_brun_dblindirect
...
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/befs/befs.h | 19 | ||||
| -rw-r--r-- | fs/befs/btree.c | 60 | ||||
| -rw-r--r-- | fs/befs/datastream.c | 253 | ||||
| -rw-r--r-- | fs/befs/debug.c | 1 | ||||
| -rw-r--r-- | fs/befs/io.c | 26 | ||||
| -rw-r--r-- | fs/befs/io.h | 2 | ||||
| -rw-r--r-- | fs/befs/linuxvfs.c | 130 | ||||
| -rw-r--r-- | fs/befs/super.c | 36 |
8 files changed, 244 insertions, 283 deletions
diff --git a/fs/befs/befs.h b/fs/befs/befs.h index e0f59263a96d..c6bad51d8ec7 100644 --- a/fs/befs/befs.h +++ b/fs/befs/befs.h | |||
| @@ -43,7 +43,10 @@ struct befs_sb_info { | |||
| 43 | u32 ag_shift; | 43 | u32 ag_shift; |
| 44 | u32 num_ags; | 44 | u32 num_ags; |
| 45 | 45 | ||
| 46 | /* jornal log entry */ | 46 | /* State of the superblock */ |
| 47 | u32 flags; | ||
| 48 | |||
| 49 | /* Journal log entry */ | ||
| 47 | befs_block_run log_blocks; | 50 | befs_block_run log_blocks; |
| 48 | befs_off_t log_start; | 51 | befs_off_t log_start; |
| 49 | befs_off_t log_end; | 52 | befs_off_t log_end; |
| @@ -79,7 +82,7 @@ enum befs_err { | |||
| 79 | BEFS_BT_END, | 82 | BEFS_BT_END, |
| 80 | BEFS_BT_EMPTY, | 83 | BEFS_BT_EMPTY, |
| 81 | BEFS_BT_MATCH, | 84 | BEFS_BT_MATCH, |
| 82 | BEFS_BT_PARMATCH, | 85 | BEFS_BT_OVERFLOW, |
| 83 | BEFS_BT_NOT_FOUND | 86 | BEFS_BT_NOT_FOUND |
| 84 | }; | 87 | }; |
| 85 | 88 | ||
| @@ -140,18 +143,6 @@ befs_iaddrs_per_block(struct super_block *sb) | |||
| 140 | return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr); | 143 | return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr); |
| 141 | } | 144 | } |
| 142 | 145 | ||
| 143 | static inline int | ||
| 144 | befs_iaddr_is_empty(const befs_inode_addr *iaddr) | ||
| 145 | { | ||
| 146 | return (!iaddr->allocation_group) && (!iaddr->start) && (!iaddr->len); | ||
| 147 | } | ||
| 148 | |||
| 149 | static inline size_t | ||
| 150 | befs_brun_size(struct super_block *sb, befs_block_run run) | ||
| 151 | { | ||
| 152 | return BEFS_SB(sb)->block_size * run.len; | ||
| 153 | } | ||
| 154 | |||
| 155 | #include "endian.h" | 146 | #include "endian.h" |
| 156 | 147 | ||
| 157 | #endif /* _LINUX_BEFS_H */ | 148 | #endif /* _LINUX_BEFS_H */ |
diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 307645f9e284..7e135ea73fdd 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c | |||
| @@ -85,7 +85,7 @@ struct befs_btree_node { | |||
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | /* local constants */ | 87 | /* local constants */ |
| 88 | static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; | 88 | static const befs_off_t BEFS_BT_INVAL = 0xffffffffffffffffULL; |
| 89 | 89 | ||
| 90 | /* local functions */ | 90 | /* local functions */ |
| 91 | static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds, | 91 | static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds, |
| @@ -156,8 +156,6 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds, | |||
| 156 | sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth); | 156 | sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth); |
| 157 | sup->data_type = fs32_to_cpu(sb, od_sup->data_type); | 157 | sup->data_type = fs32_to_cpu(sb, od_sup->data_type); |
| 158 | sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr); | 158 | sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr); |
| 159 | sup->free_node_ptr = fs64_to_cpu(sb, od_sup->free_node_ptr); | ||
| 160 | sup->max_size = fs64_to_cpu(sb, od_sup->max_size); | ||
| 161 | 159 | ||
| 162 | brelse(bh); | 160 | brelse(bh); |
| 163 | if (sup->magic != BEFS_BTREE_MAGIC) { | 161 | if (sup->magic != BEFS_BTREE_MAGIC) { |
| @@ -183,8 +181,8 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds, | |||
| 183 | * Calls befs_read_datastream to read in the indicated btree node and | 181 | * Calls befs_read_datastream to read in the indicated btree node and |
| 184 | * makes sure its header fields are in cpu byteorder, byteswapping if | 182 | * makes sure its header fields are in cpu byteorder, byteswapping if |
| 185 | * necessary. | 183 | * necessary. |
| 186 | * Note: node->bh must be NULL when this function called first | 184 | * Note: node->bh must be NULL when this function is called the first time. |
| 187 | * time. Don't forget brelse(node->bh) after last call. | 185 | * Don't forget brelse(node->bh) after last call. |
| 188 | * | 186 | * |
| 189 | * On success, returns BEFS_OK and *@node contains the btree node that | 187 | * On success, returns BEFS_OK and *@node contains the btree node that |
| 190 | * starts at @node_off, with the node->head fields in cpu byte order. | 188 | * starts at @node_off, with the node->head fields in cpu byte order. |
| @@ -244,7 +242,7 @@ befs_bt_read_node(struct super_block *sb, const befs_data_stream *ds, | |||
| 244 | * Read the superblock and rootnode of the b+tree. | 242 | * Read the superblock and rootnode of the b+tree. |
| 245 | * Drill down through the interior nodes using befs_find_key(). | 243 | * Drill down through the interior nodes using befs_find_key(). |
| 246 | * Once at the correct leaf node, use befs_find_key() again to get the | 244 | * Once at the correct leaf node, use befs_find_key() again to get the |
| 247 | * actuall value stored with the key. | 245 | * actual value stored with the key. |
| 248 | */ | 246 | */ |
| 249 | int | 247 | int |
| 250 | befs_btree_find(struct super_block *sb, const befs_data_stream *ds, | 248 | befs_btree_find(struct super_block *sb, const befs_data_stream *ds, |
| @@ -283,9 +281,9 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, | |||
| 283 | 281 | ||
| 284 | while (!befs_leafnode(this_node)) { | 282 | while (!befs_leafnode(this_node)) { |
| 285 | res = befs_find_key(sb, this_node, key, &node_off); | 283 | res = befs_find_key(sb, this_node, key, &node_off); |
| 286 | if (res == BEFS_BT_NOT_FOUND) | 284 | /* if no key set, try the overflow node */ |
| 285 | if (res == BEFS_BT_OVERFLOW) | ||
| 287 | node_off = this_node->head.overflow; | 286 | node_off = this_node->head.overflow; |
| 288 | /* if no match, go to overflow node */ | ||
| 289 | if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) { | 287 | if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) { |
| 290 | befs_error(sb, "befs_btree_find() failed to read " | 288 | befs_error(sb, "befs_btree_find() failed to read " |
| 291 | "node at %llu", node_off); | 289 | "node at %llu", node_off); |
| @@ -293,15 +291,15 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, | |||
| 293 | } | 291 | } |
| 294 | } | 292 | } |
| 295 | 293 | ||
| 296 | /* at the correct leaf node now */ | 294 | /* at a leaf node now, check if it is correct */ |
| 297 | |||
| 298 | res = befs_find_key(sb, this_node, key, value); | 295 | res = befs_find_key(sb, this_node, key, value); |
| 299 | 296 | ||
| 300 | brelse(this_node->bh); | 297 | brelse(this_node->bh); |
| 301 | kfree(this_node); | 298 | kfree(this_node); |
| 302 | 299 | ||
| 303 | if (res != BEFS_BT_MATCH) { | 300 | if (res != BEFS_BT_MATCH) { |
| 304 | befs_debug(sb, "<--- %s Key %s not found", __func__, key); | 301 | befs_error(sb, "<--- %s Key %s not found", __func__, key); |
| 302 | befs_debug(sb, "<--- %s ERROR", __func__); | ||
| 305 | *value = 0; | 303 | *value = 0; |
| 306 | return BEFS_BT_NOT_FOUND; | 304 | return BEFS_BT_NOT_FOUND; |
| 307 | } | 305 | } |
| @@ -324,16 +322,12 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, | |||
| 324 | * @findkey: Keystring to search for | 322 | * @findkey: Keystring to search for |
| 325 | * @value: If key is found, the value stored with the key is put here | 323 | * @value: If key is found, the value stored with the key is put here |
| 326 | * | 324 | * |
| 327 | * finds exact match if one exists, and returns BEFS_BT_MATCH | 325 | * Finds exact match if one exists, and returns BEFS_BT_MATCH. |
| 328 | * If no exact match, finds first key in node that is greater | 326 | * If there is no match and node's value array is too small for key, return |
| 329 | * (alphabetically) than the search key and returns BEFS_BT_PARMATCH | 327 | * BEFS_BT_OVERFLOW. |
| 330 | * (for partial match, I guess). Can you think of something better to | 328 | * If no match and node should countain this key, return BEFS_BT_NOT_FOUND. |
| 331 | * call it? | ||
| 332 | * | ||
| 333 | * If no key was a match or greater than the search key, return | ||
| 334 | * BEFS_BT_NOT_FOUND. | ||
| 335 | * | 329 | * |
| 336 | * Use binary search instead of a linear. | 330 | * Uses binary search instead of a linear. |
| 337 | */ | 331 | */ |
| 338 | static int | 332 | static int |
| 339 | befs_find_key(struct super_block *sb, struct befs_btree_node *node, | 333 | befs_find_key(struct super_block *sb, struct befs_btree_node *node, |
| @@ -348,18 +342,16 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, | |||
| 348 | 342 | ||
| 349 | befs_debug(sb, "---> %s %s", __func__, findkey); | 343 | befs_debug(sb, "---> %s %s", __func__, findkey); |
| 350 | 344 | ||
| 351 | *value = 0; | ||
| 352 | |||
| 353 | findkey_len = strlen(findkey); | 345 | findkey_len = strlen(findkey); |
| 354 | 346 | ||
| 355 | /* if node can not contain key, just skeep this node */ | 347 | /* if node can not contain key, just skip this node */ |
| 356 | last = node->head.all_key_count - 1; | 348 | last = node->head.all_key_count - 1; |
| 357 | thiskey = befs_bt_get_key(sb, node, last, &keylen); | 349 | thiskey = befs_bt_get_key(sb, node, last, &keylen); |
| 358 | 350 | ||
| 359 | eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len); | 351 | eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len); |
| 360 | if (eq < 0) { | 352 | if (eq < 0) { |
| 361 | befs_debug(sb, "<--- %s %s not found", __func__, findkey); | 353 | befs_debug(sb, "<--- node can't contain %s", findkey); |
| 362 | return BEFS_BT_NOT_FOUND; | 354 | return BEFS_BT_OVERFLOW; |
| 363 | } | 355 | } |
| 364 | 356 | ||
| 365 | valarray = befs_bt_valarray(node); | 357 | valarray = befs_bt_valarray(node); |
| @@ -387,12 +379,15 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, | |||
| 387 | else | 379 | else |
| 388 | first = mid + 1; | 380 | first = mid + 1; |
| 389 | } | 381 | } |
| 382 | |||
| 383 | /* return an existing value so caller can arrive to a leaf node */ | ||
| 390 | if (eq < 0) | 384 | if (eq < 0) |
| 391 | *value = fs64_to_cpu(sb, valarray[mid + 1]); | 385 | *value = fs64_to_cpu(sb, valarray[mid + 1]); |
| 392 | else | 386 | else |
| 393 | *value = fs64_to_cpu(sb, valarray[mid]); | 387 | *value = fs64_to_cpu(sb, valarray[mid]); |
| 394 | befs_debug(sb, "<--- %s found %s at %d", __func__, thiskey, mid); | 388 | befs_error(sb, "<--- %s %s not found", __func__, findkey); |
| 395 | return BEFS_BT_PARMATCH; | 389 | befs_debug(sb, "<--- %s ERROR", __func__); |
| 390 | return BEFS_BT_NOT_FOUND; | ||
| 396 | } | 391 | } |
| 397 | 392 | ||
| 398 | /** | 393 | /** |
| @@ -405,7 +400,7 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node, | |||
| 405 | * @keysize: Length of the returned key | 400 | * @keysize: Length of the returned key |
| 406 | * @value: Value stored with the returned key | 401 | * @value: Value stored with the returned key |
| 407 | * | 402 | * |
| 408 | * Heres how it works: Key_no is the index of the key/value pair to | 403 | * Here's how it works: Key_no is the index of the key/value pair to |
| 409 | * return in keybuf/value. | 404 | * return in keybuf/value. |
| 410 | * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is | 405 | * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is |
| 411 | * the number of characters in the key (just a convenience). | 406 | * the number of characters in the key (just a convenience). |
| @@ -422,7 +417,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, | |||
| 422 | { | 417 | { |
| 423 | struct befs_btree_node *this_node; | 418 | struct befs_btree_node *this_node; |
| 424 | befs_btree_super bt_super; | 419 | befs_btree_super bt_super; |
| 425 | befs_off_t node_off = 0; | 420 | befs_off_t node_off; |
| 426 | int cur_key; | 421 | int cur_key; |
| 427 | fs64 *valarray; | 422 | fs64 *valarray; |
| 428 | char *keystart; | 423 | char *keystart; |
| @@ -467,7 +462,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, | |||
| 467 | while (key_sum + this_node->head.all_key_count <= key_no) { | 462 | while (key_sum + this_node->head.all_key_count <= key_no) { |
| 468 | 463 | ||
| 469 | /* no more nodes to look in: key_no is too large */ | 464 | /* no more nodes to look in: key_no is too large */ |
| 470 | if (this_node->head.right == befs_bt_inval) { | 465 | if (this_node->head.right == BEFS_BT_INVAL) { |
| 471 | *keysize = 0; | 466 | *keysize = 0; |
| 472 | *value = 0; | 467 | *value = 0; |
| 473 | befs_debug(sb, | 468 | befs_debug(sb, |
| @@ -541,7 +536,6 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, | |||
| 541 | * @node_off: Pointer to offset of current node within datastream. Modified | 536 | * @node_off: Pointer to offset of current node within datastream. Modified |
| 542 | * by the function. | 537 | * by the function. |
| 543 | * | 538 | * |
| 544 | * | ||
| 545 | * Helper function for btree traverse. Moves the current position to the | 539 | * Helper function for btree traverse. Moves the current position to the |
| 546 | * start of the first leaf node. | 540 | * start of the first leaf node. |
| 547 | * | 541 | * |
| @@ -608,7 +602,7 @@ static int | |||
| 608 | befs_leafnode(struct befs_btree_node *node) | 602 | befs_leafnode(struct befs_btree_node *node) |
| 609 | { | 603 | { |
| 610 | /* all interior nodes (and only interior nodes) have an overflow node */ | 604 | /* all interior nodes (and only interior nodes) have an overflow node */ |
| 611 | if (node->head.overflow == befs_bt_inval) | 605 | if (node->head.overflow == BEFS_BT_INVAL) |
| 612 | return 1; | 606 | return 1; |
| 613 | else | 607 | else |
| 614 | return 0; | 608 | return 0; |
| @@ -715,7 +709,7 @@ befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node, | |||
| 715 | * | 709 | * |
| 716 | * Returns 0 if @key1 and @key2 are equal. | 710 | * Returns 0 if @key1 and @key2 are equal. |
| 717 | * Returns >0 if @key1 is greater. | 711 | * Returns >0 if @key1 is greater. |
| 718 | * Returns <0 if @key2 is greater.. | 712 | * Returns <0 if @key2 is greater. |
| 719 | */ | 713 | */ |
| 720 | static int | 714 | static int |
| 721 | befs_compare_strings(const void *key1, int keylen1, | 715 | befs_compare_strings(const void *key1, int keylen1, |
diff --git a/fs/befs/datastream.c b/fs/befs/datastream.c index af1bc19b7c85..b4c7ba013c0d 100644 --- a/fs/befs/datastream.c +++ b/fs/befs/datastream.c | |||
| @@ -22,22 +22,22 @@ const befs_inode_addr BAD_IADDR = { 0, 0, 0 }; | |||
| 22 | 22 | ||
| 23 | static int befs_find_brun_direct(struct super_block *sb, | 23 | static int befs_find_brun_direct(struct super_block *sb, |
| 24 | const befs_data_stream *data, | 24 | const befs_data_stream *data, |
| 25 | befs_blocknr_t blockno, befs_block_run * run); | 25 | befs_blocknr_t blockno, befs_block_run *run); |
| 26 | 26 | ||
| 27 | static int befs_find_brun_indirect(struct super_block *sb, | 27 | static int befs_find_brun_indirect(struct super_block *sb, |
| 28 | const befs_data_stream *data, | 28 | const befs_data_stream *data, |
| 29 | befs_blocknr_t blockno, | 29 | befs_blocknr_t blockno, |
| 30 | befs_block_run * run); | 30 | befs_block_run *run); |
| 31 | 31 | ||
| 32 | static int befs_find_brun_dblindirect(struct super_block *sb, | 32 | static int befs_find_brun_dblindirect(struct super_block *sb, |
| 33 | const befs_data_stream *data, | 33 | const befs_data_stream *data, |
| 34 | befs_blocknr_t blockno, | 34 | befs_blocknr_t blockno, |
| 35 | befs_block_run * run); | 35 | befs_block_run *run); |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * befs_read_datastream - get buffer_head containing data, starting from pos. | 38 | * befs_read_datastream - get buffer_head containing data, starting from pos. |
| 39 | * @sb: Filesystem superblock | 39 | * @sb: Filesystem superblock |
| 40 | * @ds: datastrem to find data with | 40 | * @ds: datastream to find data with |
| 41 | * @pos: start of data | 41 | * @pos: start of data |
| 42 | * @off: offset of data in buffer_head->b_data | 42 | * @off: offset of data in buffer_head->b_data |
| 43 | * | 43 | * |
| @@ -46,7 +46,7 @@ static int befs_find_brun_dblindirect(struct super_block *sb, | |||
| 46 | */ | 46 | */ |
| 47 | struct buffer_head * | 47 | struct buffer_head * |
| 48 | befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, | 48 | befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, |
| 49 | befs_off_t pos, uint * off) | 49 | befs_off_t pos, uint *off) |
| 50 | { | 50 | { |
| 51 | struct buffer_head *bh; | 51 | struct buffer_head *bh; |
| 52 | befs_block_run run; | 52 | befs_block_run run; |
| @@ -75,7 +75,13 @@ befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, | |||
| 75 | return bh; | 75 | return bh; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /* | 78 | /** |
| 79 | * befs_fblock2brun - give back block run for fblock | ||
| 80 | * @sb: the superblock | ||
| 81 | * @data: datastream to read from | ||
| 82 | * @fblock: the blocknumber with the file position to find | ||
| 83 | * @run: The found run is passed back through this pointer | ||
| 84 | * | ||
| 79 | * Takes a file position and gives back a brun who's starting block | 85 | * Takes a file position and gives back a brun who's starting block |
| 80 | * is block number fblock of the file. | 86 | * is block number fblock of the file. |
| 81 | * | 87 | * |
| @@ -88,7 +94,7 @@ befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, | |||
| 88 | */ | 94 | */ |
| 89 | int | 95 | int |
| 90 | befs_fblock2brun(struct super_block *sb, const befs_data_stream *data, | 96 | befs_fblock2brun(struct super_block *sb, const befs_data_stream *data, |
| 91 | befs_blocknr_t fblock, befs_block_run * run) | 97 | befs_blocknr_t fblock, befs_block_run *run) |
| 92 | { | 98 | { |
| 93 | int err; | 99 | int err; |
| 94 | befs_off_t pos = fblock << BEFS_SB(sb)->block_shift; | 100 | befs_off_t pos = fblock << BEFS_SB(sb)->block_shift; |
| @@ -115,7 +121,7 @@ befs_fblock2brun(struct super_block *sb, const befs_data_stream *data, | |||
| 115 | /** | 121 | /** |
| 116 | * befs_read_lsmylink - read long symlink from datastream. | 122 | * befs_read_lsmylink - read long symlink from datastream. |
| 117 | * @sb: Filesystem superblock | 123 | * @sb: Filesystem superblock |
| 118 | * @ds: Datastrem to read from | 124 | * @ds: Datastream to read from |
| 119 | * @buff: Buffer in which to place long symlink data | 125 | * @buff: Buffer in which to place long symlink data |
| 120 | * @len: Length of the long symlink in bytes | 126 | * @len: Length of the long symlink in bytes |
| 121 | * | 127 | * |
| @@ -128,6 +134,7 @@ befs_read_lsymlink(struct super_block *sb, const befs_data_stream *ds, | |||
| 128 | befs_off_t bytes_read = 0; /* bytes readed */ | 134 | befs_off_t bytes_read = 0; /* bytes readed */ |
| 129 | u16 plen; | 135 | u16 plen; |
| 130 | struct buffer_head *bh; | 136 | struct buffer_head *bh; |
| 137 | |||
| 131 | befs_debug(sb, "---> %s length: %llu", __func__, len); | 138 | befs_debug(sb, "---> %s length: %llu", __func__, len); |
| 132 | 139 | ||
| 133 | while (bytes_read < len) { | 140 | while (bytes_read < len) { |
| @@ -183,13 +190,13 @@ befs_count_blocks(struct super_block *sb, const befs_data_stream *ds) | |||
| 183 | metablocks += ds->indirect.len; | 190 | metablocks += ds->indirect.len; |
| 184 | 191 | ||
| 185 | /* | 192 | /* |
| 186 | Double indir block, plus all the indirect blocks it mapps | 193 | * Double indir block, plus all the indirect blocks it maps. |
| 187 | In the double-indirect range, all block runs of data are | 194 | * In the double-indirect range, all block runs of data are |
| 188 | BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know | 195 | * BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know |
| 189 | how many data block runs are in the double-indirect region, | 196 | * how many data block runs are in the double-indirect region, |
| 190 | and from that we know how many indirect blocks it takes to | 197 | * and from that we know how many indirect blocks it takes to |
| 191 | map them. We assume that the indirect blocks are also | 198 | * map them. We assume that the indirect blocks are also |
| 192 | BEFS_DBLINDIR_BRUN_LEN blocks long. | 199 | * BEFS_DBLINDIR_BRUN_LEN blocks long. |
| 193 | */ | 200 | */ |
| 194 | if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) { | 201 | if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) { |
| 195 | uint dbl_bytes; | 202 | uint dbl_bytes; |
| @@ -212,58 +219,50 @@ befs_count_blocks(struct super_block *sb, const befs_data_stream *ds) | |||
| 212 | return blocks; | 219 | return blocks; |
| 213 | } | 220 | } |
| 214 | 221 | ||
| 215 | /* | 222 | /** |
| 216 | Finds the block run that starts at file block number blockno | 223 | * befs_find_brun_direct - find a direct block run in the datastream |
| 217 | in the file represented by the datastream data, if that | 224 | * @sb: the superblock |
| 218 | blockno is in the direct region of the datastream. | 225 | * @data: the datastream |
| 219 | 226 | * @blockno: the blocknumber to find | |
| 220 | sb: the superblock | 227 | * @run: The found run is passed back through this pointer |
| 221 | data: the datastream | 228 | * |
| 222 | blockno: the blocknumber to find | 229 | * Finds the block run that starts at file block number blockno |
| 223 | run: The found run is passed back through this pointer | 230 | * in the file represented by the datastream data, if that |
| 224 | 231 | * blockno is in the direct region of the datastream. | |
| 225 | Return value is BEFS_OK if the blockrun is found, BEFS_ERR | 232 | * |
| 226 | otherwise. | 233 | * Return value is BEFS_OK if the blockrun is found, BEFS_ERR |
| 227 | 234 | * otherwise. | |
| 228 | Algorithm: | 235 | * |
| 229 | Linear search. Checks each element of array[] to see if it | 236 | * Algorithm: |
| 230 | contains the blockno-th filesystem block. This is necessary | 237 | * Linear search. Checks each element of array[] to see if it |
| 231 | because the block runs map variable amounts of data. Simply | 238 | * contains the blockno-th filesystem block. This is necessary |
| 232 | keeps a count of the number of blocks searched so far (sum), | 239 | * because the block runs map variable amounts of data. Simply |
| 233 | incrementing this by the length of each block run as we come | 240 | * keeps a count of the number of blocks searched so far (sum), |
| 234 | across it. Adds sum to *count before returning (this is so | 241 | * incrementing this by the length of each block run as we come |
| 235 | you can search multiple arrays that are logicaly one array, | 242 | * across it. Adds sum to *count before returning (this is so |
| 236 | as in the indirect region code). | 243 | * you can search multiple arrays that are logicaly one array, |
| 237 | 244 | * as in the indirect region code). | |
| 238 | When/if blockno is found, if blockno is inside of a block | 245 | * |
| 239 | run as stored on disk, we offset the start and length members | 246 | * When/if blockno is found, if blockno is inside of a block |
| 240 | of the block run, so that blockno is the start and len is | 247 | * run as stored on disk, we offset the start and length members |
| 241 | still valid (the run ends in the same place). | 248 | * of the block run, so that blockno is the start and len is |
| 242 | 249 | * still valid (the run ends in the same place). | |
| 243 | 2001-11-15 Will Dyson | 250 | */ |
| 244 | */ | ||
| 245 | static int | 251 | static int |
| 246 | befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data, | 252 | befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data, |
| 247 | befs_blocknr_t blockno, befs_block_run * run) | 253 | befs_blocknr_t blockno, befs_block_run *run) |
| 248 | { | 254 | { |
| 249 | int i; | 255 | int i; |
| 250 | const befs_block_run *array = data->direct; | 256 | const befs_block_run *array = data->direct; |
| 251 | befs_blocknr_t sum; | 257 | befs_blocknr_t sum; |
| 252 | befs_blocknr_t max_block = | ||
| 253 | data->max_direct_range >> BEFS_SB(sb)->block_shift; | ||
| 254 | 258 | ||
| 255 | befs_debug(sb, "---> %s, find %lu", __func__, (unsigned long)blockno); | 259 | befs_debug(sb, "---> %s, find %lu", __func__, (unsigned long)blockno); |
| 256 | 260 | ||
| 257 | if (blockno > max_block) { | ||
| 258 | befs_error(sb, "%s passed block outside of direct region", | ||
| 259 | __func__); | ||
| 260 | return BEFS_ERR; | ||
| 261 | } | ||
| 262 | |||
| 263 | for (i = 0, sum = 0; i < BEFS_NUM_DIRECT_BLOCKS; | 261 | for (i = 0, sum = 0; i < BEFS_NUM_DIRECT_BLOCKS; |
| 264 | sum += array[i].len, i++) { | 262 | sum += array[i].len, i++) { |
| 265 | if (blockno >= sum && blockno < sum + (array[i].len)) { | 263 | if (blockno >= sum && blockno < sum + (array[i].len)) { |
| 266 | int offset = blockno - sum; | 264 | int offset = blockno - sum; |
| 265 | |||
| 267 | run->allocation_group = array[i].allocation_group; | 266 | run->allocation_group = array[i].allocation_group; |
| 268 | run->start = array[i].start + offset; | 267 | run->start = array[i].start + offset; |
| 269 | run->len = array[i].len - offset; | 268 | run->len = array[i].len - offset; |
| @@ -275,38 +274,39 @@ befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data, | |||
| 275 | } | 274 | } |
| 276 | } | 275 | } |
| 277 | 276 | ||
| 277 | befs_error(sb, "%s failed to find file block %lu", __func__, | ||
| 278 | (unsigned long)blockno); | ||
| 278 | befs_debug(sb, "---> %s ERROR", __func__); | 279 | befs_debug(sb, "---> %s ERROR", __func__); |
| 279 | return BEFS_ERR; | 280 | return BEFS_ERR; |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | /* | 283 | /** |
| 283 | Finds the block run that starts at file block number blockno | 284 | * befs_find_brun_indirect - find a block run in the datastream |
| 284 | in the file represented by the datastream data, if that | 285 | * @sb: the superblock |
| 285 | blockno is in the indirect region of the datastream. | 286 | * @data: the datastream |
| 286 | 287 | * @blockno: the blocknumber to find | |
| 287 | sb: the superblock | 288 | * @run: The found run is passed back through this pointer |
| 288 | data: the datastream | 289 | * |
| 289 | blockno: the blocknumber to find | 290 | * Finds the block run that starts at file block number blockno |
| 290 | run: The found run is passed back through this pointer | 291 | * in the file represented by the datastream data, if that |
| 291 | 292 | * blockno is in the indirect region of the datastream. | |
| 292 | Return value is BEFS_OK if the blockrun is found, BEFS_ERR | 293 | * |
| 293 | otherwise. | 294 | * Return value is BEFS_OK if the blockrun is found, BEFS_ERR |
| 294 | 295 | * otherwise. | |
| 295 | Algorithm: | 296 | * |
| 296 | For each block in the indirect run of the datastream, read | 297 | * Algorithm: |
| 297 | it in and search through it for search_blk. | 298 | * For each block in the indirect run of the datastream, read |
| 298 | 299 | * it in and search through it for search_blk. | |
| 299 | XXX: | 300 | * |
| 300 | Really should check to make sure blockno is inside indirect | 301 | * XXX: |
| 301 | region. | 302 | * Really should check to make sure blockno is inside indirect |
| 302 | 303 | * region. | |
| 303 | 2001-11-15 Will Dyson | 304 | */ |
| 304 | */ | ||
| 305 | static int | 305 | static int |
| 306 | befs_find_brun_indirect(struct super_block *sb, | 306 | befs_find_brun_indirect(struct super_block *sb, |
| 307 | const befs_data_stream *data, | 307 | const befs_data_stream *data, |
| 308 | befs_blocknr_t blockno, | 308 | befs_blocknr_t blockno, |
| 309 | befs_block_run * run) | 309 | befs_block_run *run) |
| 310 | { | 310 | { |
| 311 | int i, j; | 311 | int i, j; |
| 312 | befs_blocknr_t sum = 0; | 312 | befs_blocknr_t sum = 0; |
| @@ -326,11 +326,12 @@ befs_find_brun_indirect(struct super_block *sb, | |||
| 326 | 326 | ||
| 327 | /* Examine blocks of the indirect run one at a time */ | 327 | /* Examine blocks of the indirect run one at a time */ |
| 328 | for (i = 0; i < indirect.len; i++) { | 328 | for (i = 0; i < indirect.len; i++) { |
| 329 | indirblock = befs_bread(sb, indirblockno + i); | 329 | indirblock = sb_bread(sb, indirblockno + i); |
| 330 | if (indirblock == NULL) { | 330 | if (indirblock == NULL) { |
| 331 | befs_debug(sb, "---> %s failed to read " | 331 | befs_error(sb, "---> %s failed to read " |
| 332 | "disk block %lu from the indirect brun", | 332 | "disk block %lu from the indirect brun", |
| 333 | __func__, (unsigned long)indirblockno + i); | 333 | __func__, (unsigned long)indirblockno + i); |
| 334 | befs_debug(sb, "<--- %s ERROR", __func__); | ||
| 334 | return BEFS_ERR; | 335 | return BEFS_ERR; |
| 335 | } | 336 | } |
| 336 | 337 | ||
| @@ -370,52 +371,51 @@ befs_find_brun_indirect(struct super_block *sb, | |||
| 370 | return BEFS_ERR; | 371 | return BEFS_ERR; |
| 371 | } | 372 | } |
| 372 | 373 | ||
| 373 | /* | 374 | /** |
| 374 | Finds the block run that starts at file block number blockno | 375 | * befs_find_brun_dblindirect - find a block run in the datastream |
| 375 | in the file represented by the datastream data, if that | 376 | * @sb: the superblock |
| 376 | blockno is in the double-indirect region of the datastream. | 377 | * @data: the datastream |
| 377 | 378 | * @blockno: the blocknumber to find | |
| 378 | sb: the superblock | 379 | * @run: The found run is passed back through this pointer |
| 379 | data: the datastream | 380 | * |
| 380 | blockno: the blocknumber to find | 381 | * Finds the block run that starts at file block number blockno |
| 381 | run: The found run is passed back through this pointer | 382 | * in the file represented by the datastream data, if that |
| 382 | 383 | * blockno is in the double-indirect region of the datastream. | |
| 383 | Return value is BEFS_OK if the blockrun is found, BEFS_ERR | 384 | * |
| 384 | otherwise. | 385 | * Return value is BEFS_OK if the blockrun is found, BEFS_ERR |
| 385 | 386 | * otherwise. | |
| 386 | Algorithm: | 387 | * |
| 387 | The block runs in the double-indirect region are different. | 388 | * Algorithm: |
| 388 | They are always allocated 4 fs blocks at a time, so each | 389 | * The block runs in the double-indirect region are different. |
| 389 | block run maps a constant amount of file data. This means | 390 | * They are always allocated 4 fs blocks at a time, so each |
| 390 | that we can directly calculate how many block runs into the | 391 | * block run maps a constant amount of file data. This means |
| 391 | double-indirect region we need to go to get to the one that | 392 | * that we can directly calculate how many block runs into the |
| 392 | maps a particular filesystem block. | 393 | * double-indirect region we need to go to get to the one that |
| 393 | 394 | * maps a particular filesystem block. | |
| 394 | We do this in two stages. First we calculate which of the | 395 | * |
| 395 | inode addresses in the double-indirect block will point us | 396 | * We do this in two stages. First we calculate which of the |
| 396 | to the indirect block that contains the mapping for the data, | 397 | * inode addresses in the double-indirect block will point us |
| 397 | then we calculate which of the inode addresses in that | 398 | * to the indirect block that contains the mapping for the data, |
| 398 | indirect block maps the data block we are after. | 399 | * then we calculate which of the inode addresses in that |
| 399 | 400 | * indirect block maps the data block we are after. | |
| 400 | Oh, and once we've done that, we actually read in the blocks | 401 | * |
| 401 | that contain the inode addresses we calculated above. Even | 402 | * Oh, and once we've done that, we actually read in the blocks |
| 402 | though the double-indirect run may be several blocks long, | 403 | * that contain the inode addresses we calculated above. Even |
| 403 | we can calculate which of those blocks will contain the index | 404 | * though the double-indirect run may be several blocks long, |
| 404 | we are after and only read that one. We then follow it to | 405 | * we can calculate which of those blocks will contain the index |
| 405 | the indirect block and perform a similar process to find | 406 | * we are after and only read that one. We then follow it to |
| 406 | the actual block run that maps the data block we are interested | 407 | * the indirect block and perform a similar process to find |
| 407 | in. | 408 | * the actual block run that maps the data block we are interested |
| 408 | 409 | * in. | |
| 409 | Then we offset the run as in befs_find_brun_array() and we are | 410 | * |
| 410 | done. | 411 | * Then we offset the run as in befs_find_brun_array() and we are |
| 411 | 412 | * done. | |
| 412 | 2001-11-15 Will Dyson | 413 | */ |
| 413 | */ | ||
| 414 | static int | 414 | static int |
| 415 | befs_find_brun_dblindirect(struct super_block *sb, | 415 | befs_find_brun_dblindirect(struct super_block *sb, |
| 416 | const befs_data_stream *data, | 416 | const befs_data_stream *data, |
| 417 | befs_blocknr_t blockno, | 417 | befs_blocknr_t blockno, |
| 418 | befs_block_run * run) | 418 | befs_block_run *run) |
| 419 | { | 419 | { |
| 420 | int dblindir_indx; | 420 | int dblindir_indx; |
| 421 | int indir_indx; | 421 | int indir_indx; |
| @@ -430,10 +430,9 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
| 430 | struct buffer_head *indir_block; | 430 | struct buffer_head *indir_block; |
| 431 | befs_block_run indir_run; | 431 | befs_block_run indir_run; |
| 432 | befs_disk_inode_addr *iaddr_array; | 432 | befs_disk_inode_addr *iaddr_array; |
| 433 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | ||
| 434 | 433 | ||
| 435 | befs_blocknr_t indir_start_blk = | 434 | befs_blocknr_t indir_start_blk = |
| 436 | data->max_indirect_range >> befs_sb->block_shift; | 435 | data->max_indirect_range >> BEFS_SB(sb)->block_shift; |
| 437 | 436 | ||
| 438 | off_t dbl_indir_off = blockno - indir_start_blk; | 437 | off_t dbl_indir_off = blockno - indir_start_blk; |
| 439 | 438 | ||
| @@ -471,7 +470,7 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
| 471 | } | 470 | } |
| 472 | 471 | ||
| 473 | dbl_indir_block = | 472 | dbl_indir_block = |
| 474 | befs_bread(sb, iaddr2blockno(sb, &data->double_indirect) + | 473 | sb_bread(sb, iaddr2blockno(sb, &data->double_indirect) + |
| 475 | dbl_which_block); | 474 | dbl_which_block); |
| 476 | if (dbl_indir_block == NULL) { | 475 | if (dbl_indir_block == NULL) { |
| 477 | befs_error(sb, "%s couldn't read the " | 476 | befs_error(sb, "%s couldn't read the " |
| @@ -479,7 +478,6 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
| 479 | (unsigned long) | 478 | (unsigned long) |
| 480 | iaddr2blockno(sb, &data->double_indirect) + | 479 | iaddr2blockno(sb, &data->double_indirect) + |
| 481 | dbl_which_block); | 480 | dbl_which_block); |
| 482 | brelse(dbl_indir_block); | ||
| 483 | return BEFS_ERR; | 481 | return BEFS_ERR; |
| 484 | } | 482 | } |
| 485 | 483 | ||
| @@ -499,12 +497,11 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
| 499 | } | 497 | } |
| 500 | 498 | ||
| 501 | indir_block = | 499 | indir_block = |
| 502 | befs_bread(sb, iaddr2blockno(sb, &indir_run) + which_block); | 500 | sb_bread(sb, iaddr2blockno(sb, &indir_run) + which_block); |
| 503 | if (indir_block == NULL) { | 501 | if (indir_block == NULL) { |
| 504 | befs_error(sb, "%s couldn't read the indirect block " | 502 | befs_error(sb, "%s couldn't read the indirect block " |
| 505 | "at blockno %lu", __func__, (unsigned long) | 503 | "at blockno %lu", __func__, (unsigned long) |
| 506 | iaddr2blockno(sb, &indir_run) + which_block); | 504 | iaddr2blockno(sb, &indir_run) + which_block); |
| 507 | brelse(indir_block); | ||
| 508 | return BEFS_ERR; | 505 | return BEFS_ERR; |
| 509 | } | 506 | } |
| 510 | 507 | ||
diff --git a/fs/befs/debug.c b/fs/befs/debug.c index 4de7cffcd662..85c13392e9e8 100644 --- a/fs/befs/debug.c +++ b/fs/befs/debug.c | |||
| @@ -169,6 +169,7 @@ befs_dump_super_block(const struct super_block *sb, befs_super_block * sup) | |||
| 169 | 169 | ||
| 170 | befs_debug(sb, " num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks)); | 170 | befs_debug(sb, " num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks)); |
| 171 | befs_debug(sb, " used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks)); | 171 | befs_debug(sb, " used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks)); |
| 172 | befs_debug(sb, " inode_size %u", fs32_to_cpu(sb, sup->inode_size)); | ||
| 172 | 173 | ||
| 173 | befs_debug(sb, " magic2 %08x", fs32_to_cpu(sb, sup->magic2)); | 174 | befs_debug(sb, " magic2 %08x", fs32_to_cpu(sb, sup->magic2)); |
| 174 | befs_debug(sb, " blocks_per_ag %u", | 175 | befs_debug(sb, " blocks_per_ag %u", |
diff --git a/fs/befs/io.c b/fs/befs/io.c index 523c8af2d770..b4a558126ee1 100644 --- a/fs/befs/io.c +++ b/fs/befs/io.c | |||
| @@ -27,7 +27,7 @@ struct buffer_head * | |||
| 27 | befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) | 27 | befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) |
| 28 | { | 28 | { |
| 29 | struct buffer_head *bh; | 29 | struct buffer_head *bh; |
| 30 | befs_blocknr_t block = 0; | 30 | befs_blocknr_t block; |
| 31 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 31 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
| 32 | 32 | ||
| 33 | befs_debug(sb, "---> Enter %s " | 33 | befs_debug(sb, "---> Enter %s " |
| @@ -59,27 +59,3 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) | |||
| 59 | befs_debug(sb, "<--- %s ERROR", __func__); | 59 | befs_debug(sb, "<--- %s ERROR", __func__); |
| 60 | return NULL; | 60 | return NULL; |
| 61 | } | 61 | } |
| 62 | |||
| 63 | struct buffer_head * | ||
| 64 | befs_bread(struct super_block *sb, befs_blocknr_t block) | ||
| 65 | { | ||
| 66 | struct buffer_head *bh; | ||
| 67 | |||
| 68 | befs_debug(sb, "---> Enter %s %lu", __func__, (unsigned long)block); | ||
| 69 | |||
| 70 | bh = sb_bread(sb, block); | ||
| 71 | |||
| 72 | if (bh == NULL) { | ||
| 73 | befs_error(sb, "Failed to read block %lu", | ||
| 74 | (unsigned long)block); | ||
| 75 | goto error; | ||
| 76 | } | ||
| 77 | |||
| 78 | befs_debug(sb, "<--- %s", __func__); | ||
| 79 | |||
| 80 | return bh; | ||
| 81 | |||
| 82 | error: | ||
| 83 | befs_debug(sb, "<--- %s ERROR", __func__); | ||
| 84 | return NULL; | ||
| 85 | } | ||
diff --git a/fs/befs/io.h b/fs/befs/io.h index 9b78266b6aa5..78d7bc6e60de 100644 --- a/fs/befs/io.h +++ b/fs/befs/io.h | |||
| @@ -5,5 +5,3 @@ | |||
| 5 | struct buffer_head *befs_bread_iaddr(struct super_block *sb, | 5 | struct buffer_head *befs_bread_iaddr(struct super_block *sb, |
| 6 | befs_inode_addr iaddr); | 6 | befs_inode_addr iaddr); |
| 7 | 7 | ||
| 8 | struct buffer_head *befs_bread(struct super_block *sb, befs_blocknr_t block); | ||
| 9 | |||
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index bfe9f9994935..647a276eba56 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
| @@ -120,7 +120,7 @@ befs_get_block(struct inode *inode, sector_t block, | |||
| 120 | struct super_block *sb = inode->i_sb; | 120 | struct super_block *sb = inode->i_sb; |
| 121 | befs_data_stream *ds = &BEFS_I(inode)->i_data.ds; | 121 | befs_data_stream *ds = &BEFS_I(inode)->i_data.ds; |
| 122 | befs_block_run run = BAD_IADDR; | 122 | befs_block_run run = BAD_IADDR; |
| 123 | int res = 0; | 123 | int res; |
| 124 | ulong disk_off; | 124 | ulong disk_off; |
| 125 | 125 | ||
| 126 | befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld", | 126 | befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld", |
| @@ -179,15 +179,16 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | |||
| 179 | kfree(utfname); | 179 | kfree(utfname); |
| 180 | 180 | ||
| 181 | } else { | 181 | } else { |
| 182 | ret = befs_btree_find(sb, ds, dentry->d_name.name, &offset); | 182 | ret = befs_btree_find(sb, ds, name, &offset); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | if (ret == BEFS_BT_NOT_FOUND) { | 185 | if (ret == BEFS_BT_NOT_FOUND) { |
| 186 | befs_debug(sb, "<--- %s %pd not found", __func__, dentry); | 186 | befs_debug(sb, "<--- %s %pd not found", __func__, dentry); |
| 187 | d_add(dentry, NULL); | ||
| 187 | return ERR_PTR(-ENOENT); | 188 | return ERR_PTR(-ENOENT); |
| 188 | 189 | ||
| 189 | } else if (ret != BEFS_OK || offset == 0) { | 190 | } else if (ret != BEFS_OK || offset == 0) { |
| 190 | befs_warning(sb, "<--- %s Error", __func__); | 191 | befs_error(sb, "<--- %s Error", __func__); |
| 191 | return ERR_PTR(-ENODATA); | 192 | return ERR_PTR(-ENODATA); |
| 192 | } | 193 | } |
| 193 | 194 | ||
| @@ -211,56 +212,55 @@ befs_readdir(struct file *file, struct dir_context *ctx) | |||
| 211 | befs_off_t value; | 212 | befs_off_t value; |
| 212 | int result; | 213 | int result; |
| 213 | size_t keysize; | 214 | size_t keysize; |
| 214 | unsigned char d_type; | ||
| 215 | char keybuf[BEFS_NAME_LEN + 1]; | 215 | char keybuf[BEFS_NAME_LEN + 1]; |
| 216 | 216 | ||
| 217 | befs_debug(sb, "---> %s name %pD, inode %ld, ctx->pos %lld", | 217 | befs_debug(sb, "---> %s name %pD, inode %ld, ctx->pos %lld", |
| 218 | __func__, file, inode->i_ino, ctx->pos); | 218 | __func__, file, inode->i_ino, ctx->pos); |
| 219 | 219 | ||
| 220 | more: | 220 | while (1) { |
| 221 | result = befs_btree_read(sb, ds, ctx->pos, BEFS_NAME_LEN + 1, | 221 | result = befs_btree_read(sb, ds, ctx->pos, BEFS_NAME_LEN + 1, |
| 222 | keybuf, &keysize, &value); | 222 | keybuf, &keysize, &value); |
| 223 | 223 | ||
| 224 | if (result == BEFS_ERR) { | 224 | if (result == BEFS_ERR) { |
| 225 | befs_debug(sb, "<--- %s ERROR", __func__); | 225 | befs_debug(sb, "<--- %s ERROR", __func__); |
| 226 | befs_error(sb, "IO error reading %pD (inode %lu)", | 226 | befs_error(sb, "IO error reading %pD (inode %lu)", |
| 227 | file, inode->i_ino); | 227 | file, inode->i_ino); |
| 228 | return -EIO; | 228 | return -EIO; |
| 229 | |||
| 230 | } else if (result == BEFS_BT_END) { | ||
| 231 | befs_debug(sb, "<--- %s END", __func__); | ||
| 232 | return 0; | ||
| 233 | |||
| 234 | } else if (result == BEFS_BT_EMPTY) { | ||
| 235 | befs_debug(sb, "<--- %s Empty directory", __func__); | ||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | 229 | ||
| 239 | d_type = DT_UNKNOWN; | 230 | } else if (result == BEFS_BT_END) { |
| 231 | befs_debug(sb, "<--- %s END", __func__); | ||
| 232 | return 0; | ||
| 240 | 233 | ||
| 241 | /* Convert to NLS */ | 234 | } else if (result == BEFS_BT_EMPTY) { |
| 242 | if (BEFS_SB(sb)->nls) { | 235 | befs_debug(sb, "<--- %s Empty directory", __func__); |
| 243 | char *nlsname; | 236 | return 0; |
| 244 | int nlsnamelen; | ||
| 245 | result = | ||
| 246 | befs_utf2nls(sb, keybuf, keysize, &nlsname, &nlsnamelen); | ||
| 247 | if (result < 0) { | ||
| 248 | befs_debug(sb, "<--- %s ERROR", __func__); | ||
| 249 | return result; | ||
| 250 | } | 237 | } |
| 251 | if (!dir_emit(ctx, nlsname, nlsnamelen, | 238 | |
| 252 | (ino_t) value, d_type)) { | 239 | /* Convert to NLS */ |
| 240 | if (BEFS_SB(sb)->nls) { | ||
| 241 | char *nlsname; | ||
| 242 | int nlsnamelen; | ||
| 243 | |||
| 244 | result = | ||
| 245 | befs_utf2nls(sb, keybuf, keysize, &nlsname, | ||
| 246 | &nlsnamelen); | ||
| 247 | if (result < 0) { | ||
| 248 | befs_debug(sb, "<--- %s ERROR", __func__); | ||
| 249 | return result; | ||
| 250 | } | ||
| 251 | if (!dir_emit(ctx, nlsname, nlsnamelen, | ||
| 252 | (ino_t) value, DT_UNKNOWN)) { | ||
| 253 | kfree(nlsname); | ||
| 254 | return 0; | ||
| 255 | } | ||
| 253 | kfree(nlsname); | 256 | kfree(nlsname); |
| 254 | return 0; | 257 | } else { |
| 258 | if (!dir_emit(ctx, keybuf, keysize, | ||
| 259 | (ino_t) value, DT_UNKNOWN)) | ||
| 260 | return 0; | ||
| 255 | } | 261 | } |
| 256 | kfree(nlsname); | 262 | ctx->pos++; |
| 257 | } else { | ||
| 258 | if (!dir_emit(ctx, keybuf, keysize, | ||
| 259 | (ino_t) value, d_type)) | ||
| 260 | return 0; | ||
| 261 | } | 263 | } |
| 262 | ctx->pos++; | ||
| 263 | goto more; | ||
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static struct inode * | 266 | static struct inode * |
| @@ -299,7 +299,6 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
| 299 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 299 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
| 300 | struct befs_inode_info *befs_ino; | 300 | struct befs_inode_info *befs_ino; |
| 301 | struct inode *inode; | 301 | struct inode *inode; |
| 302 | long ret = -EIO; | ||
| 303 | 302 | ||
| 304 | befs_debug(sb, "---> %s inode = %lu", __func__, ino); | 303 | befs_debug(sb, "---> %s inode = %lu", __func__, ino); |
| 305 | 304 | ||
| @@ -318,7 +317,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
| 318 | befs_ino->i_inode_num.allocation_group, | 317 | befs_ino->i_inode_num.allocation_group, |
| 319 | befs_ino->i_inode_num.start, befs_ino->i_inode_num.len); | 318 | befs_ino->i_inode_num.start, befs_ino->i_inode_num.len); |
| 320 | 319 | ||
| 321 | bh = befs_bread(sb, inode->i_ino); | 320 | bh = sb_bread(sb, inode->i_ino); |
| 322 | if (!bh) { | 321 | if (!bh) { |
| 323 | befs_error(sb, "unable to read inode block - " | 322 | befs_error(sb, "unable to read inode block - " |
| 324 | "inode = %lu", inode->i_ino); | 323 | "inode = %lu", inode->i_ino); |
| @@ -421,7 +420,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
| 421 | unacquire_none: | 420 | unacquire_none: |
| 422 | iget_failed(inode); | 421 | iget_failed(inode); |
| 423 | befs_debug(sb, "<--- %s - Bad inode", __func__); | 422 | befs_debug(sb, "<--- %s - Bad inode", __func__); |
| 424 | return ERR_PTR(ret); | 423 | return ERR_PTR(-EIO); |
| 425 | } | 424 | } |
| 426 | 425 | ||
| 427 | /* Initialize the inode cache. Called at fs setup. | 426 | /* Initialize the inode cache. Called at fs setup. |
| @@ -436,10 +435,9 @@ befs_init_inodecache(void) | |||
| 436 | 0, (SLAB_RECLAIM_ACCOUNT| | 435 | 0, (SLAB_RECLAIM_ACCOUNT| |
| 437 | SLAB_MEM_SPREAD|SLAB_ACCOUNT), | 436 | SLAB_MEM_SPREAD|SLAB_ACCOUNT), |
| 438 | init_once); | 437 | init_once); |
| 439 | if (befs_inode_cachep == NULL) { | 438 | if (befs_inode_cachep == NULL) |
| 440 | pr_err("%s: Couldn't initialize inode slabcache\n", __func__); | ||
| 441 | return -ENOMEM; | 439 | return -ENOMEM; |
| 442 | } | 440 | |
| 443 | return 0; | 441 | return 0; |
| 444 | } | 442 | } |
| 445 | 443 | ||
| @@ -524,8 +522,6 @@ befs_utf2nls(struct super_block *sb, const char *in, | |||
| 524 | 522 | ||
| 525 | *out = result = kmalloc(maxlen, GFP_NOFS); | 523 | *out = result = kmalloc(maxlen, GFP_NOFS); |
| 526 | if (!*out) { | 524 | if (!*out) { |
| 527 | befs_error(sb, "%s cannot allocate memory", __func__); | ||
| 528 | *out_len = 0; | ||
| 529 | return -ENOMEM; | 525 | return -ENOMEM; |
| 530 | } | 526 | } |
| 531 | 527 | ||
| @@ -604,7 +600,6 @@ befs_nls2utf(struct super_block *sb, const char *in, | |||
| 604 | 600 | ||
| 605 | *out = result = kmalloc(maxlen, GFP_NOFS); | 601 | *out = result = kmalloc(maxlen, GFP_NOFS); |
| 606 | if (!*out) { | 602 | if (!*out) { |
| 607 | befs_error(sb, "%s cannot allocate memory", __func__); | ||
| 608 | *out_len = 0; | 603 | *out_len = 0; |
| 609 | return -ENOMEM; | 604 | return -ENOMEM; |
| 610 | } | 605 | } |
| @@ -637,10 +632,6 @@ befs_nls2utf(struct super_block *sb, const char *in, | |||
| 637 | return -EILSEQ; | 632 | return -EILSEQ; |
| 638 | } | 633 | } |
| 639 | 634 | ||
| 640 | /** | ||
| 641 | * Use the | ||
| 642 | * | ||
| 643 | */ | ||
| 644 | enum { | 635 | enum { |
| 645 | Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err, | 636 | Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err, |
| 646 | }; | 637 | }; |
| @@ -760,19 +751,19 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 760 | long ret = -EINVAL; | 751 | long ret = -EINVAL; |
| 761 | const unsigned long sb_block = 0; | 752 | const unsigned long sb_block = 0; |
| 762 | const off_t x86_sb_off = 512; | 753 | const off_t x86_sb_off = 512; |
| 754 | int blocksize; | ||
| 763 | 755 | ||
| 764 | save_mount_options(sb, data); | 756 | save_mount_options(sb, data); |
| 765 | 757 | ||
| 766 | sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); | 758 | sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); |
| 767 | if (sb->s_fs_info == NULL) { | 759 | if (sb->s_fs_info == NULL) |
| 768 | pr_err("(%s): Unable to allocate memory for private " | ||
| 769 | "portion of superblock. Bailing.\n", sb->s_id); | ||
| 770 | goto unacquire_none; | 760 | goto unacquire_none; |
| 771 | } | 761 | |
| 772 | befs_sb = BEFS_SB(sb); | 762 | befs_sb = BEFS_SB(sb); |
| 773 | 763 | ||
| 774 | if (!parse_options((char *) data, &befs_sb->mount_opts)) { | 764 | if (!parse_options((char *) data, &befs_sb->mount_opts)) { |
| 775 | befs_error(sb, "cannot parse mount options"); | 765 | if (!silent) |
| 766 | befs_error(sb, "cannot parse mount options"); | ||
| 776 | goto unacquire_priv_sbp; | 767 | goto unacquire_priv_sbp; |
| 777 | } | 768 | } |
| 778 | 769 | ||
| @@ -793,10 +784,16 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 793 | * least 1k to get the second 512 bytes of the volume. | 784 | * least 1k to get the second 512 bytes of the volume. |
| 794 | * -WD 10-26-01 | 785 | * -WD 10-26-01 |
| 795 | */ | 786 | */ |
| 796 | sb_min_blocksize(sb, 1024); | 787 | blocksize = sb_min_blocksize(sb, 1024); |
| 788 | if (!blocksize) { | ||
| 789 | if (!silent) | ||
| 790 | befs_error(sb, "unable to set blocksize"); | ||
| 791 | goto unacquire_priv_sbp; | ||
| 792 | } | ||
| 797 | 793 | ||
| 798 | if (!(bh = sb_bread(sb, sb_block))) { | 794 | if (!(bh = sb_bread(sb, sb_block))) { |
| 799 | befs_error(sb, "unable to read superblock"); | 795 | if (!silent) |
| 796 | befs_error(sb, "unable to read superblock"); | ||
| 800 | goto unacquire_priv_sbp; | 797 | goto unacquire_priv_sbp; |
| 801 | } | 798 | } |
| 802 | 799 | ||
| @@ -820,9 +817,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 820 | brelse(bh); | 817 | brelse(bh); |
| 821 | 818 | ||
| 822 | if( befs_sb->num_blocks > ~((sector_t)0) ) { | 819 | if( befs_sb->num_blocks > ~((sector_t)0) ) { |
| 823 | befs_error(sb, "blocks count: %llu " | 820 | if (!silent) |
| 824 | "is larger than the host can use", | 821 | befs_error(sb, "blocks count: %llu is larger than the host can use", |
| 825 | befs_sb->num_blocks); | 822 | befs_sb->num_blocks); |
| 826 | goto unacquire_priv_sbp; | 823 | goto unacquire_priv_sbp; |
| 827 | } | 824 | } |
| 828 | 825 | ||
| @@ -841,7 +838,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 841 | } | 838 | } |
| 842 | sb->s_root = d_make_root(root); | 839 | sb->s_root = d_make_root(root); |
| 843 | if (!sb->s_root) { | 840 | if (!sb->s_root) { |
| 844 | befs_error(sb, "get root inode failed"); | 841 | if (!silent) |
| 842 | befs_error(sb, "get root inode failed"); | ||
| 845 | goto unacquire_priv_sbp; | 843 | goto unacquire_priv_sbp; |
| 846 | } | 844 | } |
| 847 | 845 | ||
| @@ -870,9 +868,9 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 870 | unacquire_priv_sbp: | 868 | unacquire_priv_sbp: |
| 871 | kfree(befs_sb->mount_opts.iocharset); | 869 | kfree(befs_sb->mount_opts.iocharset); |
| 872 | kfree(sb->s_fs_info); | 870 | kfree(sb->s_fs_info); |
| 871 | sb->s_fs_info = NULL; | ||
| 873 | 872 | ||
| 874 | unacquire_none: | 873 | unacquire_none: |
| 875 | sb->s_fs_info = NULL; | ||
| 876 | return ret; | 874 | return ret; |
| 877 | } | 875 | } |
| 878 | 876 | ||
diff --git a/fs/befs/super.c b/fs/befs/super.c index aeafc4d84278..7c50025c99d8 100644 --- a/fs/befs/super.c +++ b/fs/befs/super.c | |||
| @@ -13,24 +13,20 @@ | |||
| 13 | #include "befs.h" | 13 | #include "befs.h" |
| 14 | #include "super.h" | 14 | #include "super.h" |
| 15 | 15 | ||
| 16 | /** | 16 | /* |
| 17 | * load_befs_sb -- Read from disk and properly byteswap all the fields | 17 | * befs_load_sb -- Read from disk and properly byteswap all the fields |
| 18 | * of the befs superblock | 18 | * of the befs superblock |
| 19 | * | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * | ||
| 23 | */ | 19 | */ |
| 24 | int | 20 | int |
| 25 | befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) | 21 | befs_load_sb(struct super_block *sb, befs_super_block *disk_sb) |
| 26 | { | 22 | { |
| 27 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 23 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
| 28 | 24 | ||
| 29 | /* Check the byte order of the filesystem */ | 25 | /* Check the byte order of the filesystem */ |
| 30 | if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE) | 26 | if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE) |
| 31 | befs_sb->byte_order = BEFS_BYTESEX_LE; | 27 | befs_sb->byte_order = BEFS_BYTESEX_LE; |
| 32 | else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE) | 28 | else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE) |
| 33 | befs_sb->byte_order = BEFS_BYTESEX_BE; | 29 | befs_sb->byte_order = BEFS_BYTESEX_BE; |
| 34 | 30 | ||
| 35 | befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1); | 31 | befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1); |
| 36 | befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2); | 32 | befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2); |
| @@ -45,6 +41,8 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) | |||
| 45 | befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift); | 41 | befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift); |
| 46 | befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags); | 42 | befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags); |
| 47 | 43 | ||
| 44 | befs_sb->flags = fs32_to_cpu(sb, disk_sb->flags); | ||
| 45 | |||
| 48 | befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks); | 46 | befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks); |
| 49 | befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start); | 47 | befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start); |
| 50 | befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end); | 48 | befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end); |
| @@ -84,15 +82,15 @@ befs_check_sb(struct super_block *sb) | |||
| 84 | } | 82 | } |
| 85 | 83 | ||
| 86 | if (befs_sb->block_size > PAGE_SIZE) { | 84 | if (befs_sb->block_size > PAGE_SIZE) { |
| 87 | befs_error(sb, "blocksize(%u) cannot be larger" | 85 | befs_error(sb, "blocksize(%u) cannot be larger " |
| 88 | "than system pagesize(%lu)", befs_sb->block_size, | 86 | "than system pagesize(%lu)", befs_sb->block_size, |
| 89 | PAGE_SIZE); | 87 | PAGE_SIZE); |
| 90 | return BEFS_ERR; | 88 | return BEFS_ERR; |
| 91 | } | 89 | } |
| 92 | 90 | ||
| 93 | /* | 91 | /* |
| 94 | * block_shift and block_size encode the same information | 92 | * block_shift and block_size encode the same information |
| 95 | * in different ways as a consistency check. | 93 | * in different ways as a consistency check. |
| 96 | */ | 94 | */ |
| 97 | 95 | ||
| 98 | if ((1 << befs_sb->block_shift) != befs_sb->block_size) { | 96 | if ((1 << befs_sb->block_shift) != befs_sb->block_size) { |
| @@ -101,10 +99,18 @@ befs_check_sb(struct super_block *sb) | |||
| 101 | return BEFS_ERR; | 99 | return BEFS_ERR; |
| 102 | } | 100 | } |
| 103 | 101 | ||
| 104 | if (befs_sb->log_start != befs_sb->log_end) { | 102 | |
| 103 | /* ag_shift also encodes the same information as blocks_per_ag in a | ||
| 104 | * different way, non-fatal consistency check | ||
| 105 | */ | ||
| 106 | if ((1 << befs_sb->ag_shift) != befs_sb->blocks_per_ag) | ||
| 107 | befs_error(sb, "ag_shift disagrees with blocks_per_ag."); | ||
| 108 | |||
| 109 | if (befs_sb->log_start != befs_sb->log_end || | ||
| 110 | befs_sb->flags == BEFS_DIRTY) { | ||
| 105 | befs_error(sb, "Filesystem not clean! There are blocks in the " | 111 | befs_error(sb, "Filesystem not clean! There are blocks in the " |
| 106 | "journal. You must boot into BeOS and mount this volume " | 112 | "journal. You must boot into BeOS and mount this " |
| 107 | "to make it clean."); | 113 | "volume to make it clean."); |
| 108 | return BEFS_ERR; | 114 | return BEFS_ERR; |
| 109 | } | 115 | } |
| 110 | 116 | ||
