xref: /minix3/minix/fs/ext2/utility.c (revision 2e89653e65c25c480c40ec47d9e27349f1279c8c)
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  *				conv2					     *
13  *===========================================================================*/
14 unsigned conv2(norm, w)
15 int norm;			/* TRUE if no swap, FALSE for byte swap */
16 int w;				/* promotion of 16-bit word to be swapped */
17 {
18 /* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
19   if (norm) return( (unsigned) w & 0xFFFF);
20   return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
21 }
22 
23 
24 /*===========================================================================*
25  *				conv4					     *
26  *===========================================================================*/
27 long conv4(norm, x)
28 int norm;			/* TRUE if no swap, FALSE for byte swap */
29 long x;				/* 32-bit long to be byte swapped */
30 {
31 /* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
32   unsigned lo, hi;
33   long l;
34 
35   if (norm) return(x);			/* byte order was already ok */
36   lo = conv2(FALSE, (int) x & 0xFFFF);	/* low-order half, byte swapped */
37   hi = conv2(FALSE, (int) (x>>16) & 0xFFFF);	/* high-order half, swapped */
38   l = ( (long) lo <<16) | hi;
39   return(l);
40 }
41 
42 
43 /*===========================================================================*
44  *				ansi_strcmp				     *
45  *===========================================================================*/
46 int ansi_strcmp(register const char* ansi_s, register const char *s2,
47 			register size_t ansi_s_length)
48 {
49 /* Compare non null-terminated string ansi_s (length=ansi_s_length)
50  * with C-string s2.
51  * It returns 0 if strings are equal, otherwise -1 is returned.
52  */
53 	if (ansi_s_length) {
54 		do {
55 			if (*s2 == '\0')
56 				return -1;
57 			if (*ansi_s++ != *s2++)
58 				return -1;
59 		} while (--ansi_s_length > 0);
60 
61 		if (*s2 == '\0')
62 			return 0;
63 		else
64 			return -1;
65 	}
66 	return 0;
67 }
68 
69 
70 /*===========================================================================*
71  *				setbit   				     *
72  *===========================================================================*/
73 bit_t setbit(bitchunk_t *bitmap, bit_t max_bits, unsigned int word)
74 {
75   /* Find free bit in bitmap and set. Return number of the bit,
76    * if failed return -1.
77    */
78   bitchunk_t *wptr, *wlim;
79   bit_t b = -1;
80 
81   /* TODO: do we need to add 1? I saw a situation, when it was
82    * required, and since we check bit number with max_bits it
83    * should be safe.
84    */
85   wlim = &bitmap[FS_BITMAP_CHUNKS(max_bits >> 3)];
86 
87   /* Iterate over the words in block. */
88   for (wptr = &bitmap[word]; wptr < wlim; wptr++) {
89 	bit_t i;
90 	bitchunk_t k;
91 
92 	/* Does this word contain a free bit? */
93 	if (*wptr == (bitchunk_t) ~0)
94 		continue;
95 
96 	/* Find and allocate the free bit. */
97 	k = (int) *wptr;
98 	for (i = 0; (k & (1 << i)) != 0; ++i) {}
99 
100 	/* Bit number from the start of the bit map. */
101 	b = (wptr - &bitmap[0]) * FS_BITCHUNK_BITS + i;
102 
103 	/* Don't allocate bits beyond the end of the map. */
104 	if (b >= max_bits) {
105 		b = -1;
106 		continue;
107 	}
108 
109 	/* Allocate bit number. */
110 	k |= 1 << i;
111 	*wptr = (int) k;
112 	break;
113   }
114 
115   return b;
116 }
117 
118 
119 /*===========================================================================*
120  *				setbyte   				     *
121  *===========================================================================*/
122 bit_t setbyte(bitchunk_t *bitmap, bit_t max_bits)
123 {
124   /* Find free byte in bitmap and set it. Return number of the starting bit,
125    * if failed return -1.
126    */
127   unsigned char *wptr, *wlim;
128   bit_t b = -1;
129 
130   wptr = (unsigned char*) &bitmap[0];
131   /* TODO: do we need to add 1? I saw a situation, when it was
132    * required, and since we check bit number with max_bits it
133    * should be safe.
134    */
135   wlim = &wptr[(max_bits >> 3)];
136 
137   /* Iterate over the words in block. */
138   for ( ; wptr < wlim; wptr++) {
139 	/* Is it a free byte? */
140 	if (*wptr | 0)
141 		continue;
142 
143 	/* Bit number from the start of the bit map. */
144 	b = (wptr - (unsigned char*) &bitmap[0]) * CHAR_BIT;
145 
146 	/* Don't allocate bits beyond the end of the map. */
147 	if (b + CHAR_BIT >= max_bits) {
148 		b = -1;
149 		continue;
150 	}
151 
152 	/* Allocate byte number. */
153 	*wptr = (unsigned char) ~0;
154 	break;
155   }
156   return b;
157 }
158 
159 
160 /*===========================================================================*
161  *				unsetbit   				     *
162  *===========================================================================*/
163 int unsetbit(bitchunk_t *bitmap, bit_t bit)
164 {
165   /* Unset specified bit. If requested bit is already free return -1,
166    * otherwise return 0.
167    */
168   unsigned int word;		/* bit_returned word in bitmap */
169   bitchunk_t k, mask;
170 
171   word = bit / FS_BITCHUNK_BITS;
172   bit = bit % FS_BITCHUNK_BITS; /* index in word */
173   mask = 1 << bit;
174 
175   k = (int) bitmap[word];
176   if (!(k & mask))
177 	return -1;
178 
179   k &= ~mask;
180   bitmap[word] = (int) k;
181   return 0;
182 }
183