Clean up the warning messages
[thunix.git] / fs / tfs / inode.c
blob6de7fd31b9edcc21d422c61ae791bfd6294898a3
1 #include <stdio.h>
2 #include <string.h>
3 #include <malloc.h>
5 #include "tfs.h"
6 #include "cache.h"
7 #include "dirent.h"
9 #define current_time 0
12 void free_inode(struct inode *inode)
14 if(inode->i_data)
15 free(inode->i_data);
16 free(inode);
19 struct inode *new_inode(int mode)
21 struct inode *inode;
23 inode = malloc(sizeof(*inode));
24 if (!inode) {
25 printk("malloc for new inode failed!\n");
26 return NULL;
28 memset(inode, 0, sizeof(*inode));
29 inode->i_mode = mode;
31 inode->i_atime = current_time;
32 inode->i_ctime = current_time;
33 inode->i_mtime = current_time;
35 inode->i_data = malloc(TFS_N_BLOCKS * sizeof(uint32_t *));
36 memset(inode->i_data, 0, TFS_N_BLOCKS * sizeof(uint32_t *));
37 if (!inode->i_data) {
38 printk("malloc for inode data failed!\n");
39 free(inode);
40 return NULL;
44 return inode;
49 * release all the stuff related to the inode
51 int tfs_release_inode(struct tfs_sb_info *sbi, struct inode *inode)
53 int inr = inode->i_ino;
54 int index = 0;
55 int block;
57 if (!inode) {
58 printk("ERROR: trying to free a NULL inode!\n");
59 return -1;
62 TFS_DEBUG("trying to release inode: %d\n", inr);
64 if (tfs_free_inode(sbi, inr) == -1) {
65 printk("ERROR: trying to free inode %d failed!\n", inr);
66 return -1;
69 while ((block = tfs_bmap(inode, index++)))
70 tfs_free_block(sbi, block);
72 free_inode(inode);
73 return 0;
77 struct inode * tfs_new_inode(struct tfs_sb_info *sbi, int mode)
79 struct inode *inode;
80 int inr;
82 inode = new_inode(mode);
83 if (!inode)
84 return NULL;
85 /*
86 * allocate it start from TFS_ROOT_INODE, so only the first one
87 * will get it:)
88 */
89 inr = tfs_alloc_inode(sbi, TFS_ROOT_INODE);
90 if (inr == -1) {
91 free(inode);
92 return NULL;
95 inode->i_ino = inr;
97 return inode;
100 struct inode * tfs_root_init(struct tfs_sb_info *sbi)
102 struct inode *inode;
104 inode = tfs_new_inode(sbi, TFS_DIR);
105 if (inode->i_ino != TFS_ROOT_INODE) {
106 TFS_DEBUG("root init error!\n");
107 free_inode(inode);
108 inode = NULL;
111 return inode;
115 static void tfs_fill_inode(struct inode *inode, struct tfs_inode *tinode)
117 //inode->i_mode = get_mode(tinode->i_mode);
118 inode->i_mode = tinode->i_mode;
119 inode->i_size = tinode->i_size;
120 inode->i_atime = tinode->i_atime;
121 inode->i_ctime = tinode->i_ctime;
122 inode->i_mtime = tinode->i_mtime;
123 inode->i_dtime = tinode->i_dtime;
124 inode->i_flags = tinode->i_flags;
126 memcpy(inode->i_data, tinode->i_block, TFS_N_BLOCKS * sizeof(uint32_t *));
129 static int tfs_read_inode(struct tfs_sb_info *sbi, struct tfs_inode *tinode, int inr)
131 uint32_t inode_block;
132 struct cache_struct *cs;
134 inode_block = sbi->s_inode_table + (inr - 1) / TFS_INODES_PER_BLOCK(sbi);
135 cs = get_cache_block(sbi, inode_block);
136 if (!cs)
137 return -1;
139 memcpy(tinode, cs->data + ((inr - 1) % TFS_INODES_PER_BLOCK(sbi)) * sizeof(*tinode), sizeof(*tinode));
141 return 0;
144 struct inode * tfs_iget_by_inr(struct tfs_sb_info *sbi, int inr)
146 struct inode *inode;
147 struct tfs_inode tinode;
149 if (tfs_read_inode(sbi, &tinode, inr) == -1) {
150 printk("ERROR: read disk inode error!\n");
151 return NULL;
154 inode = new_inode(0);
155 if (inode) {
156 tfs_fill_inode(inode, &tinode);
157 inode->i_ino = inr;
160 return inode;
163 struct inode *tfs_iget_root(struct tfs_sb_info *sbi)
165 return tfs_iget_by_inr(sbi, TFS_ROOT_INODE);
168 struct inode *tfs_iget(struct tfs_sb_info * sbi, char *dname, struct inode *dir)
170 struct tfs_dir_entry *de;
172 if (!tfs_find_entry(sbi, dname, dir, &de))
173 return NULL;
175 return tfs_iget_by_inr(sbi, de->d_inode);
178 static void tfs_write_inode(struct tfs_inode *tinode, struct inode *inode)
180 tinode->i_mode = inode->i_mode;
181 tinode->i_size = inode->i_size;
182 tinode->i_atime = inode->i_atime;
183 tinode->i_ctime = inode->i_ctime;
184 tinode->i_mtime = inode->i_mtime;
185 tinode->i_dtime = inode->i_dtime;
186 tinode->i_flags = inode->i_flags;
188 memcpy(tinode->i_block, inode->i_data, TFS_N_BLOCKS * sizeof(uint32_t *));
189 tinode->i_reserved[0] = 0;
193 int tfs_iwrite(struct tfs_sb_info *sbi, struct inode *inode)
195 struct cache_struct *cs;
196 struct tfs_inode *tinode;
197 uint32_t inode_block;
198 int res = 0;
200 inode_block = sbi->s_inode_table + (inode->i_ino - 1) / TFS_INODES_PER_BLOCK(sbi);
201 cs = get_cache_block(sbi, inode_block);
202 if (!cs)
203 return -1;
204 tinode = (struct tfs_inode *)cs->data + ((inode->i_ino - 1) % TFS_INODES_PER_BLOCK(sbi));
205 tfs_write_inode(tinode, inode);
206 tfs_bwrite(sbi, inode_block, cs->data);
208 return -1;
211 uint32_t tfs_bmap(struct inode *inode, int index)
213 if (index >= TFS_N_BLOCKS) {
214 printk("File too big!\n");
215 return 0;
218 return inode->i_data[index];
223 struct inode * tfs_namei(struct tfs_sb_info *sbi, const char *name, uint32_t flag)
225 struct inode *inode;
226 struct inode *parent;
227 char part[TFS_NAME_LEN + 1];
228 char *p;
230 if (*name == '/') {
231 inode = tfs_iget_root(sbi);
232 while (*name == '/')
233 name++;
234 } else {
235 inode = this_dir->dd_dir->inode;
238 parent = inode;
240 while (*name) {
241 p = part;
242 while (*name && *name != '/') {
243 if (p >= part + TFS_NAME_LEN) {
244 printk("ERROR: file name to long!\n");
245 return NULL;
247 *p++ = *name++;
249 *p = '\0';
250 while (*name && *name == '/')
251 name++;
252 if (!*name && (flag & LOOKUP_PARENT))
253 return parent;
254 inode = tfs_iget(sbi, part, parent);
255 if (!inode)
256 break;
258 if (parent != this_dir->dd_dir->inode)
259 free_inode(parent);
260 parent = inode;
261 if (!*name)
262 break;
265 if (!inode && flag & LOOKUP_CREATE) {
266 inode = __mknod(sbi, parent, part, TFS_FILE);
267 tfs_iwrite(sbi, inode);
270 return inode;
273 static const char *__strrchr(const char *s, int c)
275 const char *end = s + strlen(s) - 1;
276 while (*end != c && end >= s)
277 end--;
278 if (end < s)
279 return NULL;
280 return end;
283 const char *get_base_name(const char *path_org)
285 char *p;
286 char *path = strdup(path_org);
288 p = strrchr(path, '/');
289 if (!p) {
290 free(path);
291 return path_org;
293 /* the /linux/hello/ case */
294 if (*(p + 1) == 0) {
295 *p = 0;
296 p--;
297 while (*p != '/' && p >= path) {
298 *p = 0;
299 p--;
301 if (p < path)
302 return NULL;
305 return p + 1;
308 struct inode * __mknod(struct tfs_sb_info *sbi, struct inode *dir, const char *filename, int mode)
310 struct inode *inode;
311 struct tfs_dir_entry *de;
312 struct cache_struct *cs;
313 int dirty = 0;
315 if ((cs = tfs_find_entry(sbi, filename, dir, &de))) {
316 printk("ERROR: %s exist!\n", filename);
317 return NULL;
320 inode = tfs_new_inode(sbi, mode);
321 if (!inode)
322 return NULL;
323 inode->i_mtime = inode->i_atime = current_time;
324 tfs_iwrite(sbi, inode);
326 if (tfs_add_entry(sbi, dir, filename, inode->i_ino, &dirty) == -1) {
327 TFS_DEBUG("trying to add a new entry: %s faild!\n", filename);
328 free_inode(dir);
329 free_inode(inode);
330 return NULL;
332 if (dirty)
333 tfs_iwrite(sbi, dir);
335 return inode;
338 struct inode * tfs_mknod(struct tfs_sb_info *sbi, const char *filename, int mode, struct inode **parent_dir)
340 struct inode *dir;
341 struct inode *inode;
342 const char *base_name = get_base_name(filename);
344 dir = tfs_namei(sbi, filename, LOOKUP_PARENT);
345 if (!dir) {
346 printk("ERROR: path not exist!\n");
347 return NULL;
350 inode = __mknod(sbi, dir, base_name, mode);
351 if (parent_dir) {
352 *parent_dir = dir;
353 } else {
354 if (this_dir->dd_dir->inode != dir)
355 free_inode(dir);
358 return inode;