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