1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
/* Created (MFS based):
* February 2010 (Evgeniy Ivanov)
*/
#include "fs.h"
#include "buf.h"
#include "inode.h"
#include "super.h"
/*===========================================================================*
* get_block *
*===========================================================================*/
struct buf *get_block(dev_t dev, block_t block, int how)
{
/* Wrapper routine for lmfs_get_block(). This ext2 implementation does not deal
* well with block read errors pretty much anywhere. To prevent corruption due
* to unchecked error conditions, we panic upon an I/O failure here.
*/
struct buf *bp;
int r;
if ((r = lmfs_get_block(&bp, dev, block, how)) != OK && r != ENOENT)
panic("ext2: error getting block (%llu,%u): %d", dev, block, r);
assert(r == OK || how == PEEK);
return (r == OK) ? bp : NULL;
}
/*===========================================================================*
* conv2 *
*===========================================================================*/
unsigned conv2(norm, w)
int norm; /* TRUE if no swap, FALSE for byte swap */
int w; /* promotion of 16-bit word to be swapped */
{
/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
if (norm) return( (unsigned) w & 0xFFFF);
return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
}
/*===========================================================================*
* conv4 *
*===========================================================================*/
long conv4(norm, x)
int norm; /* TRUE if no swap, FALSE for byte swap */
long x; /* 32-bit long to be byte swapped */
{
/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
unsigned lo, hi;
long l;
if (norm) return(x); /* byte order was already ok */
lo = conv2(FALSE, (int) x & 0xFFFF); /* low-order half, byte swapped */
hi = conv2(FALSE, (int) (x>>16) & 0xFFFF); /* high-order half, swapped */
l = ( (long) lo <<16) | hi;
return(l);
}
/*===========================================================================*
* ansi_strcmp *
*===========================================================================*/
int ansi_strcmp(register const char* ansi_s, register const char *s2,
register size_t ansi_s_length)
{
/* Compare non null-terminated string ansi_s (length=ansi_s_length)
* with C-string s2.
* It returns 0 if strings are equal, otherwise -1 is returned.
*/
if (ansi_s_length) {
do {
if (*s2 == '\0')
return -1;
if (*ansi_s++ != *s2++)
return -1;
} while (--ansi_s_length > 0);
if (*s2 == '\0')
return 0;
else
return -1;
}
return 0;
}
/*===========================================================================*
* setbit *
*===========================================================================*/
bit_t setbit(bitchunk_t *bitmap, bit_t max_bits, unsigned int word)
{
/* Find free bit in bitmap and set. Return number of the bit,
* if failed return -1.
*/
bitchunk_t *wptr, *wlim;
bit_t b = -1;
/* TODO: do we need to add 1? I saw a situation, when it was
* required, and since we check bit number with max_bits it
* should be safe.
*/
wlim = &bitmap[FS_BITMAP_CHUNKS(max_bits >> 3)];
/* Iterate over the words in block. */
for (wptr = &bitmap[word]; wptr < wlim; wptr++) {
bit_t i;
bitchunk_t k;
/* Does this word contain a free bit? */
if (*wptr == (bitchunk_t) ~0)
continue;
/* Find and allocate the free bit. */
k = (int) *wptr;
for (i = 0; (k & (1 << i)) != 0; ++i) {}
/* Bit number from the start of the bit map. */
b = (wptr - &bitmap[0]) * FS_BITCHUNK_BITS + i;
/* Don't allocate bits beyond the end of the map. */
if (b >= max_bits) {
b = -1;
continue;
}
/* Allocate bit number. */
k |= 1 << i;
*wptr = (int) k;
break;
}
return b;
}
/*===========================================================================*
* setbyte *
*===========================================================================*/
bit_t setbyte(bitchunk_t *bitmap, bit_t max_bits)
{
/* Find free byte in bitmap and set it. Return number of the starting bit,
* if failed return -1.
*/
unsigned char *wptr, *wlim;
bit_t b = -1;
wptr = (unsigned char*) &bitmap[0];
/* TODO: do we need to add 1? I saw a situation, when it was
* required, and since we check bit number with max_bits it
* should be safe.
*/
wlim = &wptr[(max_bits >> 3)];
/* Iterate over the words in block. */
for ( ; wptr < wlim; wptr++) {
/* Is it a free byte? */
if (*wptr | 0)
continue;
/* Bit number from the start of the bit map. */
b = (wptr - (unsigned char*) &bitmap[0]) * CHAR_BIT;
/* Don't allocate bits beyond the end of the map. */
if (b + CHAR_BIT >= max_bits) {
b = -1;
continue;
}
/* Allocate byte number. */
*wptr = (unsigned char) ~0;
break;
}
return b;
}
/*===========================================================================*
* unsetbit *
*===========================================================================*/
int unsetbit(bitchunk_t *bitmap, bit_t bit)
{
/* Unset specified bit. If requested bit is already free return -1,
* otherwise return 0.
*/
unsigned int word; /* bit_returned word in bitmap */
bitchunk_t k, mask;
word = bit / FS_BITCHUNK_BITS;
bit = bit % FS_BITCHUNK_BITS; /* index in word */
mask = 1 << bit;
k = (int) bitmap[word];
if (!(k & mask))
return -1;
k &= ~mask;
bitmap[word] = (int) k;
return 0;
}
|