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