source: mainline/uspace/srv/fs/minixfs/mfs_read.c@ 155f792

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 155f792 was 155f792, checked in by Maurizio Lombardi <m.lombardi85@…>, 14 years ago

Use a generic minixfs inode in core to avoid code duplication

  • Property mode set to 100644
File size: 2.7 KB
RevLine 
[930baca]1#include <assert.h>
2#include <errno.h>
3#include "mfs.h"
4#include "mfs_utils.h"
5
[155f792]6static int read_map_ondisk(uint32_t *b, const struct mfs_node *mnode, int rblock);
[930baca]7
8/*Given the position in the file expressed in
9 *bytes, this function returns the on-disk block
10 *relative to that position.
11 *Returns zero if the block does not exist.
12 */
13int read_map(uint32_t *b, const struct mfs_node *mnode, const uint32_t pos)
14{
15 int r;
16
17 assert(mnode);
18 assert(mnode->instance);
19
20 const struct mfs_sb_info *sbi = mnode->instance->sbi;
21 assert(sbi);
22
23 const int block_size = sbi->block_size;
24
25 /*Compute relative block number in file*/
26 int rblock = pos / block_size;
27
[155f792]28 if (mnode->ino_i->i_size < (int32_t) pos) {
[930baca]29 r = EOK;
[155f792]30 *b = 0;
[930baca]31 goto out;
32 }
33
[155f792]34 r = read_map_ondisk(b, mnode, rblock);
[930baca]35out:
36 return r;
37}
38
[155f792]39static int read_map_ondisk(uint32_t *b, const struct mfs_node *mnode, int rblock)
[930baca]40{
41 block_t *bi1, *bi2;
[155f792]42 int r, nr_direct, nr_indirect;
43 int ptrs_per_block;
[930baca]44
45 assert(mnode);
[155f792]46 const struct mfs_ino_info *ino_i = mnode->ino_i;
[930baca]47
[155f792]48 assert(ino_i);
[930baca]49 assert(mnode->instance);
50
51 const struct mfs_sb_info *sbi = mnode->instance->sbi;
52 assert(sbi);
53
[155f792]54 const int fs_version = sbi->fs_version;
55
56 if (fs_version == MFS_VERSION_V1) {
57 nr_direct = V1_NR_DIRECT_ZONES;
58 nr_indirect = V1_NR_INDIRECT_ZONES;
59 ptrs_per_block = MFS_BLOCKSIZE / sizeof(uint16_t);
60 } else {
61 nr_direct = V2_NR_DIRECT_ZONES;
62 nr_indirect = V2_NR_INDIRECT_ZONES;
63 ptrs_per_block = sbi->block_size / sizeof(uint32_t);
64 }
[930baca]65
[155f792]66 if (rblock < nr_direct) {
67 *b = ino_i->i_dzone[rblock];
[930baca]68 r = EOK;
69 goto out;
70 }
[155f792]71 rblock -= nr_direct - 1;
[930baca]72
73 /*Check if the wanted block is in the single indirect zone*/
74 if (rblock < ptrs_per_block) {
[155f792]75 if (ino_i->i_izone[0] == 0) {
[930baca]76 r = -1;
77 goto out;
78 }
79
[155f792]80 r = read_ind_block(bi2, mnode->instance, ino_i->i_izone[0]);
[930baca]81
82 if (r != EOK)
83 goto out;
84
[155f792]85 *b = fs_version == MFS_VERSION_V1 ?
86 ((uint16_t *) bi1->data)[rblock] :
87 ((uint32_t *) bi1->data)[rblock];
[930baca]88 goto out_block;
89 }
90
91 rblock -= ptrs_per_block - 1;
92
93 /*The wanted block is in the double indirect zone*/
94 uint32_t di_block = rblock / ptrs_per_block;
95
96 /*read the first indirect zone*/
[155f792]97 if (ino_i->i_izone[1] == 0) {
[930baca]98 r = -1;
99 goto out;
100 }
101
[155f792]102 r = read_ind_block(bi1, mnode->instance, ino_i->i_izone[1]);
[930baca]103
104 if (r != EOK)
105 goto out;
106
107 /*read the second indirect zone*/
[155f792]108 if (fs_version == MFS_VERSION_V1) {
109 r = read_ind_block(bi2, mnode->instance,
110 ((uint16_t *) bi1->data)[di_block]);
111
112 if (r != EOK)
113 goto out_block;
114
115 *b = ((uint16_t *) bi2->data)[rblock % ptrs_per_block];
116 } else {
117 r = read_ind_block(bi2, mnode->instance,
[930baca]118 ((uint32_t *) bi1->data)[di_block]);
119
[155f792]120 if (r != EOK)
121 goto out_block;
[930baca]122
[155f792]123 *b = ((uint32_t *) bi2->data)[rblock % ptrs_per_block];
124 }
[930baca]125 block_put(bi2);
126
127out_block:
128 block_put(bi1);
129out:
130 return r;
131}
132
Note: See TracBrowser for help on using the repository browser.