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
type_ext2_block_bitmap___entry(char * command_line)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
type_ext2_block_bitmap___next(char * command_line)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
type_ext2_block_bitmap___prev(char * command_line)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
type_ext2_block_bitmap___allocate(char * command_line)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
type_ext2_block_bitmap___deallocate(char * command_line)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
allocate_block(long entry_num)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
deallocate_block(long entry_num)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
type_ext2_block_bitmap___show(char * command_line)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