xref: /minix/minix/fs/ext2/utility.c (revision 7f5f010b)
1 /* Created (MFS based):
2  *   February 2010 (Evgeniy Ivanov)
3  */
4 
5 #include "fs.h"
6 #include "buf.h"
7 #include "inode.h"
8 #include "super.h"
9 
10 
11 /*===========================================================================*
12  *				no_sys					     *
13  *===========================================================================*/
14 int no_sys()
15 {
16 /* Somebody has used an illegal system call number */
17   printf("no_sys: invalid call %d\n", req_nr);
18   return(EINVAL);
19 }
20 
21 
22 /*===========================================================================*
23  *				conv2					     *
24  *===========================================================================*/
25 unsigned conv2(norm, w)
26 int norm;			/* TRUE if no swap, FALSE for byte swap */
27 int w;				/* promotion of 16-bit word to be swapped */
28 {
29 /* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
30   if (norm) return( (unsigned) w & 0xFFFF);
31   return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
32 }
33 
34 
35 /*===========================================================================*
36  *				conv4					     *
37  *===========================================================================*/
38 long conv4(norm, x)
39 int norm;			/* TRUE if no swap, FALSE for byte swap */
40 long x;				/* 32-bit long to be byte swapped */
41 {
42 /* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
43   unsigned lo, hi;
44   long l;
45 
46   if (norm) return(x);			/* byte order was already ok */
47   lo = conv2(FALSE, (int) x & 0xFFFF);	/* low-order half, byte swapped */
48   hi = conv2(FALSE, (int) (x>>16) & 0xFFFF);	/* high-order half, swapped */
49   l = ( (long) lo <<16) | hi;
50   return(l);
51 }
52 
53 
54 /*===========================================================================*
55  *				clock_time				     *
56  *===========================================================================*/
57 time_t clock_time()
58 {
59 /* This routine returns the time in seconds since 1.1.1970.  MINIX is an
60  * astrophysically naive system that assumes the earth rotates at a constant
61  * rate and that such things as leap seconds do not exist.
62  */
63 
64   register int k;
65   clock_t uptime;
66   clock_t realtime;
67   time_t boottime;
68 
69   if ( (k=getuptime(&uptime, &realtime, &boottime)) != OK)
70 		panic("clock_time: getuptme2 failed: %d", k);
71 
72   return( (time_t) (boottime + (realtime/sys_hz())));
73 }
74 
75 
76 /*===========================================================================*
77  *				mfs_min					     *
78  *===========================================================================*/
79 int min(unsigned int l, unsigned int r)
80 {
81   if(r >= l) return(l);
82 
83   return(r);
84 }
85 
86 
87 /*===========================================================================*
88  *				mfs_nul					     *
89  *===========================================================================*/
90 void mfs_nul_f(const char *file, int line, const char *str, unsigned int len,
91 		      unsigned int maxlen)
92 {
93   if(len < maxlen && str[len-1] != '\0') {
94 	printf("ext2 %s:%d string (length %d, maxlen %d) not null-terminated\n",
95 		file, line, len, maxlen);
96   }
97 }
98 
99 #define MYASSERT(c) if(!(c)) { printf("ext2:%s:%d: sanity check: %s failed\n", \
100   file, line, #c); panic("sanity check " #c " failed: %d", __LINE__); }
101 
102 
103 /*===========================================================================*
104  *				ansi_strcmp				     *
105  *===========================================================================*/
106 int ansi_strcmp(register const char* ansi_s, register const char *s2,
107 			register size_t ansi_s_length)
108 {
109 /* Compare non null-terminated string ansi_s (length=ansi_s_length)
110  * with C-string s2.
111  * It returns 0 if strings are equal, otherwise -1 is returned.
112  */
113 	if (ansi_s_length) {
114 		do {
115 			if (*s2 == '\0')
116 				return -1;
117 			if (*ansi_s++ != *s2++)
118 				return -1;
119 		} while (--ansi_s_length > 0);
120 
121 		if (*s2 == '\0')
122 			return 0;
123 		else
124 			return -1;
125 	}
126 	return 0;
127 }
128 
129 
130 /*===========================================================================*
131  *				setbit   				     *
132  *===========================================================================*/
133 bit_t setbit(bitchunk_t *bitmap, bit_t max_bits, unsigned int word)
134 {
135   /* Find free bit in bitmap and set. Return number of the bit,
136    * if failed return -1.
137    */
138   bitchunk_t *wptr, *wlim;
139   bit_t b = -1;
140 
141   /* TODO: do we need to add 1? I saw a situation, when it was
142    * required, and since we check bit number with max_bits it
143    * should be safe.
144    */
145   wlim = &bitmap[FS_BITMAP_CHUNKS(max_bits >> 3)];
146 
147   /* Iterate over the words in block. */
148   for (wptr = &bitmap[word]; wptr < wlim; wptr++) {
149 	bit_t i;
150 	bitchunk_t k;
151 
152 	/* Does this word contain a free bit? */
153 	if (*wptr == (bitchunk_t) ~0)
154 		continue;
155 
156 	/* Find and allocate the free bit. */
157 	k = (int) *wptr;
158 	for (i = 0; (k & (1 << i)) != 0; ++i) {}
159 
160 	/* Bit number from the start of the bit map. */
161 	b = (wptr - &bitmap[0]) * FS_BITCHUNK_BITS + i;
162 
163 	/* Don't allocate bits beyond the end of the map. */
164 	if (b >= max_bits) {
165 		b = -1;
166 		continue;
167 	}
168 
169 	/* Allocate bit number. */
170 	k |= 1 << i;
171 	*wptr = (int) k;
172 	break;
173   }
174 
175   return b;
176 }
177 
178 
179 /*===========================================================================*
180  *				setbyte   				     *
181  *===========================================================================*/
182 bit_t setbyte(bitchunk_t *bitmap, bit_t max_bits)
183 {
184   /* Find free byte in bitmap and set it. Return number of the starting bit,
185    * if failed return -1.
186    */
187   unsigned char *wptr, *wlim;
188   bit_t b = -1;
189 
190   wptr = (unsigned char*) &bitmap[0];
191   /* TODO: do we need to add 1? I saw a situation, when it was
192    * required, and since we check bit number with max_bits it
193    * should be safe.
194    */
195   wlim = &wptr[(max_bits >> 3)];
196 
197   /* Iterate over the words in block. */
198   for ( ; wptr < wlim; wptr++) {
199 	/* Is it a free byte? */
200 	if (*wptr | 0)
201 		continue;
202 
203 	/* Bit number from the start of the bit map. */
204 	b = (wptr - (unsigned char*) &bitmap[0]) * CHAR_BIT;
205 
206 	/* Don't allocate bits beyond the end of the map. */
207 	if (b + CHAR_BIT >= max_bits) {
208 		b = -1;
209 		continue;
210 	}
211 
212 	/* Allocate byte number. */
213 	*wptr = (unsigned char) ~0;
214 	break;
215   }
216   return b;
217 }
218 
219 
220 /*===========================================================================*
221  *				unsetbit   				     *
222  *===========================================================================*/
223 int unsetbit(bitchunk_t *bitmap, bit_t bit)
224 {
225   /* Unset specified bit. If requested bit is already free return -1,
226    * otherwise return 0.
227    */
228   unsigned int word;		/* bit_returned word in bitmap */
229   bitchunk_t k, mask;
230 
231   word = bit / FS_BITCHUNK_BITS;
232   bit = bit % FS_BITCHUNK_BITS; /* index in word */
233   mask = 1 << bit;
234 
235   k = (int) bitmap[word];
236   if (!(k & mask))
237 	return -1;
238 
239   k &= ~mask;
240   bitmap[word] = (int) k;
241   return 0;
242 }
243