10 struct file
*tfs_open(struct tfs_sb_info
*sbi
, const char *filename
)
15 inode
= tfs_namei(sbi
, filename
, LOOKUP_CREATE
);
17 printf("ERROR: open file: %s falied!\n", filename
);
21 file
= malloc(sizeof(*file
));
23 printf("malloc file structure error!\n");
35 uint32_t fstk_lseek(struct file
*file
, uint32_t off
, int mode
)
39 else if (mode
== SEEK_END
)
40 file
->offset
= file
->inode
->i_size
+ off
;
41 else if (mode
== SEEK_SET
)
48 int tfs_read(struct file
*file
, void *buf
, uint32_t count
)
50 struct tfs_sb_info
*sbi
= file
->sbi
;
51 int blocks
= roundup(count
, sbi
->s_block_size
);
52 int index
= file
->offset
>> sbi
->s_block_shift
;
53 int block
= file
->inode
->i_data
[index
++];
54 int bufoff
= file
->offset
& (sbi
->s_block_size
- 1);
61 if (file
->offset
>= file
->inode
->i_size
)
63 tfs_bread(sbi
, block
, buf
);
64 bytes_read
= sbi
->s_block_size
- bufoff
;
65 memcpy(buf
, buf
+ bufoff
, bytes_read
);
67 file
->offset
+= bytes_read
;
71 block
= file
->inode
->i_data
[index
++];
74 tfs_bread(sbi
, block
, buf
);
75 bytes_read
+= sbi
->s_block_size
;
76 file
->offset
+= sbi
->s_block_size
;
77 buf
+= sbi
->s_block_size
;
84 #define min(a, b) ((a) < (b) ? a : b)
85 int tfs_write(struct file
*file
, void *buf
, uint32_t count
)
87 struct tfs_sb_info
*sbi
= file
->sbi
;
88 struct cache_struct
*cs
;
89 int blocks
= roundup(count
, sbi
->s_block_size
);
90 int index
= file
->offset
>> sbi
->s_block_shift
;
92 int bufoff
= file
->offset
& (sbi
->s_block_size
- 1);
93 int bytes_written
= 0;
99 block
= tfs_bmap(file
->inode
, index
++);
101 if (index
- 1 < TFS_N_BLOCKS
) {
102 block
= tfs_alloc_block(sbi
, sbi
->s_data_area
);
104 printf("allocating block for new file faile! OUT OF SPACE!\n");
107 file
->inode
->i_data
[index
- 1] = block
;
113 cs
= get_cache_block(sbi
, block
);
114 bytes_written
= min(sbi
->s_block_size
, count
) - bufoff
;
115 memcpy(cs
->data
+ bufoff
, buf
, bytes_written
);
116 buf
+= bytes_written
;
117 file
->offset
+= bytes_written
;
118 count
-= bytes_written
;
119 file
->inode
->i_size
+= bytes_written
;
120 /* write back to disk */
121 if (tfs_bwrite(sbi
, block
, cs
->data
) == -1) {
122 printf("disk I/O error:failed to write file data back to disk!\n");
129 block
= tfs_bmap(file
->inode
, index
++);
131 if (index
- 1 < TFS_N_BLOCKS
) {
132 block
= tfs_alloc_block(sbi
, sbi
->s_data_area
);
134 printf("allocating block for new file faile: out of space!\n");
137 file
->inode
->i_data
[index
- 1] = block
;
143 bytes_need
= min(sbi
->s_block_size
, count
);
144 cs
= get_cache_block(sbi
, block
);
145 memcpy(cs
->data
, buf
, bytes_need
);
146 bytes_written
+= bytes_need
;
147 file
->offset
+= bytes_need
;
149 file
->inode
->i_size
+= bytes_need
;
150 if (tfs_bwrite(sbi
, block
, cs
->data
) == -1) {
151 printf("disk I/O error:failed to write file data back to disk!\n");
157 tfs_iwrite(sbi
, file
->inode
);
159 return bytes_written
;
166 void tfs_close(struct file
*file
)
169 free_inode(file
->inode
);