Makefile cleaup
[thunix.git] / fs / tfs / file.c
blob5133fa6ec5c883b05e1a21454317830b7f8e84be
1 #include <stdio.h>
2 #include <string.h>
3 #include <malloc.h>
5 #include "tfs.h"
6 #include "cache.h"
7 #include "file.h"
10 struct file *tfs_open(struct tfs_sb_info *sbi, const char *filename, uint32_t flag)
12 struct inode *inode;
13 struct file *file;
15 inode = tfs_namei(sbi, filename, flag);
16 if (!inode) {
17 printk("ERROR: open file: %s falied!\n", filename);
18 return NULL;
21 file = malloc(sizeof(*file));
22 if (!file) {
23 printk("malloc file structure error!\n");
24 free_inode(inode);
25 return NULL;
28 file->sbi = sbi;
29 file->inode = inode;
30 file->offset = 0;
32 return file;
35 uint32_t fstk_lseek(struct file *file, uint32_t off, int mode)
37 if (mode == SEEK_CUR)
38 file->offset += off;
39 else if (mode == SEEK_END)
40 file->offset = file->inode->i_size + off;
41 else if (mode == SEEK_SET)
42 file->offset = off;
43 else
44 file->offset = -1;
45 return file->offset;
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);
55 int bytes_read = 0;
57 if (!blocks)
58 return -1;
59 if (!block)
60 return -1;
61 if (file->offset >= file->inode->i_size)
62 return -1;
63 tfs_bread(sbi, block, buf);
64 bytes_read = sbi->s_block_size - bufoff;
65 memcpy(buf, buf + bufoff, bytes_read);
66 buf += bytes_read;
67 file->offset += bytes_read;
68 blocks--;
70 while (blocks--) {
71 block = file->inode->i_data[index++];
72 if (!block)
73 break;
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;
80 return bytes_read;
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;
91 int block;
92 int bufoff = file->offset & (sbi->s_block_size - 1);
93 int bytes_written = 0;
96 if (!blocks)
97 return -1;
99 block = tfs_bmap(file->inode, index++);
100 if (!block) {
101 if (index - 1 < TFS_N_BLOCKS) {
102 block = tfs_alloc_block(sbi, sbi->s_data_area);
103 if (block == -1) {
104 printk("allocating block for new file faile! OUT OF SPACE!\n");
105 return -1;
107 file->inode->i_data[index - 1] = block;
108 } else {
109 /* file too big */
110 return -1;
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 tfs_bwrite(sbi, block, cs->data);
122 blocks--;
124 while (blocks--) {
125 int bytes_need;
126 block = tfs_bmap(file->inode, index++);
127 if (!block) {
128 if (index - 1 < TFS_N_BLOCKS) {
129 block = tfs_alloc_block(sbi, sbi->s_data_area);
130 if (block == -1) {
131 printk("allocating block for new file faile: out of space!\n");
132 goto err;
134 file->inode->i_data[index - 1] = block;
135 } else {
136 /* fle too big */
137 goto err;
140 bytes_need = min(sbi->s_block_size, count);
141 cs = get_cache_block(sbi, block);
142 memcpy(cs->data, buf, bytes_need);
143 bytes_written += bytes_need;
144 file->offset += bytes_need;
145 buf += bytes_need;
146 file->inode->i_size += bytes_need;
147 tfs_bwrite(sbi, block, cs->data);
150 done:
151 tfs_iwrite(sbi, file->inode);
153 return bytes_written;
155 err:
156 bytes_written = -1;
157 goto done;
160 void tfs_close(struct file *file)
162 if (file) {
163 free_inode(file->inode);
164 free(file);