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