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