11 void free_inode(struct inode
*inode
)
18 struct inode
*new_inode(int mode
)
22 inode
= malloc(sizeof(*inode
));
24 printf("malloc for new inode failed!\n");
27 memset(inode
, 0, sizeof(*inode
));
30 inode
->i_atime
= current_time
;
31 inode
->i_ctime
= current_time
;
32 inode
->i_mtime
= current_time
;
34 inode
->i_data
= malloc(TFS_N_BLOCKS
* sizeof(uint32_t *));
36 printf("malloc for inode data failed!\n");
47 * release all the stuff related to the inode
49 int tfs_release_inode(struct tfs_sb_info
*sbi
, struct inode
*inode
)
51 int inr
= inode
->i_ino
;
54 printf("ERROR: trying to free a NULL inode!\n");
58 TFS_DEBUG("trying to release inode: %d\n", inr
);
60 if (tfs_free_inode(sbi
, inr
) == -1) {
61 printf("ERROR: trying to free inode %d failed!\n", inr
);
69 struct inode
* tfs_new_inode(struct tfs_sb_info
*sbi
, int mode
)
74 inode
= new_inode(mode
);
78 * allocate it start from TFS_ROOT_INODE, so only the first one
81 inr
= tfs_alloc_inode(sbi
, TFS_ROOT_INODE
);
93 static void tfs_fill_inode(struct inode
*inode
, struct tfs_inode
*tinode
)
95 //inode->i_mode = get_mode(tinode->i_mode);
96 inode
->i_mode
= tinode
->i_mode
;
97 inode
->i_size
= tinode
->i_size
;
98 inode
->i_atime
= tinode
->i_atime
;
99 inode
->i_ctime
= tinode
->i_ctime
;
100 inode
->i_mtime
= tinode
->i_mtime
;
101 inode
->i_dtime
= tinode
->i_dtime
;
102 inode
->i_flags
= tinode
->i_flags
;
104 memcpy(inode
->i_data
, tinode
->i_block
, TFS_N_BLOCKS
* sizeof(uint32_t *));
107 static int tfs_read_inode(struct tfs_sb_info
*sbi
, struct tfs_inode
*tinode
, int inr
)
109 uint32_t inode_block
;
110 struct cache_struct
*cs
;
112 inode_block
= sbi
->s_inode_table
+ (inr
- 1) / TFS_INODES_PER_BLOCK(sbi
);
113 cs
= get_cache_block(sbi
, inode_block
);
117 memcpy(tinode
, cs
->data
+ ((inr
- 1) % TFS_INODES_PER_BLOCK(sbi
)) * sizeof(*tinode
), sizeof(*tinode
));
122 struct inode
* tfs_iget_by_inr(struct tfs_sb_info
*sbi
, int inr
)
125 struct tfs_inode tinode
;
127 if (tfs_read_inode(sbi
, &tinode
, inr
) == -1) {
128 printf("ERROR: read disk inode error!\n");
132 inode
= new_inode(0);
134 tfs_fill_inode(inode
, &tinode
);
141 static struct inode
*tfs_iget_root(struct tfs_sb_info
*sbi
)
143 return tfs_iget_by_inr(sbi
, TFS_ROOT_INODE
);
146 static struct inode
*tfs_iget(struct tfs_sb_info
* sbi
, char *dname
, struct inode
*dir
)
148 struct tfs_dir_entry
*de
;
150 //de = tfs_find_entry(dname, dir);
154 return tfs_iget_by_inr(sbi
, de
->d_inode
);
157 static void *tfs_write_inode(struct tfs_inode
*tinode
, struct inode
*inode
)
159 tinode
->i_mode
= inode
->i_mode
;
160 tinode
->i_size
= inode
->i_size
;
161 tinode
->i_atime
= inode
->i_atime
;
162 tinode
->i_ctime
= inode
->i_ctime
;
163 tinode
->i_mtime
= inode
->i_mtime
;
164 tinode
->i_dtime
= inode
->i_dtime
;
165 tinode
->i_flags
= inode
->i_flags
;
167 memcpy(tinode
->i_block
, inode
->i_data
, TFS_N_BLOCKS
* sizeof(uint32_t *));
168 tinode
->i_reserved
[0] = 0;
171 static void *tfs_iwrite(struct tfs_sb_info
*sbi
, struct inode
*inode
)
173 struct cache_struct
*cs
;
174 struct tfs_inode
*tinode
;
175 uint32_t inode_block
;
177 inode_block
= sbi
->s_inode_table
+ (inode
->i_ino
- 1) / TFS_INODES_PER_BLOCK(sbi
);
178 cs
= get_cache_block(sbi
, inode_block
);
179 tinode
= (struct tfs_inode
*)cs
->data
+ ((inode
->i_ino
- 1) % TFS_INODES_PER_BLOCK(sbi
));
180 tfs_write_inode(tinode
, inode
);
181 tfs_bwrite(sbi
, inode_block
, cs
->data
);
186 struct inode
* namei(struct tfs_sb_info
*sbi
, const char *name
, uint32_t flag
)
189 struct inode
*parent
;
190 char part
[TFS_NAME_LEN
+ 1];
194 inode
= tfs_iget_root(sbi
);
198 printf("ERROR: relative path searching is not supported for now!\n");
205 while (*name
&& *name
!= '/') {
206 if (p
>= part
+ TFS_NAME_LEN
) {
207 printf("ERROR: file name to long!\n");
213 while (*name
&& *name
== '/')
215 if (!*name
&& (flag
& LOOKUP_PARENT
))
217 inode
= tfs_iget(sbi
, part
, parent
);
230 static char *__strrchr(const char *s
, int c
)
232 const char *end
= s
+ strlen(s
) - 1;
233 while (*end
!= c
&& end
>= s
)
240 static char *get_base_name(const char *path_org
)
243 char *path
= strdup(path_org
);
245 p
= strrchr(path
, '/');
248 /* the /linux/hello/ case */
252 while (*p
!= '/' && p
>= path
) {
263 struct inode
* tfs_mknod(struct tfs_sb_info
*sbi
, const char *path
, int mode
)
267 const char *filename
= get_base_name(path
);
268 struct tfs_dir_entry
*de
;
271 dir
= namei(sbi
, filename
, LOOKUP_PARENT
);
273 printf("ERROR: path not exist!\n");
277 if (de
= tfs_find_entry(sbi
, filename
, dir
)) {
278 printf("ERROR: %s exist!\n", path
);
282 inode
= tfs_new_inode(sbi
, mode
);
285 inode
->i_mtime
= inode
->i_atime
= current_time
;
286 tfs_iwrite(sbi
, inode
);
288 if (tfs_add_entry(sbi
, dir
, filename
, inode
->i_ino
, &dirty
) == -1) {
289 TFS_DEBUG("trying to add a new entry: %s faild!\n", filename
);
293 tfs_iwrite(sbi
, dir
);
299 #if 0 /* the debug part */
300 int main(int argc
, char *argv
[])