10 * NOTE! unlike strncmp, ext2_match_entry returns 1 for success, 0 for failure.
12 * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
14 static inline int tfs_match_entry (const char * const name
,
15 struct tfs_dir_entry
* de
)
19 return !strncmp(name
, de
->d_name
, strlen(name
));
22 struct tfs_dir_entry
* tfs_find_entry(struct tfs_sb_info
*sbi
,
29 struct tfs_dir_entry
*de
;
30 struct cache_struct
*cs
;
32 block
= inode
->i_data
[index
++];
35 cs
= get_cache_block(sbi
, block
);
36 de
= (struct tfs_dir_entry
*)cs
->data
;
38 while(i
< (int)inode
->i_size
) {
39 if ((char *)de
>= (char *)cs
->data
+ sbi
->s_block_size
) {
40 if ((block
= inode
->i_data
[index
++]) < sbi
->s_data_area
)
42 cs
= get_cache_block(sbi
, block
);
43 de
= (struct tfs_dir_entry
*)cs
->data
;
45 if (tfs_match_entry(dname
, de
))
54 int tfs_add_entry(struct tfs_sb_info
*sbi
, struct inode
*dir
, const char *name
, int inr
, int * dirty
)
58 struct cache_struct
*cs
;
59 struct tfs_dir_entry
*de
;
61 if (strlen(name
) > TFS_NAME_LEN
) {
62 printk("ERROR: file name too long!\n");
66 if (!(block
= dir
->i_data
[index
++]))
68 cs
= get_cache_block(sbi
, block
);
69 de
= (struct tfs_dir_entry
*)cs
->data
;
70 while (i
<= (int)dir
->i_size
) {
71 if ((void *)de
>= cs
->data
+ sbi
->s_block_size
) {
72 if (!(block
= dir
->i_data
[index
++]))
74 cs
= get_cache_block(sbi
, block
);
75 de
= (struct tfs_dir_entry
*)cs
->data
;
79 i
+= sizeof(struct tfs_dir_entry
);
86 /* allocate a new block to hold the new entry */
88 block
= tfs_alloc_block(sbi
, sbi
->s_data_area
);
89 dir
->i_data
[index
- 1] = block
;
91 printk("ERROR: allocate new block failed, out of space!\n");
94 cs
= get_cache_block(sbi
, block
);
95 de
= (struct tfs_dir_entry
*)cs
->data
;
96 memset(cs
->data
, 0, sbi
->s_block_size
);
99 * This will go through the next if sentence, since if we
100 * allocated a new entry, then 'i >= dir->i_size' would
105 if (i
>= dir
->i_size
) {
106 /* Add a new entry at last */
107 dir
->i_size
+= sizeof(struct tfs_dir_entry
);
109 /* tell the caller to update this inode */
114 * Else, we find a unused hole, this usually happens when user
115 * removes a file or directory, so we can just fill up
116 * the hole, and do not need allocate more space.
119 memcpy(de
->d_name
, name
, strlen(name
));
121 /* write the entry back to disk */
122 tfs_bwrite(sbi
, block
, cs
->data
);
128 int tfs_mkdir(struct tfs_sb_info
*sbi
, const char *path
)
131 struct inode
*parent_dir
;
135 dir
= tfs_mknod(sbi
, path
, TFS_DIR
, &parent_dir
);
137 TFS_DEBUG("mknod for path failed!\n");
141 res
= tfs_add_entry(sbi
, dir
, ".", dir
->i_ino
, &dirty
);
143 TFS_DEBUG("trying to add '.' under %s failed!\n", path
);
147 res
= tfs_add_entry(sbi
, dir
, "..", parent_dir
->i_ino
, &dirty
);
149 TFS_DEBUG("trying to add .. under %s failed!\n", path
);
154 tfs_iwrite(sbi
, dir
);
157 if (this_dir
->dd_dir
->inode
!= parent_dir
)
158 free_inode(parent_dir
);
165 /* for relative path searching */
168 DIR *tfs_opendir(struct tfs_sb_info
*sbi
, const char *path
)
170 DIR *dir
= malloc(sizeof(*dir
));
173 printk("malloc for DIR structure error!\n");
177 dir
->dd_dir
= tfs_open(sbi
, path
);
186 /* read one directry entry at a time */
187 struct dirent
* tfs_readdir(DIR *dir
)
189 struct dirent
*dirent
;
190 struct tfs_dir_entry
*de
;
191 struct cache_struct
*cs
;
192 struct file
*file
= dir
->dd_dir
;
193 struct inode
*inode
= file
->inode
;
194 struct tfs_sb_info
*sbi
= file
->sbi
;
195 int index
= file
->offset
>> sbi
->s_block_shift
;
198 if (file
->offset
>= inode
->i_size
)
200 if (!(block
= tfs_bmap(inode
, index
)))
202 cs
= get_cache_block(sbi
, block
);
203 de
= (struct tfs_dir_entry
*)(cs
->data
+ (file
->offset
& (sbi
->s_block_size
- 1)));
205 if (!(dirent
= malloc(sizeof(*dirent
)))) {
206 printk("malloc dirent structure in tfs_readdir error!\n");
209 memset(dirent
, 0, sizeof(*dirent
));
210 dirent
->d_ino
= de
->d_inode
;
211 dirent
->d_off
= file
->offset
;
212 dirent
->d_reclen
= sizeof(struct tfs_dir_entry
);
214 memcpy(dirent
->d_name
, de
->d_name
, TFS_NAME_LEN
);
216 file
->offset
+= sizeof(struct tfs_dir_entry
);
222 void tfs_closedir(DIR *dir
)
225 free_inode(dir
->dd_dir
->inode
);
231 #if 0 /* the debug part */
232 int main(int argc
, char *argv
[])