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
);
92 struct inode
* tfs_root_init(struct tfs_sb_info
*sbi
)
96 inode
= tfs_new_inode(sbi
, TFS_DIR
);
97 if (inode
->i_ino
!= TFS_ROOT_INODE
) {
98 TFS_DEBUG("root init error!\n");
107 static void tfs_fill_inode(struct inode
*inode
, struct tfs_inode
*tinode
)
109 //inode->i_mode = get_mode(tinode->i_mode);
110 inode
->i_mode
= tinode
->i_mode
;
111 inode
->i_size
= tinode
->i_size
;
112 inode
->i_atime
= tinode
->i_atime
;
113 inode
->i_ctime
= tinode
->i_ctime
;
114 inode
->i_mtime
= tinode
->i_mtime
;
115 inode
->i_dtime
= tinode
->i_dtime
;
116 inode
->i_flags
= tinode
->i_flags
;
118 memcpy(inode
->i_data
, tinode
->i_block
, TFS_N_BLOCKS
* sizeof(uint32_t *));
121 static int tfs_read_inode(struct tfs_sb_info
*sbi
, struct tfs_inode
*tinode
, int inr
)
123 uint32_t inode_block
;
124 struct cache_struct
*cs
;
126 inode_block
= sbi
->s_inode_table
+ (inr
- 1) / TFS_INODES_PER_BLOCK(sbi
);
127 cs
= get_cache_block(sbi
, inode_block
);
131 memcpy(tinode
, cs
->data
+ ((inr
- 1) % TFS_INODES_PER_BLOCK(sbi
)) * sizeof(*tinode
), sizeof(*tinode
));
136 struct inode
* tfs_iget_by_inr(struct tfs_sb_info
*sbi
, int inr
)
139 struct tfs_inode tinode
;
141 if (tfs_read_inode(sbi
, &tinode
, inr
) == -1) {
142 printf("ERROR: read disk inode error!\n");
146 inode
= new_inode(0);
148 tfs_fill_inode(inode
, &tinode
);
155 struct inode
*tfs_iget_root(struct tfs_sb_info
*sbi
)
157 return tfs_iget_by_inr(sbi
, TFS_ROOT_INODE
);
160 struct inode
*tfs_iget(struct tfs_sb_info
* sbi
, char *dname
, struct inode
*dir
)
162 struct tfs_dir_entry
*de
;
164 de
= tfs_find_entry(sbi
, dname
, dir
);
168 return tfs_iget_by_inr(sbi
, de
->d_inode
);
171 static void tfs_write_inode(struct tfs_inode
*tinode
, struct inode
*inode
)
173 tinode
->i_mode
= inode
->i_mode
;
174 tinode
->i_size
= inode
->i_size
;
175 tinode
->i_atime
= inode
->i_atime
;
176 tinode
->i_ctime
= inode
->i_ctime
;
177 tinode
->i_mtime
= inode
->i_mtime
;
178 tinode
->i_dtime
= inode
->i_dtime
;
179 tinode
->i_flags
= inode
->i_flags
;
181 memcpy(tinode
->i_block
, inode
->i_data
, TFS_N_BLOCKS
* sizeof(uint32_t *));
182 tinode
->i_reserved
[0] = 0;
186 int tfs_iwrite(struct tfs_sb_info
*sbi
, struct inode
*inode
)
188 struct cache_struct
*cs
;
189 struct tfs_inode
*tinode
;
190 uint32_t inode_block
;
193 inode_block
= sbi
->s_inode_table
+ (inode
->i_ino
- 1) / TFS_INODES_PER_BLOCK(sbi
);
194 cs
= get_cache_block(sbi
, inode_block
);
197 tinode
= (struct tfs_inode
*)cs
->data
+ ((inode
->i_ino
- 1) % TFS_INODES_PER_BLOCK(sbi
));
198 tfs_write_inode(tinode
, inode
);
199 res
= tfs_bwrite(sbi
, inode_block
, cs
->data
);
206 struct inode
* tfs_namei(struct tfs_sb_info
*sbi
, const char *name
, uint32_t flag
)
209 struct inode
*parent
;
210 char part
[TFS_NAME_LEN
+ 1];
214 inode
= tfs_iget_root(sbi
);
218 printf("ERROR: relative path searching is not supported for now!\n");
225 while (*name
&& *name
!= '/') {
226 if (p
>= part
+ TFS_NAME_LEN
) {
227 printf("ERROR: file name to long!\n");
233 while (*name
&& *name
== '/')
235 if (!*name
&& (flag
& LOOKUP_PARENT
))
237 inode
= tfs_iget(sbi
, part
, parent
);
250 static const char *__strrchr(const char *s
, int c
)
252 const char *end
= s
+ strlen(s
) - 1;
253 while (*end
!= c
&& end
>= s
)
260 static char *get_base_name(const char *path_org
)
263 char *path
= strdup(path_org
);
265 p
= strrchr(path
, '/');
268 /* the /linux/hello/ case */
272 while (*p
!= '/' && p
>= path
) {
283 struct inode
* tfs_mknod(struct tfs_sb_info
*sbi
, const char *path
, int mode
, struct inode
**parent_dir
)
287 const char *filename
= get_base_name(path
);
288 struct tfs_dir_entry
*de
;
291 dir
= tfs_namei(sbi
, filename
, LOOKUP_PARENT
);
293 printf("ERROR: path not exist!\n");
297 if (de
= tfs_find_entry(sbi
, filename
, dir
)) {
298 printf("ERROR: %s exist!\n", path
);
303 inode
= tfs_new_inode(sbi
, mode
);
306 inode
->i_mtime
= inode
->i_atime
= current_time
;
307 tfs_iwrite(sbi
, inode
);
309 if (tfs_add_entry(sbi
, dir
, filename
, inode
->i_ino
, &dirty
) == -1) {
310 TFS_DEBUG("trying to add a new entry: %s faild!\n", filename
);
316 tfs_iwrite(sbi
, dir
);
327 #if 0 /* the debug part */
328 int main(int argc
, char *argv
[])