-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiskmanager.cpp
More file actions
99 lines (84 loc) · 2.84 KB
/
Copy pathdiskmanager.cpp
File metadata and controls
99 lines (84 loc) · 2.84 KB
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
#include <iostream>
#include <cstring>
#include <string>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include "diskutils.hpp"
void create_disk(key_t key) {
int shmid = shmget(key, DISK_SIZE, IPC_CREAT | 0666);
if (shmid < 0) {
perror("Error: shmget failed");
exit(1);
}
unsigned char* VD = (unsigned char*)shmat(shmid, NULL, 0);
if (VD == (unsigned char*)-1) {
perror("Error: shmat failed");
exit(1);
}
memset(VD, 0, DISK_SIZE);
// Block 0 – Superblock
unsigned int nblocks = TOTAL_BLOCKS;
unsigned int nfreeblocks = TOTAL_BLOCKS - 266;
unsigned int root_block = ROOT_DIR_BLOCK;
memcpy(VD + (SUPERBLOCK * BLOCK_SIZE), &nblocks, 4);
memcpy(VD + (SUPERBLOCK * BLOCK_SIZE) + 4, &nfreeblocks, 4);
memcpy(VD + (SUPERBLOCK * BLOCK_SIZE) + 8, &root_block, 4);
// Bitmap (Blocks 1-8): mark blocks 0-265 as allocated
unsigned int bitmap_offset = BITMAP_START * BLOCK_SIZE;
for (int i = 0; i <= 265; i++) {
int byte_idx = i / 8;
int bit_idx = i % 8;
VD[bitmap_offset + byte_idx] |= (1 << bit_idx);
}
// Root directory (Block 265)
metadata dot = {'d', ".", 2, ROOT_DIR_BLOCK};
metadata dotdot = {'d', "..", 0, ROOT_DIR_BLOCK};
// Zero-pad the name fields properly
memset(dot.name, 0, 23);
dot.name[0] = '.';
memset(dotdot.name, 0, 23);
dotdot.name[0] = '.';
dotdot.name[1] = '.';
unsigned int root_offset = ROOT_DIR_BLOCK * BLOCK_SIZE;
memcpy(VD + root_offset, &dot, sizeof(metadata));
memcpy(VD + root_offset + sizeof(metadata), &dotdot, sizeof(metadata));
std::cout << "+++ Virtual Disk Created and Formatted successfully.\n";
std::cout << "+++ Number of blocks: " << nblocks << "\n";
std::cout << "+++ Number of free blocks: " << nfreeblocks << "\n";
std::cout << "+++ First block of root directory: " << root_block << "\n";
shmdt(VD);
}
void remove_disk(key_t key) {
int shmid = shmget(key, DISK_SIZE, 0666);
if (shmid < 0) {
perror("Error: shmget failed (disk might not exist)");
exit(1);
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("Error: shmctl IPC_RMID failed");
exit(1);
}
std::cout << "+++ Virtual Disk Removed successfully.\n";
}
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " [-create | -remove]\n";
return 1;
}
key_t key = ftok(".", 'D');
if (key == -1) {
perror("Error: ftok failed");
return 1;
}
std::string mode(argv[1]);
if(mode == "-create")
create_disk(key);
else if (mode == "-remove")
remove_disk(key);
else {
std::cerr << "***Error: Unknown mode. Use -create or -remove.\n";
return 1;
}
return 0;
}