Ext
 All Files Functions
methods.c
1 
4 #include "methods.h"
5 #include "../../utils/utils.h"
6 #include "defines.h"
7 
8 uint16_t create_dir_helper(const int fd,
9  const struct superblock* superblock,
10  uint16_t parent_node_id,
11  bool is_root) {
12  uint16_t new_inode_id = reserve_inode(superblock);
13  if (new_inode_id == superblock->fs_info->inodes_count) {
14  fprintf(stderr, "Can't create more inodes. Abort!\n");
15  return superblock->fs_info->inodes_count;
16  }
17 
18  uint16_t new_block_id = reserve_block(superblock);
19  if (new_block_id == superblock->fs_info->blocks_count) {
20  fprintf(stderr, "Can't create more blocks. Abort!\n");
21  free_inode(superblock, new_inode_id);
22  return superblock->fs_info->inodes_count;
23  }
24 
25  if (is_root) {
26  parent_node_id = new_inode_id;
27  }
28 
29  struct inode inode;
30  init_inode(&inode, new_inode_id, false, superblock);
31  inode.block_ids[0] = new_block_id;
32  inode.inode_info->blocks_count = 1;
33 
34  struct block block;
35  init_block_with_records(&block, superblock, new_block_id, new_inode_id, 2);
36 
37  struct block_record dot_record;
38  init_block_record(&dot_record, superblock, new_inode_id);
39  memcpy(dot_record.path, ".", 1);
40  block.block_records[0] = dot_record;
41 
42  struct block_record two_dots_record;
43  init_block_record(&two_dots_record, superblock, parent_node_id);
44  memcpy(two_dots_record.path, "..", 2);
45  block.block_records[1] = two_dots_record;
46 
47  if (write_block(fd, &block, superblock) == -1) {
48  fprintf(stderr, "Can't write block. Abort!\n");
49  free_inode(superblock, new_inode_id);
50  free_block(superblock, new_block_id);
51  destroy_inode(&inode);
52  destruct_block(&block);
53  return superblock->fs_info->inodes_count;
54  }
55  destruct_block(&block);
56 
57  if (write_inode(fd, &inode, superblock) == -1) {
58  fprintf(stderr, "Can't write inode. Abort!\n");
59  free_inode(superblock, new_inode_id);
60  free_block(superblock, new_block_id);
61  destroy_inode(&inode);
62  return superblock->fs_info->inodes_count;
63  }
64  destroy_inode(&inode);
65 
66  if (write_super_block(fd, superblock) == -1) {
67  fprintf(stderr, "Can't write superblock. Abort!\n");
68  free_inode(superblock, new_inode_id);
69  free_block(superblock, new_block_id);
70  return superblock->fs_info->inodes_count;
71  }
72 
73  return new_inode_id;
74 }
75 
76 uint16_t create_file_helper(int fd,
77  const struct superblock* superblock,
78  uint16_t parent_node_id) {
79  uint16_t new_inode_id = reserve_inode(superblock);
80  if (new_inode_id == superblock->fs_info->inodes_count) {
81  fprintf(stderr, "Can't create more inodes. Abort!\n");
82  return superblock->fs_info->inodes_count;
83  }
84 
85  uint16_t new_block_id = reserve_block(superblock);
86  if (new_block_id == superblock->fs_info->blocks_count) {
87  fprintf(stderr, "Can't create more blocks. Abort!\n");
88  free_inode(superblock, new_inode_id);
89  return superblock->fs_info->inodes_count;
90  }
91 
92  struct inode inode;
93  init_inode(&inode, new_inode_id, true, superblock);
94  inode.block_ids[0] = new_block_id;
95  inode.inode_info->blocks_count = 1;
96 
97  struct block block;
98  init_block(&block, superblock, new_block_id, new_inode_id);
99 
100  if (write_block(fd, &block, superblock) == -1) {
101  fprintf(stderr, "Can't write block. Abort!\n");
102  free_inode(superblock, new_inode_id);
103  free_block(superblock, new_block_id);
104  destroy_inode(&inode);
105  destruct_block(&block);
106  return superblock->fs_info->inodes_count;
107  }
108  destruct_block(&block);
109 
110  if (write_inode(fd, &inode, superblock) == -1) {
111  fprintf(stderr, "Can't write inode. Abort!\n");
112  free_inode(superblock, new_inode_id);
113  free_block(superblock, new_block_id);
114  destroy_inode(&inode);
115  return superblock->fs_info->inodes_count;
116  }
117  destroy_inode(&inode);
118 
119  if (write_super_block(fd, superblock) == -1) {
120  fprintf(stderr, "Can't write superblock. Abort!\n");
121  free_inode(superblock, new_inode_id);
122  free_block(superblock, new_block_id);
123  return superblock->fs_info->inodes_count;
124  }
125 
126  return new_inode_id;
127 }
128 
129 bool get_inode_id_of_dir_rec(const int fd,
130  const char* path,
131  uint16_t* current_inode_id,
132  const struct superblock* superblock) {
133  struct inode inode;
134  if (read_inode(fd, &inode, *current_inode_id, superblock) == -1) {
135  fprintf(stderr, "Can't read inode. Abort!\n");
136  return false;
137  }
138 
139  if (inode.inode_info->is_file) {
140  fprintf(stderr, "Trying to list file. Abort!\n");
141  destroy_inode(&inode);
142  return false;
143  }
144 
145  char* current_file_name =
146  (char*) calloc(superblock->fs_info->max_path_len, sizeof(char));
147  char* path_to_parse = parse_path(path, current_file_name);
148 
149  if (strcmp(current_file_name, "/") == 0) {
150  destroy_inode(&inode);
151  free(current_file_name);
152  return true;
153  }
154 
155  struct block block;
156  read_block(fd, &block, inode.block_ids[0], superblock);
157 
158  bool founded = false;
159  uint16_t right_record_id = 0;
160 
161  for (; right_record_id < block.block_info->records_count; ++right_record_id) {
162  if (strcmp(block.block_records[right_record_id].path, current_file_name)
163  == 0) {
164  founded = true;
165  break;
166  }
167  }
168 
169  if (!founded) {
170  fprintf(stderr, "Directory doesn't exist. Abort!\n");
171  destruct_block(&block);
172  destroy_inode(&inode);
173  free(current_file_name);
174  return false;
175  }
176 
177  *current_inode_id = block.block_records[right_record_id].inode_id;
178 
179  if (path_to_parse == NULL) {
180  destruct_block(&block);
181  destroy_inode(&inode);
182  free(current_file_name);
183  return true;
184  } else {
185  bool result = get_inode_id_of_dir_rec(fd,
186  path_to_parse,
187  current_inode_id,
188  superblock);
189  destruct_block(&block);
190  destroy_inode(&inode);
191  free(current_file_name);
192  return result;
193  }
194 
195 }
196 
197 uint16_t get_inode_id_of_dir(const int fd,
198  const char* path,
199  const struct superblock* superblock) {
200  uint16_t current_inode_id = ROOT_INODE_ID;
201 
202  if (!get_inode_id_of_dir_rec(fd, path, &current_inode_id, superblock)) {
203  fprintf(stderr, "Can't find inode. Abort!\n");
204  return superblock->fs_info->inodes_count;
205  }
206 
207  return current_inode_id;
208 }
209 
210 bool is_dir_exist(const int fd,
211  struct inode* inode,
212  const char* dirname,
213  const struct superblock* superblock) {
214  struct block block;
215  if (read_block(fd, &block, inode->block_ids[0], superblock) == -1) {
216  fprintf(stderr, "Can't read block. Abort without cleaning!\n");
217  exit(EXIT_FAILURE);
218  }
219 
220  for (uint16_t record_id = 0; record_id < block.block_info->records_count;
221  ++record_id) {
222  if (strcmp(dirname, block.block_records[record_id].path) == 0) {
223  destruct_block(&block);
224  return true;
225  }
226  }
227 
228  destruct_block(&block);
229  return false;
230 }
231 
232 uint16_t get_file_inode_id(const int fd,
233  struct inode* inode,
234  const char* dirname,
235  const struct superblock* superblock) {
236  struct block block;
237  if (read_block(fd, &block, inode->block_ids[0], superblock) == -1) {
238  fprintf(stderr, "Can't read block. Abort without cleaning!\n");
239  exit(EXIT_FAILURE);
240  }
241 
242  for (uint16_t record_id = 0; record_id < block.block_info->records_count;
243  ++record_id) {
244  if (strcmp(dirname, block.block_records[record_id].path) == 0) {
245  uint16_t inode_id = block.block_records[record_id].inode_id;
246  destruct_block(&block);
247  return inode_id;
248  }
249  }
250 
251  destruct_block(&block);
252  return superblock->fs_info->inodes_count;
253 }
uint16_t get_file_inode_id(int fd, struct inode *inode, const char *dirname, const struct superblock *superblock)
Return inode_id of file.
Definition: methods.c:232
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_inode(int fd, struct inode *inode, const struct superblock *superblock)
Write inode from memory.
Definition: inode.c:83
uint16_t create_file_helper(int fd, const struct superblock *superblock, uint16_t parent_node_id)
Helper for create new file Creates file with parent = parent_node_id.
Definition: methods.c:76
uint16_t free_block(const struct superblock *superblock, uint16_t block_id)
Release block.
Definition: superblock.c:149
ssize_t write_block(int fd, struct block *block, const struct superblock *superblock)
Write.
Definition: block.c:189
ssize_t write_super_block(int fd, struct superblock *superblock)
Write sb to memory.
Definition: superblock.c:85
void destroy_inode(struct inode *inode)
Destructor of inode.
Definition: inode.c:44
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
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
Contains constants of FS.
uint16_t free_inode(const struct superblock *superblock, uint16_t inode_id)
Release inode.
Definition: superblock.c:128
uint16_t reserve_inode(const struct superblock *superblock)
Reserve free inode.
Definition: superblock.c:117
uint16_t reserve_block(const struct superblock *superblock)
Reserve block.
Definition: superblock.c:138
void destruct_block(struct block *block)
Destructor of block.
Definition: block.c:118
uint16_t create_dir_helper(int fd, const struct superblock *superblock, uint16_t parent_node_id, bool is_root)
Helper for create new directory Creates dir with parent = parent_node_id (or itself if is_root)...
Definition: methods.c:8
uint16_t get_inode_id_of_dir(int fd, const char *path, const struct superblock *superblock)
Parse path and find inode of this dir.
Definition: methods.c:197
void init_inode(struct inode *inode, uint16_t id, bool is_file, const struct superblock *superblock)
Constructor of inode.
Definition: inode.c:34
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
ssize_t read_inode(int fd, struct inode *inode, uint16_t inode_id, const struct superblock *superblock)
Read inode from memory.
Definition: inode.c:49
Contains useful methods to work with FS.
bool is_dir_exist(int fd, struct inode *inode, const char *dirname, const struct superblock *superblock)
Check if dir exists in inode.
Definition: methods.c:210