13 #include <linux/kernel.h>
15 #include <linux/string.h>
24 befs_data_stream *
data,
28 befs_data_stream *
data,
30 befs_block_run *
run);
33 befs_data_stream *
data,
35 befs_block_run *
run);
51 struct buffer_head *bh =
NULL;
55 befs_debug(sb,
"---> befs_read_datastream() %Lu", pos);
56 block = pos >> BEFS_SB(sb)->block_shift;
58 *off = pos - (block << BEFS_SB(sb)->block_shift);
61 befs_error(sb,
"BeFS: Error finding disk addr of block %lu",
63 befs_debug(sb,
"<--- befs_read_datastream() ERROR");
68 befs_error(sb,
"BeFS: Error reading block %lu from datastream",
73 befs_debug(sb,
"<--- befs_read_datastream() read data, starting at %Lu",
97 if (pos < data->max_direct_range) {
98 err = befs_find_brun_direct(sb, data, fblock, run);
100 }
else if (pos < data->max_indirect_range) {
101 err = befs_find_brun_indirect(sb, data, fblock, run);
103 }
else if (pos < data->max_double_indirect_range) {
104 err = befs_find_brun_dblindirect(sb, data, fblock, run);
108 "befs_fblock2brun() was asked to find block %lu, "
109 "which is not mapped by the datastream\n", fblock);
130 struct buffer_head *bh =
NULL;
131 befs_debug(sb,
"---> befs_read_lsymlink() length: %Lu", len);
133 while (bytes_read < len) {
136 befs_error(sb,
"BeFS: Error reading datastream block "
137 "starting from %Lu", bytes_read);
138 befs_debug(sb,
"<--- befs_read_lsymlink() ERROR");
142 plen = ((bytes_read + BEFS_SB(sb)->block_size) < len) ?
143 BEFS_SB(sb)->block_size : len - bytes_read;
144 memcpy(buff + bytes_read, bh->b_data, plen);
149 befs_debug(sb,
"<--- befs_read_lsymlink() read %u bytes", bytes_read);
181 if (ds->size > ds->max_direct_range)
182 metablocks += ds->indirect.len;
193 if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) {
199 ds->max_double_indirect_range - ds->max_indirect_range;
202 indirblocks = dbl_bruns / befs_iaddrs_per_block(sb);
204 metablocks += ds->double_indirect.len;
205 metablocks += indirblocks;
208 blocks = datablocks + metablocks;
209 befs_debug(sb,
"<--- befs_count_blocks() %u blocks", blocks);
249 befs_block_run *array = data->direct;
252 data->max_direct_range >> BEFS_SB(sb)->block_shift;
254 befs_debug(sb,
"---> befs_find_brun_direct(), find %lu", blockno);
256 if (blockno > max_block) {
257 befs_error(sb,
"befs_find_brun_direct() passed block outside of"
263 sum += array[
i].len, i++) {
264 if (blockno >= sum && blockno < sum + (array[i].len)) {
266 run->allocation_group = array[
i].allocation_group;
267 run->start = array[
i].start +
offset;
268 run->len = array[
i].len -
offset;
270 befs_debug(sb,
"---> befs_find_brun_direct(), "
271 "found %lu at direct[%d]", blockno, i);
276 befs_debug(sb,
"---> befs_find_brun_direct() ERROR");
306 befs_block_run * run)
312 struct buffer_head *indirblock;
313 befs_disk_block_run *array;
315 befs_block_run indirect = data->indirect;
317 int arraylen = befs_iaddrs_per_block(sb);
319 befs_debug(sb,
"---> befs_find_brun_indirect(), find %lu", blockno);
321 indir_start_blk = data->max_direct_range >> BEFS_SB(sb)->block_shift;
322 search_blk = blockno - indir_start_blk;
325 for (i = 0; i < indirect.len; i++) {
326 indirblock =
befs_bread(sb, indirblockno + i);
327 if (indirblock ==
NULL) {
329 "---> befs_find_brun_indirect() failed to "
330 "read disk block %lu from the indirect brun",
335 array = (befs_disk_block_run *) indirblock->b_data;
337 for (j = 0; j < arraylen; ++
j) {
338 int len = fs16_to_cpu(sb, array[j].len);
340 if (search_blk >= sum && search_blk < sum + len) {
342 run->allocation_group =
343 fs32_to_cpu(sb, array[j].allocation_group);
347 fs16_to_cpu(sb, array[j].len) -
offset;
351 "<--- befs_find_brun_indirect() found "
352 "file block %lu at indirect[%d]",
353 blockno, j + (i * arraylen));
363 befs_error(sb,
"BeFS: befs_find_brun_indirect() failed to find "
364 "file block %lu", blockno);
366 befs_debug(sb,
"<--- befs_find_brun_indirect() ERROR");
414 befs_block_run * run)
423 off_t dblindir_leftover;
425 struct buffer_head *dbl_indir_block;
426 struct buffer_head *indir_block;
427 befs_block_run indir_run;
434 off_t dbl_indir_off = blockno - indir_start_blk;
444 size_t diblklen = iblklen * befs_iaddrs_per_block(sb)
447 befs_debug(sb,
"---> befs_find_brun_dblindirect() find %lu", blockno);
455 dblindir_indx = dbl_indir_off / diblklen;
456 dblindir_leftover = dbl_indir_off % diblklen;
457 indir_indx = dblindir_leftover / diblklen;
460 dbl_which_block = dblindir_indx / befs_iaddrs_per_block(sb);
461 if (dbl_which_block > data->double_indirect.len) {
462 befs_error(sb,
"The double-indirect index calculated by "
463 "befs_read_brun_dblindirect(), %d, is outside the range "
464 "of the double-indirect block", dblindir_indx);
469 befs_bread(sb, iaddr2blockno(sb, &data->double_indirect) +
471 if (dbl_indir_block ==
NULL) {
472 befs_error(sb,
"befs_read_brun_dblindirect() couldn't read the "
473 "double-indirect block at blockno %lu",
475 &data->double_indirect) +
477 brelse(dbl_indir_block);
482 dblindir_indx - (dbl_which_block * befs_iaddrs_per_block(sb));
484 indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]);
485 brelse(dbl_indir_block);
489 which_block = indir_indx / befs_iaddrs_per_block(sb);
490 if (which_block > indir_run.len) {
491 befs_error(sb,
"The indirect index calculated by "
492 "befs_read_brun_dblindirect(), %d, is outside the range "
493 "of the indirect block", indir_indx);
498 befs_bread(sb, iaddr2blockno(sb, &indir_run) + which_block);
499 if (indir_block ==
NULL) {
500 befs_error(sb,
"befs_read_brun_dblindirect() couldn't read the "
501 "indirect block at blockno %lu",
502 iaddr2blockno(sb, &indir_run) + which_block);
507 block_indx = indir_indx - (which_block * befs_iaddrs_per_block(sb));
509 *run = fsrun_to_cpu(sb, iaddr_array[block_indx]);
513 blockno_at_run_start = indir_start_blk;
514 blockno_at_run_start += diblklen * dblindir_indx;
515 blockno_at_run_start += iblklen * indir_indx;
516 offset = blockno - blockno_at_run_start;
521 befs_debug(sb,
"Found file block %lu in double_indirect[%d][%d],"
522 " double_indirect_leftover = %lu",
523 blockno, dblindir_indx, indir_indx, dblindir_leftover);