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