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
Line 
1#include <assert.h>
2#include <errno.h>
3#include "mfs.h"
4#include "mfs_utils.h"
5
6static int read_map_ondisk(uint32_t *b, const struct mfs_node *mnode, int rblock);
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
28 if (mnode->ino_i->i_size < (int32_t) pos) {
29 r = EOK;
30 *b = 0;
31 goto out;
32 }
33
34 r = read_map_ondisk(b, mnode, rblock);
35out:
36 return r;
37}
38
39static int read_map_ondisk(uint32_t *b, const struct mfs_node *mnode, int rblock)
40{
41 block_t *bi1, *bi2;
42 int r, nr_direct, nr_indirect;
43 int ptrs_per_block;
44
45 assert(mnode);
46 const struct mfs_ino_info *ino_i = mnode->ino_i;
47
48 assert(ino_i);
49 assert(mnode->instance);
50
51 const struct mfs_sb_info *sbi = mnode->instance->sbi;
52 assert(sbi);
53
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 }
65
66 if (rblock < nr_direct) {
67 *b = ino_i->i_dzone[rblock];
68 r = EOK;
69 goto out;
70 }
71 rblock -= nr_direct - 1;
72
73 /*Check if the wanted block is in the single indirect zone*/
74 if (rblock < ptrs_per_block) {
75 if (ino_i->i_izone[0] == 0) {
76 r = -1;
77 goto out;
78 }
79
80 r = read_ind_block(bi2, mnode->instance, ino_i->i_izone[0]);
81
82 if (r != EOK)
83 goto out;
84
85 *b = fs_version == MFS_VERSION_V1 ?
86 ((uint16_t *) bi1->data)[rblock] :
87 ((uint32_t *) bi1->data)[rblock];
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*/
97 if (ino_i->i_izone[1] == 0) {
98 r = -1;
99 goto out;
100 }
101
102 r = read_ind_block(bi1, mnode->instance, ino_i->i_izone[1]);
103
104 if (r != EOK)
105 goto out;
106
107 /*read the second indirect zone*/
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,
118 ((uint32_t *) bi1->data)[di_block]);
119
120 if (r != EOK)
121 goto out_block;
122
123 *b = ((uint32_t *) bi2->data)[rblock % ptrs_per_block];
124 }
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.