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 *));
36 memset(inode
->i_data
, 0, TFS_N_BLOCKS
* sizeof(uint32_t *));
38 printk("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 printk("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 printk("ERROR: trying to free inode %d failed!\n", inr
);
69 while ((block
= tfs_bmap(inode
, index
++)))
70 tfs_free_block(sbi
, block
);
77 struct inode
* tfs_new_inode(struct tfs_sb_info
*sbi
, int mode
)
82 inode
= new_inode(mode
);
86 * allocate it start from TFS_ROOT_INODE, so only the first one
89 inr
= tfs_alloc_inode(sbi
, TFS_ROOT_INODE
);
100 struct inode
* tfs_root_init(struct tfs_sb_info
*sbi
)
104 inode
= tfs_new_inode(sbi
, TFS_DIR
);
105 if (inode
->i_ino
!= TFS_ROOT_INODE
) {
106 TFS_DEBUG("root init error!\n");
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
);
139 memcpy(tinode
, cs
->data
+ ((inr
- 1) % TFS_INODES_PER_BLOCK(sbi
)) * sizeof(*tinode
), sizeof(*tinode
));
144 struct inode
* tfs_iget_by_inr(struct tfs_sb_info
*sbi
, int inr
)
147 struct tfs_inode tinode
;
149 if (tfs_read_inode(sbi
, &tinode
, inr
) == -1) {
150 printk("ERROR: read disk inode error!\n");
154 inode
= new_inode(0);
156 tfs_fill_inode(inode
, &tinode
);
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
))
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
;
200 inode_block
= sbi
->s_inode_table
+ (inode
->i_ino
- 1) / TFS_INODES_PER_BLOCK(sbi
);
201 cs
= get_cache_block(sbi
, inode_block
);
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
);
211 uint32_t tfs_bmap(struct inode
*inode
, int index
)
213 if (index
>= TFS_N_BLOCKS
) {
214 printk("File too big!\n");
218 return inode
->i_data
[index
];
223 struct inode
* tfs_namei(struct tfs_sb_info
*sbi
, const char *name
, uint32_t flag
)
226 struct inode
*parent
;
227 char part
[TFS_NAME_LEN
+ 1];
231 inode
= tfs_iget_root(sbi
);
235 inode
= this_dir
->dd_dir
->inode
;
242 while (*name
&& *name
!= '/') {
243 if (p
>= part
+ TFS_NAME_LEN
) {
244 printk("ERROR: file name to long!\n");
250 while (*name
&& *name
== '/')
252 if (!*name
&& (flag
& LOOKUP_PARENT
))
254 inode
= tfs_iget(sbi
, part
, parent
);
258 if (parent
!= this_dir
->dd_dir
->inode
)
265 if (!inode
&& flag
& LOOKUP_CREATE
) {
266 inode
= __mknod(sbi
, parent
, part
, TFS_FILE
);
267 tfs_iwrite(sbi
, 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
)
283 const char *get_base_name(const char *path_org
)
286 char *path
= strdup(path_org
);
288 p
= strrchr(path
, '/');
293 /* the /linux/hello/ case */
297 while (*p
!= '/' && p
>= path
) {
308 struct inode
* __mknod(struct tfs_sb_info
*sbi
, struct inode
*dir
, const char *filename
, int mode
)
311 struct tfs_dir_entry
*de
;
312 struct cache_struct
*cs
;
315 if ((cs
= tfs_find_entry(sbi
, filename
, dir
, &de
))) {
316 printk("ERROR: %s exist!\n", filename
);
320 inode
= tfs_new_inode(sbi
, mode
);
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
);
333 tfs_iwrite(sbi
, dir
);
338 struct inode
* tfs_mknod(struct tfs_sb_info
*sbi
, const char *filename
, int mode
, struct inode
**parent_dir
)
342 const char *base_name
= get_base_name(filename
);
344 dir
= tfs_namei(sbi
, filename
, LOOKUP_PARENT
);
346 printk("ERROR: path not exist!\n");
350 inode
= __mknod(sbi
, dir
, base_name
, mode
);
354 if (this_dir
->dd_dir
->inode
!= dir
)