12 void free_inode(struct inode
*inode
)
19 struct inode
*new_inode(int mode
)
23 inode
= malloc(sizeof(*inode
));
25 printf("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 *));
36 memset(inode
->i_data
, 0, TFS_N_BLOCKS
* sizeof(uint32_t *));
38 printf("malloc for inode data failed!\n");
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
;
58 printf("ERROR: trying to free a NULL inode!\n");
62 TFS_DEBUG("trying to release inode: %d\n", inr
);
64 if (tfs_free_inode(sbi
, inr
) == -1) {
65 printf("ERROR: trying to free inode %d failed!\n", inr
);
69 while ((block
= tfs_bmap(inode
, index
++)))
70 tfs_free_block(sbi
, block
);
76 struct inode
* tfs_new_inode(struct tfs_sb_info
*sbi
, int mode
)
81 inode
= new_inode(mode
);
85 * allocate it start from TFS_ROOT_INODE, so only the first one
88 inr
= tfs_alloc_inode(sbi
, TFS_ROOT_INODE
);
99 struct inode
* tfs_root_init(struct tfs_sb_info
*sbi
)
103 inode
= tfs_new_inode(sbi
, TFS_DIR
);
104 if (inode
->i_ino
!= TFS_ROOT_INODE
) {
105 TFS_DEBUG("root init error!\n");
114 static void tfs_fill_inode(struct inode
*inode
, struct tfs_inode
*tinode
)
116 //inode->i_mode = get_mode(tinode->i_mode);
117 inode
->i_mode
= tinode
->i_mode
;
118 inode
->i_size
= tinode
->i_size
;
119 inode
->i_atime
= tinode
->i_atime
;
120 inode
->i_ctime
= tinode
->i_ctime
;
121 inode
->i_mtime
= tinode
->i_mtime
;
122 inode
->i_dtime
= tinode
->i_dtime
;
123 inode
->i_flags
= tinode
->i_flags
;
125 memcpy(inode
->i_data
, tinode
->i_block
, TFS_N_BLOCKS
* sizeof(uint32_t *));
128 static int tfs_read_inode(struct tfs_sb_info
*sbi
, struct tfs_inode
*tinode
, int inr
)
130 uint32_t inode_block
;
131 struct cache_struct
*cs
;
133 inode_block
= sbi
->s_inode_table
+ (inr
- 1) / TFS_INODES_PER_BLOCK(sbi
);
134 cs
= get_cache_block(sbi
, inode_block
);
138 memcpy(tinode
, cs
->data
+ ((inr
- 1) % TFS_INODES_PER_BLOCK(sbi
)) * sizeof(*tinode
), sizeof(*tinode
));
143 struct inode
* tfs_iget_by_inr(struct tfs_sb_info
*sbi
, int inr
)
146 struct tfs_inode tinode
;
148 if (tfs_read_inode(sbi
, &tinode
, inr
) == -1) {
149 printf("ERROR: read disk inode error!\n");
153 inode
= new_inode(0);
155 tfs_fill_inode(inode
, &tinode
);
162 struct inode
*tfs_iget_root(struct tfs_sb_info
*sbi
)
164 return tfs_iget_by_inr(sbi
, TFS_ROOT_INODE
);
167 struct inode
*tfs_iget(struct tfs_sb_info
* sbi
, char *dname
, struct inode
*dir
)
169 struct tfs_dir_entry
*de
;
171 if (!tfs_find_entry(sbi
, dname
, dir
, &de
))
174 return tfs_iget_by_inr(sbi
, de
->d_inode
);
177 static void tfs_write_inode(struct tfs_inode
*tinode
, struct inode
*inode
)
179 tinode
->i_mode
= inode
->i_mode
;
180 tinode
->i_size
= inode
->i_size
;
181 tinode
->i_atime
= inode
->i_atime
;
182 tinode
->i_ctime
= inode
->i_ctime
;
183 tinode
->i_mtime
= inode
->i_mtime
;
184 tinode
->i_dtime
= inode
->i_dtime
;
185 tinode
->i_flags
= inode
->i_flags
;
187 memcpy(tinode
->i_block
, inode
->i_data
, TFS_N_BLOCKS
* sizeof(uint32_t *));
188 tinode
->i_reserved
[0] = 0;
192 int tfs_iwrite(struct tfs_sb_info
*sbi
, struct inode
*inode
)
194 struct cache_struct
*cs
;
195 struct tfs_inode
*tinode
;
196 uint32_t inode_block
;
199 inode_block
= sbi
->s_inode_table
+ (inode
->i_ino
- 1) / TFS_INODES_PER_BLOCK(sbi
);
200 cs
= get_cache_block(sbi
, inode_block
);
203 tinode
= (struct tfs_inode
*)cs
->data
+ ((inode
->i_ino
- 1) % TFS_INODES_PER_BLOCK(sbi
));
204 tfs_write_inode(tinode
, inode
);
205 res
= tfs_bwrite(sbi
, inode_block
, cs
->data
);
210 uint32_t tfs_bmap(struct inode
*inode
, int index
)
212 if (index
>= TFS_N_BLOCKS
) {
213 printf("File too big!\n");
217 return inode
->i_data
[index
];
222 struct inode
* tfs_namei(struct tfs_sb_info
*sbi
, const char *name
, uint32_t flag
)
225 struct inode
*parent
;
226 char part
[TFS_NAME_LEN
+ 1];
230 inode
= tfs_iget_root(sbi
);
234 inode
= this_dir
->dd_dir
->inode
;
241 while (*name
&& *name
!= '/') {
242 if (p
>= part
+ TFS_NAME_LEN
) {
243 printf("ERROR: file name to long!\n");
249 while (*name
&& *name
== '/')
251 if (!*name
&& (flag
& LOOKUP_PARENT
))
253 inode
= tfs_iget(sbi
, part
, parent
);
257 if (parent
!= this_dir
->dd_dir
->inode
)
264 if (!inode
&& flag
& LOOKUP_CREATE
) {
265 inode
= __mknod(sbi
, parent
, part
, TFS_FILE
);
266 tfs_iwrite(sbi
, inode
);
272 static const char *__strrchr(const char *s
, int c
)
274 const char *end
= s
+ strlen(s
) - 1;
275 while (*end
!= c
&& end
>= s
)
282 const char *get_base_name(const char *path_org
)
285 char *path
= strdup(path_org
);
287 p
= strrchr(path
, '/');
292 /* the /linux/hello/ case */
296 while (*p
!= '/' && p
>= path
) {
307 struct inode
* __mknod(struct tfs_sb_info
*sbi
, struct inode
*dir
, const char *filename
, int mode
)
310 struct tfs_dir_entry
*de
;
311 struct cache_struct
*cs
;
314 if (cs
= tfs_find_entry(sbi
, filename
, dir
, &de
)) {
315 printf("ERROR: %s exist!\n", filename
);
319 inode
= tfs_new_inode(sbi
, mode
);
322 inode
->i_mtime
= inode
->i_atime
= current_time
;
323 tfs_iwrite(sbi
, inode
);
325 if (tfs_add_entry(sbi
, dir
, filename
, inode
->i_ino
, &dirty
) == -1) {
326 TFS_DEBUG("trying to add a new entry: %s faild!\n", filename
);
332 tfs_iwrite(sbi
, dir
);
337 struct inode
* tfs_mknod(struct tfs_sb_info
*sbi
, const char *filename
, int mode
, struct inode
**parent_dir
)
341 const char *base_name
= get_base_name(filename
);
343 dir
= tfs_namei(sbi
, filename
, LOOKUP_PARENT
);
345 printf("ERROR: path not exist!\n");
349 inode
= __mknod(sbi
, dir
, base_name
, mode
);
353 if (this_dir
->dd_dir
->inode
!= dir
)
361 #if 0 /* the debug part */
362 int main(int argc
, char *argv
[])