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