12 void free_inode(struct inode
*inode
)
19 struct inode
*new_inode(int mode
)
23 inode
= malloc(sizeof(*inode
));
25 printk("malloc for new inode failed!\n");
28 memset(inode
, 0, sizeof(*inode
));
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 *));
37 printk("malloc for inode data failed!\n");
48 * release all the stuff related to the inode
50 int tfs_release_inode(struct tfs_sb_info
*sbi
, struct inode
*inode
)
52 int inr
= inode
->i_ino
;
57 printk("ERROR: trying to free a NULL inode!\n");
61 TFS_DEBUG("trying to release inode: %d\n", inr
);
63 if (tfs_free_inode(sbi
, inr
) == -1) {
64 printk("ERROR: trying to free inode %d failed!\n", inr
);
68 while ((block
= tfs_bmap(inode
, index
++)))
69 tfs_free_block(sbi
, block
);
75 struct inode
* tfs_new_inode(struct tfs_sb_info
*sbi
, int mode
)
80 inode
= new_inode(mode
);
84 * allocate it start from TFS_ROOT_INODE, so only the first one
87 inr
= tfs_alloc_inode(sbi
, TFS_ROOT_INODE
);
98 struct inode
* tfs_root_init(struct tfs_sb_info
*sbi
)
102 inode
= tfs_new_inode(sbi
, TFS_DIR
);
103 if (inode
->i_ino
!= TFS_ROOT_INODE
) {
104 TFS_DEBUG("root init error!\n");
113 static void tfs_fill_inode(struct inode
*inode
, struct tfs_inode
*tinode
)
115 //inode->i_mode = get_mode(tinode->i_mode);
116 inode
->i_mode
= tinode
->i_mode
;
117 inode
->i_size
= tinode
->i_size
;
118 inode
->i_atime
= tinode
->i_atime
;
119 inode
->i_ctime
= tinode
->i_ctime
;
120 inode
->i_mtime
= tinode
->i_mtime
;
121 inode
->i_dtime
= tinode
->i_dtime
;
122 inode
->i_flags
= tinode
->i_flags
;
124 memcpy(inode
->i_data
, tinode
->i_block
, TFS_N_BLOCKS
* sizeof(uint32_t *));
127 static int tfs_read_inode(struct tfs_sb_info
*sbi
, struct tfs_inode
*tinode
, int inr
)
129 uint32_t inode_block
;
130 struct cache_struct
*cs
;
132 inode_block
= sbi
->s_inode_table
+ (inr
- 1) / TFS_INODES_PER_BLOCK(sbi
);
133 cs
= get_cache_block(sbi
, inode_block
);
137 memcpy(tinode
, cs
->data
+ ((inr
- 1) % TFS_INODES_PER_BLOCK(sbi
)) * sizeof(*tinode
), sizeof(*tinode
));
142 struct inode
* tfs_iget_by_inr(struct tfs_sb_info
*sbi
, int inr
)
145 struct tfs_inode tinode
;
147 if (tfs_read_inode(sbi
, &tinode
, inr
) == -1) {
148 printk("ERROR: read disk inode error!\n");
152 inode
= new_inode(0);
154 tfs_fill_inode(inode
, &tinode
);
161 struct inode
*tfs_iget_root(struct tfs_sb_info
*sbi
)
163 return tfs_iget_by_inr(sbi
, TFS_ROOT_INODE
);
166 struct inode
*tfs_iget(struct tfs_sb_info
* sbi
, char *dname
, struct inode
*dir
)
168 struct tfs_dir_entry
*de
;
170 if (!tfs_find_entry(sbi
, dname
, dir
, &de
))
173 return tfs_iget_by_inr(sbi
, de
->d_inode
);
176 static void tfs_write_inode(struct tfs_inode
*tinode
, struct inode
*inode
)
178 tinode
->i_mode
= inode
->i_mode
;
179 tinode
->i_size
= inode
->i_size
;
180 tinode
->i_atime
= inode
->i_atime
;
181 tinode
->i_ctime
= inode
->i_ctime
;
182 tinode
->i_mtime
= inode
->i_mtime
;
183 tinode
->i_dtime
= inode
->i_dtime
;
184 tinode
->i_flags
= inode
->i_flags
;
186 memcpy(tinode
->i_block
, inode
->i_data
, TFS_N_BLOCKS
* sizeof(uint32_t *));
187 tinode
->i_reserved
[0] = 0;
191 int tfs_iwrite(struct tfs_sb_info
*sbi
, struct inode
*inode
)
193 struct cache_struct
*cs
;
194 struct tfs_inode
*tinode
;
195 uint32_t inode_block
;
198 inode_block
= sbi
->s_inode_table
+ (inode
->i_ino
- 1) / TFS_INODES_PER_BLOCK(sbi
);
199 cs
= get_cache_block(sbi
, inode_block
);
202 tinode
= (struct tfs_inode
*)cs
->data
+ ((inode
->i_ino
- 1) % TFS_INODES_PER_BLOCK(sbi
));
203 tfs_write_inode(tinode
, inode
);
204 tfs_bwrite(sbi
, inode_block
, cs
->data
);
209 uint32_t tfs_bmap(struct inode
*inode
, int index
)
211 if (index
>= TFS_N_BLOCKS
) {
212 printk("File too big!\n");
216 return inode
->i_data
[index
];
221 struct inode
* tfs_namei(struct tfs_sb_info
*sbi
, const char *name
, uint32_t flag
)
224 struct inode
*parent
;
225 char part
[TFS_NAME_LEN
+ 1];
229 inode
= tfs_iget_root(sbi
);
233 inode
= this_dir
->dd_dir
->inode
;
240 while (*name
&& *name
!= '/') {
241 if (p
>= part
+ TFS_NAME_LEN
) {
242 printk("ERROR: file name to long!\n");
248 while (*name
&& *name
== '/')
250 if (!*name
&& (flag
& LOOKUP_PARENT
))
252 inode
= tfs_iget(sbi
, part
, parent
);
256 if (parent
!= this_dir
->dd_dir
->inode
)
263 if (!inode
&& flag
& LOOKUP_CREATE
) {
264 inode
= __mknod(sbi
, parent
, part
, TFS_FILE
);
265 tfs_iwrite(sbi
, inode
);
271 static const char *__strrchr(const char *s
, int c
)
273 const char *end
= s
+ strlen(s
) - 1;
274 while (*end
!= c
&& end
>= s
)
281 const char *get_base_name(const char *path_org
)
284 char *path
= strdup(path_org
);
286 p
= strrchr(path
, '/');
291 /* the /linux/hello/ case */
295 while (*p
!= '/' && p
>= path
) {
306 struct inode
* __mknod(struct tfs_sb_info
*sbi
, struct inode
*dir
, const char *filename
, int mode
)
309 struct tfs_dir_entry
*de
;
310 struct cache_struct
*cs
;
313 if (cs
= tfs_find_entry(sbi
, filename
, dir
, &de
)) {
314 printk("ERROR: %s exist!\n", filename
);
318 inode
= tfs_new_inode(sbi
, mode
);
321 inode
->i_mtime
= inode
->i_atime
= current_time
;
322 tfs_iwrite(sbi
, inode
);
324 if (tfs_add_entry(sbi
, dir
, filename
, inode
->i_ino
, &dirty
) == -1) {
325 TFS_DEBUG("trying to add a new entry: %s faild!\n", filename
);
331 tfs_iwrite(sbi
, dir
);
336 struct inode
* tfs_mknod(struct tfs_sb_info
*sbi
, const char *filename
, int mode
, struct inode
**parent_dir
)
340 const char *base_name
= get_base_name(filename
);
342 dir
= tfs_namei(sbi
, filename
, LOOKUP_PARENT
);
344 printk("ERROR: path not exist!\n");
348 inode
= __mknod(sbi
, dir
, base_name
, mode
);
352 if (this_dir
->dd_dir
->inode
!= dir
)
360 #if 0 /* the debug part */
361 int main(int argc
, char *argv
[])