Ext
 All Files Functions
block.c
1 
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include "../../utils/utils.h"
9 #include "block.h"
10 #include "descriptors_table.h"
11 
12 size_t max_size_of_data(const struct superblock* superblock) {
13  return superblock->fs_info->block_size - sizeof(struct block_info);
14 }
15 
16 size_t sizeof_block_record(const struct superblock* superblock) {
17  return sizeof(uint16_t) + sizeof(char) * superblock->fs_info->max_path_len;
18 }
19 
20 void init_block_info(struct block* block) {
21  block->block_info = (struct block_info*) calloc(1, sizeof(struct block_info));
22 }
23 
24 void init_block_record(struct block_record* block_record,
25  const struct superblock* superblock,
26  uint16_t inode_id) {
27  block_record->inode_id = inode_id;
28  block_record->path = (char*) calloc(superblock->fs_info->max_path_len,
29  sizeof(char));
30 }
31 
32 void destruct_block_record(struct block_record* block_record) {
33  free(block_record->path);
34 }
35 
36 ssize_t read_block_record(const int fd,
37  struct block_record* block_record,
38  const struct superblock* superblock) {
39  block_record->path = (char*) calloc(superblock->fs_info->max_path_len,
40  sizeof(char));
41 
42  uint16_t inode_id_array[1];
43  ssize_t total_read = read_while(fd, (char*) inode_id_array, sizeof(uint16_t));
44 
45  if (total_read == -1) {
46  fprintf(stderr, "%s", strerror(errno));
47  destruct_block_record(block_record);
48  return -1;
49  }
50 
51  uint16_t inode_id = inode_id_array[0];
52 
53  block_record->inode_id = inode_id;
54 
55  ssize_t readed =
56  read_while(fd, block_record->path, superblock->fs_info->max_path_len
57  * sizeof(char));
58 
59  if (readed == -1) {
60  fprintf(stderr, "%s", strerror(errno));
61  destruct_block_record(block_record);
62  return -1;
63  }
64 
65  return readed + total_read;
66 }
67 
68 ssize_t write_block_record(const int fd,
69  struct block_record* block_record,
70  const struct superblock* superblock) {
71  ssize_t total_written =
72  write_while(fd, (char*) &block_record->inode_id, sizeof(uint16_t));
73 
74  if (total_written == -1) {
75  fprintf(stderr, "%s", strerror(errno));
76  destruct_block_record(block_record);
77  return -1;
78  }
79 
80  ssize_t written = write_while(fd,
81  (char*) block_record->path,
82  superblock->fs_info->max_path_len
83  * sizeof(char));
84 
85  if (written == -1) {
86  fprintf(stderr, "%s", strerror(errno));
87  destruct_block_record(block_record);
88  return -1;
89  }
90 
91  return written + total_written;
92 }
93 
94 void init_block(struct block* block,
95  const struct superblock* superblock,
96  const uint16_t block_id,
97  const uint16_t inode_id) {
98  init_block_info(block);
99  block->block_info->block_id = block_id;
100  block->block_info->inode_id = inode_id;
101  block->block_info->data_size = 0;
102  block->block_info->records_count = 0;
103  block->data = (char*) calloc(max_size_of_data(superblock), sizeof(char));
104  block->block_records = NULL;
105 }
106 
107 void init_block_with_records(struct block* block,
108  const struct superblock* superblock,
109  const uint16_t block_id,
110  const uint16_t inode_id,
111  const uint8_t records_count) {
112  init_block(block, superblock, block_id, inode_id);
113  block->block_info->records_count = records_count;
114  block->block_records = (struct block_record*) calloc(records_count,
115  sizeof(struct block_record));
116 }
117 
118 void destruct_block(struct block* block) {
119  if (block->data != NULL) {
120  free(block->data);
121  }
122 
123  for (uint8_t i = 0; i < block->block_info->records_count; ++i) {
124  destruct_block_record(block->block_records + i);
125  }
126  if (block->block_records != NULL) {
127  free(block->block_records);
128  }
129 
130  free(block->block_info);
131 }
132 
133 ssize_t read_block(const int fd,
134  struct block* block,
135  uint16_t block_id,
136  const struct superblock* superblock) {
137  init_block_info(block);
138  block->data = (char*) calloc(max_size_of_data(superblock), sizeof(char));
139  block->block_records = NULL;
140  lseek(fd,
141  sizeof_superblock(superblock) + sizeof_descriptors_table(superblock)
142  + sizeof_inodes_block(superblock)
143  + block_id * superblock->fs_info->block_size,
144  SEEK_SET);
145 
146  ssize_t total_read =
147  read_while(fd, (char*) block->block_info, sizeof(struct block_info));
148 
149  if (total_read == -1) {
150  fprintf(stderr, "%s", strerror(errno));
151  free(block->block_info);
152  free(block->data);
153  return -1;
154  }
155 
156  if (block->block_info->records_count != 0
157  && block->block_info->data_size != 0) {
158  fprintf(stderr, "Block with data and records!");
159  destruct_block(block);
160  return -1;
161  }
162 
163  if (block->block_info->records_count != 0) {
164  block->block_records =
165  (struct block_record*) calloc(block->block_info->records_count,
166  sizeof(struct block_record));
167 
168  for (uint8_t i = 0; i < block->block_info->records_count; ++i) {
169  ssize_t
170  readed = read_block_record(fd, block->block_records + i, superblock);
171  if (readed == -1) {
172  fprintf(stderr, "%s", strerror(errno));
173  destruct_block(block);
174  return -1;
175  }
176 
177  total_read += readed;
178  }
179 
180  return total_read;
181  } else if (block->block_info->data_size != 0) {
182  ssize_t readed = read_while(fd, block->data, block->block_info->data_size);
183  total_read += readed;
184  }
185 
186  return total_read;
187 }
188 
189 ssize_t write_block(const int fd,
190  struct block* block,
191  const struct superblock* superblock) {
192  lseek(fd,
193  sizeof_superblock(superblock) + sizeof_descriptors_table(superblock)
194  + sizeof_inodes_block(superblock)
195  + block->block_info->block_id * superblock->fs_info->block_size,
196  SEEK_SET);
197 
198  ssize_t total_written =
199  write_while(fd, (char*) block->block_info, sizeof(struct block_info));
200 
201  if (total_written == -1) {
202  fprintf(stderr, "%s", strerror(errno));
203  return -1;
204  }
205 
206  if (block->block_info->records_count != 0
207  && block->block_info->data_size != 0) {
208  fprintf(stderr, "Block with data and records!");
209  return -1;
210  }
211 
212  if (block->block_records != 0) {
213  for (uint8_t i = 0; i < block->block_info->records_count; ++i) {
214  ssize_t written =
215  write_block_record(fd, block->block_records + i, superblock);
216 
217  if (written == -1) {
218  fprintf(stderr, "%s", strerror(errno));
219  destruct_block(block);
220  return -1;
221  }
222 
223  total_written += written;
224  }
225  } else if (block->block_info->data_size != 0 && block->data != NULL) {
226  ssize_t written = write_while(fd,
227  block->data,
228  max_size_of_data(superblock) * sizeof(char));
229 
230  if (written == -1) {
231  fprintf(stderr, "%s", strerror(errno));
232  return -1;
233  }
234 
235  total_written += written;
236  }
237 
238  return total_written;
239 }
240 
241 uint8_t get_max_records_count(const struct superblock* superblock) {
242  return (uint8_t) (superblock->fs_info->block_size - sizeof(struct block_info))
243  / sizeof_block_record(superblock);
244 }
245 
246 uint32_t get_max_data_in_block(const struct superblock* superblock) {
247  return superblock->fs_info->block_size - sizeof(struct block_info);
248 }
249 
250 uint32_t get_max_data_size_of_all_blocks(const struct superblock* superblock) {
251  return (uint32_t) (get_max_data_in_block(superblock))
252  * superblock->fs_info->blocks_count_in_inode;
253 }
254 
255 uint32_t get_remain_data(const struct block* block,
256  const struct superblock* superblock) {
257  if (block->block_info->records_count > 0) {
258  return 0;
259  }
260 
261  return get_max_data_in_block(superblock) - block->block_info->data_size;
262 }
263 
void init_block_with_records(struct block *block, const struct superblock *superblock, uint16_t block_id, uint16_t inode_id, uint8_t records_count)
Constructor of block Init block and set its block_records array to bloc_record[records_count].
Definition: block.c:107
ssize_t write_block(int fd, struct block *block, const struct superblock *superblock)
Write.
Definition: block.c:189
uint32_t get_max_data_size_of_all_blocks(const struct superblock *superblock)
Definition: block.c:250
void init_block_record(struct block_record *block_record, const struct superblock *superblock, uint16_t inode_id)
Constructor of block record Init block record and set its path array to char[max_len_path].
Definition: block.c:24
void destruct_block_record(struct block_record *block_record)
Destructor of block_record.
Definition: block.c:32
ssize_t read_block(int fd, struct block *block, uint16_t block_id, const struct superblock *superblock)
Read block from memory.
Definition: block.c:133
int read_while(int fd, char *buffer, size_t to_read)
Properly reading from memory.
Definition: utils.c:23
uint32_t get_remain_data(const struct block *block, const struct superblock *superblock)
Definition: block.c:255
Contains descriptors_table struct and its methods.
int write_while(int fd, const char *buffer, size_t to_write)
Properly writing to memory.
Definition: utils.c:38
uint16_t sizeof_inodes_block(const struct superblock *superblock)
Calculate size of block of all inodes.
Definition: inode.c:111
void destruct_block(struct block *block)
Destructor of block.
Definition: block.c:118
uint8_t get_max_records_count(const struct superblock *superblock)
Definition: block.c:241
uint32_t get_max_data_in_block(const struct superblock *superblock)
Definition: block.c:246
uint16_t sizeof_descriptors_table(const struct superblock *superblock)
Sizeof descriptors_table.
size_t sizeof_superblock(const struct superblock *superblock)
Definition: superblock.c:23
void init_block(struct block *block, const struct superblock *superblock, uint16_t block_id, uint16_t inode_id)
Constructor of block Init block and set its block_records array to nullptr.
Definition: block.c:94
Contains block struct and its methods.