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