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 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 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 static int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
112 {
113 int read,left,chars;
114 int block, blocks, offset;
115 int bhrequest;
116 int ra_blocks, max_block, nextblock;
117 struct buffer_head ** bhb, ** bhe;
118 struct buffer_head * bhreq[NBUF];
119 struct buffer_head * buflist[NBUF];
120
121 if (!inode) {
122 printk("isofs_file_read: inode = NULL\n");
123 return -EINVAL;
124 }
125 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
126 printk("isofs_file_read: mode = %07o\n",inode->i_mode);
127 return -EINVAL;
128 }
129 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_UNKNOWN)
130 isofs_determine_filetype(inode);
131 if (filp->f_pos > inode->i_size)
132 left = 0;
133 else
134 left = inode->i_size - filp->f_pos;
135 if (left > count)
136 left = count;
137 if (left <= 0)
138 return 0;
139 read = 0;
140 block = filp->f_pos >> ISOFS_BUFFER_BITS;
141 offset = filp->f_pos & (ISOFS_BUFFER_SIZE-1);
142 blocks = (left + offset + ISOFS_BUFFER_SIZE - 1) / ISOFS_BUFFER_SIZE;
143 bhb = bhe = buflist;
144
145 ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
146 max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
147 nextblock = -1;
148
149
150
151
152
153
154
155
156
157
158
159 do {
160 bhrequest = 0;
161 while (blocks) {
162 int uptodate;
163 --blocks;
164 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE);
165 uptodate = 1;
166 if (*bhb && !(*bhb)->b_uptodate) {
167 uptodate = 0;
168 bhreq[bhrequest++] = *bhb;
169 nextblock = (*bhb)->b_blocknr + 1;
170 };
171
172 if (++bhb == &buflist[NBUF])
173 bhb = buflist;
174
175
176
177 if(bhrequest == 0 && uptodate) break;
178
179 if (bhb == bhe)
180 break;
181 }
182
183 if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) {
184
185
186 while(ra_blocks){
187 if (block >= max_block) break;
188 if(bhrequest == NBUF) break;
189 --ra_blocks;
190 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE);
191
192 if (*bhb && !(*bhb)->b_uptodate) {
193 if((*bhb)->b_blocknr != nextblock) {
194 brelse(*bhb);
195 break;
196 };
197 nextblock = (*bhb)->b_blocknr + 1;
198 bhreq[bhrequest++] = *bhb;
199 };
200
201 if (++bhb == &buflist[NBUF])
202 bhb = buflist;
203
204 if (bhb == bhe)
205 break;
206 };
207 };
208
209 if (bhrequest)
210 ll_rw_block(READ, bhrequest, bhreq);
211
212 do{
213 if (*bhe) {
214 wait_on_buffer(*bhe);
215 if (!(*bhe)->b_uptodate) {
216 do {
217 brelse(*bhe);
218 if (++bhe == &buflist[NBUF])
219 bhe = buflist;
220 } while (bhe != bhb);
221 break;
222 }
223 }
224
225 if (left < ISOFS_BUFFER_SIZE - offset)
226 chars = left;
227 else
228 chars = ISOFS_BUFFER_SIZE - offset;
229 filp->f_pos += chars;
230 left -= chars;
231 read += chars;
232 if (*bhe) {
233 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT ||
234 inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT_M)
235 unixify_text_buffer(offset+(*bhe)->b_data,
236 chars, inode->u.isofs_i.i_file_format);
237 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
238 brelse(*bhe);
239 buf += chars;
240 } else {
241 while (chars-->0)
242 put_fs_byte(0,buf++);
243 }
244 offset = 0;
245 if (++bhe == &buflist[NBUF])
246 bhe = buflist;
247 } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
248 (left > 0));
249 } while (left > 0);
250
251
252 while (bhe != bhb) {
253 if (*bhe) brelse(*bhe);
254 if (++bhe == &buflist[NBUF])
255 bhe = buflist;
256 };
257
258 filp->f_reada = 1;
259
260 if (!read)
261 return -EIO;
262 return read;
263 }