1 /* 2 3 /usr/src/ext2ed/blockbitmap_com.c 4 5 A part of the extended file system 2 disk editor. 6 7 ------------------------- 8 Handles the block bitmap. 9 ------------------------- 10 11 This file implements the commands which are specific to the blockbitmap type. 12 13 First written on: July 5 1995 14 15 Copyright (C) 1995 Gadi Oxman 16 17 */ 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #include "ext2ed.h" 24 25 /* 26 27 The functions in this file use the flobal structure block_bitmap_info. This structure contains the current 28 position in the bitmap. 29 30 */ 31 32 void type_ext2_block_bitmap___entry (char *command_line) 33 34 /* 35 36 This function changes the current entry in the bitmap. It just changes the entry_num variable in block_bitmap_info 37 and dispatches a show command to show the new entry. 38 39 */ 40 41 { 42 unsigned long entry_num; 43 char *ptr,buffer [80]; 44 45 46 47 ptr=parse_word (command_line,buffer); /* Get the requested entry */ 48 if (*ptr==0) { 49 wprintw (command_win,"Error - No argument specified\n"); 50 refresh_command_win (); return; 51 } 52 ptr=parse_word (ptr,buffer); 53 54 entry_num=atol (buffer); 55 56 57 if (entry_num >= file_system_info.super_block.s_blocks_per_group) { /* Check if it is a valid entry number */ 58 59 wprintw (command_win,"Error - Entry number out of bounds\n"); 60 refresh_command_win ();return; 61 } 62 63 64 65 block_bitmap_info.entry_num=entry_num; /* If it is, just change entry_num and */ 66 strcpy (buffer,"show");dispatch (buffer); /* dispatch a show command */ 67 } 68 69 void type_ext2_block_bitmap___next (char *command_line) 70 71 /* 72 73 This function passes to the next entry in the bitmap. We just call the above entry command. 74 75 */ 76 77 { 78 long entry_offset=1; 79 char *ptr,buffer [80]; 80 81 ptr=parse_word (command_line,buffer); 82 if (*ptr!=0) { 83 ptr=parse_word (ptr,buffer); 84 entry_offset=atol (buffer); 85 } 86 87 sprintf (buffer,"entry %ld",block_bitmap_info.entry_num+entry_offset); 88 dispatch (buffer); 89 } 90 91 void type_ext2_block_bitmap___prev (char *command_line) 92 93 { 94 long entry_offset=1; 95 char *ptr,buffer [80]; 96 97 ptr=parse_word (command_line,buffer); 98 if (*ptr!=0) { 99 ptr=parse_word (ptr,buffer); 100 entry_offset=atol (buffer); 101 } 102 103 sprintf (buffer,"entry %ld",block_bitmap_info.entry_num-entry_offset); 104 dispatch (buffer); 105 } 106 107 void type_ext2_block_bitmap___allocate (char *command_line) 108 109 /* 110 111 This function starts allocating block from the current position. Allocating involves setting the correct bits 112 in the bitmap. This function is a vector version of allocate_block below - We just run on the blocks that 113 we need to allocate, and call allocate_block for each one. 114 115 */ 116 117 { 118 long entry_num,num=1; 119 char *ptr,buffer [80]; 120 121 ptr=parse_word (command_line,buffer); /* Get the number of blocks to allocate */ 122 if (*ptr!=0) { 123 ptr=parse_word (ptr,buffer); 124 num=atol (buffer); 125 } 126 127 entry_num=block_bitmap_info.entry_num; 128 /* Check for limits */ 129 if (num > file_system_info.super_block.s_blocks_per_group-entry_num) { 130 wprintw (command_win,"Error - There aren't that much blocks in the group\n"); 131 refresh_command_win ();return; 132 } 133 134 while (num) { /* And call allocate_block */ 135 allocate_block (entry_num); /* for each block */ 136 num--;entry_num++; 137 } 138 139 dispatch ("show"); /* Show the result */ 140 } 141 142 void type_ext2_block_bitmap___deallocate (char *command_line) 143 144 /* This is the opposite of the above function - We call deallocate_block instead of allocate_block */ 145 146 { 147 long entry_num,num=1; 148 char *ptr,buffer [80]; 149 150 ptr=parse_word (command_line,buffer); 151 if (*ptr!=0) { 152 ptr=parse_word (ptr,buffer); 153 num=atol (buffer); 154 } 155 156 entry_num=block_bitmap_info.entry_num; 157 if (num > file_system_info.super_block.s_blocks_per_group-entry_num) { 158 wprintw (command_win,"Error - There aren't that much blocks in the group\n"); 159 refresh_command_win ();return; 160 } 161 162 while (num) { 163 deallocate_block (entry_num); 164 num--;entry_num++; 165 } 166 167 dispatch ("show"); 168 } 169 170 171 void allocate_block (long entry_num) 172 173 /* In this function we convert the bit number into the right byte and inner bit positions. */ 174 175 { 176 unsigned char bit_mask=1; 177 int byte_offset,j; 178 179 byte_offset=entry_num/8; /* Find the correct byte - entry_num/8 */ 180 /* The position inside the byte is entry_num %8 */ 181 for (j=0;j<entry_num%8;j++) 182 bit_mask*=2; /* Generate the or mask - 1 at the right place */ 183 type_data.u.buffer [byte_offset] |= bit_mask; /* And apply it */ 184 } 185 186 void deallocate_block (long entry_num) 187 188 /* This is the opposite of allocate_block above. We use an and mask instead of an or mask. */ 189 190 { 191 unsigned char bit_mask=1; 192 int byte_offset,j; 193 194 byte_offset=entry_num/8; 195 for (j=0;j<entry_num%8;j++) 196 bit_mask*=2; 197 bit_mask^=0xff; 198 199 type_data.u.buffer [byte_offset] &= bit_mask; 200 } 201 202 void type_ext2_block_bitmap___show (char *command_line) 203 204 /* 205 206 We show the bitmap as a series of bits, grouped at 8-bit intervals. We display 8 such groups on each line. 207 The current position (as known from block_bitmap_info.entry_num) is highlighted. 208 209 */ 210 211 { 212 int i,j; 213 unsigned char *ptr; 214 unsigned long block_num,entry_num; 215 216 ptr=type_data.u.buffer; 217 show_pad_info.line=0;show_pad_info.max_line=-1; 218 219 wmove (show_pad,0,0); 220 for (i=0,entry_num=0;i<file_system_info.super_block.s_blocks_per_group/8;i++,ptr++) { 221 for (j=1;j<=128;j*=2) { /* j contains the and bit mask */ 222 if (entry_num==block_bitmap_info.entry_num) { /* Highlight the current entry */ 223 wattrset (show_pad,A_REVERSE); 224 show_pad_info.line=show_pad_info.max_line-show_pad_info.display_lines/2; 225 } 226 227 if ((*ptr) & j) /* Apply the mask */ 228 wprintw (show_pad,"1"); 229 else 230 wprintw (show_pad,"0"); 231 232 if (entry_num==block_bitmap_info.entry_num) 233 wattrset (show_pad,A_NORMAL); 234 235 entry_num++; /* Pass to the next entry */ 236 } 237 wprintw (show_pad," "); 238 if (i%8==7) { /* Display 8 groups in a row */ 239 wprintw (show_pad,"\n"); 240 show_pad_info.max_line++; 241 } 242 } 243 244 refresh_show_pad (); 245 show_info (); /* Show the usual information */ 246 247 /* Show the group number */ 248 wmove (show_win,1,0); 249 wprintw (show_win,"Block bitmap of block group %ld\n",block_bitmap_info.group_num); 250 /* Show the block number */ 251 252 block_num=block_bitmap_info.entry_num+block_bitmap_info.group_num*file_system_info.super_block.s_blocks_per_group; 253 block_num+=file_system_info.super_block.s_first_data_block; 254 255 wprintw (show_win,"Status of block %ld - ",block_num); /* and the allocation status */ 256 ptr=type_data.u.buffer+block_bitmap_info.entry_num/8; 257 j=1; 258 for (i=block_bitmap_info.entry_num % 8;i>0;i--) 259 j*=2; 260 if ((*ptr) & j) 261 wprintw (show_win,"Allocated\n"); 262 else 263 wprintw (show_win,"Free\n"); 264 refresh_show_win (); 265 } 266