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