aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/befs/befs.h19
-rw-r--r--fs/befs/btree.c60
-rw-r--r--fs/befs/datastream.c253
-rw-r--r--fs/befs/debug.c1
-rw-r--r--fs/befs/io.c26
-rw-r--r--fs/befs/io.h2
-rw-r--r--fs/befs/linuxvfs.c130
-rw-r--r--fs/befs/super.c36
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
143static inline int
144befs_iaddr_is_empty(const befs_inode_addr *iaddr)
145{
146 return (!iaddr->allocation_group) && (!iaddr->start) && (!iaddr->len);
147}
148
149static inline size_t
150befs_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 */
88static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; 88static const befs_off_t BEFS_BT_INVAL = 0xffffffffffffffffULL;
89 89
90/* local functions */ 90/* local functions */
91static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds, 91static 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 */
249int 247int
250befs_btree_find(struct super_block *sb, const befs_data_stream *ds, 248befs_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 */
338static int 332static int
339befs_find_key(struct super_block *sb, struct befs_btree_node *node, 333befs_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
608befs_leafnode(struct befs_btree_node *node) 602befs_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 */
720static int 714static int
721befs_compare_strings(const void *key1, int keylen1, 715befs_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
23static int befs_find_brun_direct(struct super_block *sb, 23static 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
27static int befs_find_brun_indirect(struct super_block *sb, 27static 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
32static int befs_find_brun_dblindirect(struct super_block *sb, 32static 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 */
47struct buffer_head * 47struct buffer_head *
48befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, 48befs_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 */
89int 95int
90befs_fblock2brun(struct super_block *sb, const befs_data_stream *data, 96befs_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*/
245static int 251static int
246befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data, 252befs_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*/
305static int 305static int
306befs_find_brun_indirect(struct super_block *sb, 306befs_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*/
414static int 414static int
415befs_find_brun_dblindirect(struct super_block *sb, 415befs_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 *
27befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) 27befs_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
63struct buffer_head *
64befs_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 @@
5struct buffer_head *befs_bread_iaddr(struct super_block *sb, 5struct buffer_head *befs_bread_iaddr(struct super_block *sb,
6 befs_inode_addr iaddr); 6 befs_inode_addr iaddr);
7 7
8struct 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
220more: 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
266static struct inode * 266static 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 */
644enum { 635enum {
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 */
24int 20int
25befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) 21befs_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