This source file includes following definitions.
- unixify_text_buffer
- isofs_determine_filetype
- isofs_file_read
1
2
3
4
5
6
7
8
9
10
11 #include <asm/segment.h>
12 #include <asm/system.h>
13
14 #include <linux/sched.h>
15 #include <linux/iso_fs.h>
16 #include <linux/fcntl.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/stat.h>
20 #include <linux/locks.h>
21
22 #include <linux/dirent.h>
23
24 #define NBUF 16
25
26 #define MIN(a,b) (((a)<(b))?(a):(b))
27 #define MAX(a,b) (((a)>(b))?(a):(b))
28
29 #include <linux/fs.h>
30 #include <linux/iso_fs.h>
31
32 int isofs_file_read(struct inode *, struct file *, char *, int);
33
34
35
36
37
38 static struct file_operations isofs_file_operations = {
39 NULL,
40 isofs_file_read,
41 NULL,
42 NULL,
43 NULL,
44 NULL,
45 NULL,
46 NULL
47 };
48
49 struct inode_operations isofs_file_inode_operations = {
50 &isofs_file_operations,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 isofs_bmap,
63 NULL
64 };
65
66
67
68
69
70
71
72 static inline void unixify_text_buffer(char * buffer, int chars, int mode)
73 {
74 while(chars--){
75 if(*buffer == 0x1a) *buffer = 0x0a;
76 if(*buffer == 0x0d){
77 if(mode == ISOFS_FILE_TEXT_M) *buffer = 0x0a;
78 if(mode == ISOFS_FILE_TEXT) *buffer = ' ';
79 }
80 buffer++;
81 }
82 }
83
84
85
86 static void isofs_determine_filetype(struct inode * inode)
87 {
88 int block;
89 int result, i;
90 struct buffer_head * bh;
91 unsigned char * pnt;
92
93 block = isofs_bmap(inode,0);
94 if (block && (bh = bread(inode->i_dev,block, ISOFS_BUFFER_SIZE))) {
95 pnt = (char*) bh->b_data;
96 result = ISOFS_FILE_TEXT_M;
97 for(i=0;i<(inode->i_size < ISOFS_BUFFER_SIZE ? inode->i_size : ISOFS_BUFFER_SIZE);
98 i++,pnt++){
99 if(*pnt & 0x80) {result = ISOFS_FILE_BINARY; break;};
100 if(*pnt >= 0x20 || *pnt == 0x1a) continue;
101 if(*pnt == 0x0a) {result = ISOFS_FILE_TEXT; continue;};
102 if(*pnt >= 0x9 && *pnt <= 0x0d) continue;
103 result = ISOFS_FILE_BINARY;
104 break;
105 }
106 brelse(bh);
107 inode->u.isofs_i.i_file_format = result;
108 }
109 }
110
111
112
113
114
115
116
117 int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
118 {
119 int read,left,chars;
120 int block, blocks, offset;
121 int bhrequest;
122 int ra_blocks, max_block, nextblock;
123 struct buffer_head ** bhb, ** bhe;
124 struct buffer_head * bhreq[NBUF];
125 struct buffer_head * buflist[NBUF];
126
127 if (!inode) {
128 printk("isofs_file_read: inode = NULL\n");
129 return -EINVAL;
130 }
131 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
132 printk("isofs_file_read: mode = %07o\n",inode->i_mode);
133 return -EINVAL;
134 }
135 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_UNKNOWN)
136 isofs_determine_filetype(inode);
137 if (filp->f_pos > inode->i_size)
138 left = 0;
139 else
140 left = inode->i_size - filp->f_pos;
141 if (left > count)
142 left = count;
143 if (left <= 0)
144 return 0;
145 read = 0;
146 block = filp->f_pos >> ISOFS_BUFFER_BITS;
147 offset = filp->f_pos & (ISOFS_BUFFER_SIZE-1);
148 blocks = (left + offset + ISOFS_BUFFER_SIZE - 1) / ISOFS_BUFFER_SIZE;
149 bhb = bhe = buflist;
150
151 ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
152 max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
153 nextblock = -1;
154
155
156
157
158
159
160
161
162
163
164
165 do {
166 bhrequest = 0;
167 while (blocks) {
168 int uptodate;
169 --blocks;
170 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE);
171 uptodate = 1;
172 if (*bhb && !(*bhb)->b_uptodate) {
173 uptodate = 0;
174 bhreq[bhrequest++] = *bhb;
175 nextblock = (*bhb)->b_blocknr + 1;
176 };
177
178 if (++bhb == &buflist[NBUF])
179 bhb = buflist;
180
181
182
183 if(bhrequest == 0 && uptodate) break;
184
185 if (bhb == bhe)
186 break;
187 }
188
189 if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) {
190
191
192 while(ra_blocks){
193 if (block >= max_block) break;
194 if(bhrequest == NBUF) break;
195 --ra_blocks;
196 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE);
197
198 if (*bhb && !(*bhb)->b_uptodate) {
199 if((*bhb)->b_blocknr != nextblock) {
200 brelse(*bhb);
201 break;
202 };
203 nextblock = (*bhb)->b_blocknr + 1;
204 bhreq[bhrequest++] = *bhb;
205 };
206
207 if (++bhb == &buflist[NBUF])
208 bhb = buflist;
209
210 if (bhb == bhe)
211 break;
212 };
213 };
214
215 if (bhrequest)
216 ll_rw_block(READ, bhrequest, bhreq);
217
218 do{
219 if (*bhe) {
220 wait_on_buffer(*bhe);
221 if (!(*bhe)->b_uptodate) {
222 do {
223 brelse(*bhe);
224 if (++bhe == &buflist[NBUF])
225 bhe = buflist;
226 } while (bhe != bhb);
227 break;
228 }
229 }
230
231 if (left < ISOFS_BUFFER_SIZE - offset)
232 chars = left;
233 else
234 chars = ISOFS_BUFFER_SIZE - offset;
235 filp->f_pos += chars;
236 left -= chars;
237 read += chars;
238 if (*bhe) {
239 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT ||
240 inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT_M)
241 unixify_text_buffer(offset+(*bhe)->b_data,
242 chars, inode->u.isofs_i.i_file_format);
243 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
244 brelse(*bhe);
245 buf += chars;
246 } else {
247 while (chars-->0)
248 put_fs_byte(0,buf++);
249 }
250 offset = 0;
251 if (++bhe == &buflist[NBUF])
252 bhe = buflist;
253 } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
254 (left > 0));
255 } while (left > 0);
256
257
258 while (bhe != bhb) {
259 if (*bhe) brelse(*bhe);
260 if (++bhe == &buflist[NBUF])
261 bhe = buflist;
262 };
263
264 filp->f_reada = 1;
265
266 if (!read)
267 return -EIO;
268 return read;
269 }