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 #ifdef MODULE
12 #include <linux/module.h>
13 #endif
14
15 #include <asm/segment.h>
16 #include <asm/system.h>
17
18 #include <linux/sched.h>
19 #include <linux/iso_fs.h>
20 #include <linux/fcntl.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/stat.h>
24 #include <linux/locks.h>
25
26 #include <linux/dirent.h>
27
28 #define NBUF 32
29
30 #define MIN(a,b) (((a)<(b))?(a):(b))
31 #define MAX(a,b) (((a)>(b))?(a):(b))
32
33 #include <linux/fs.h>
34 #include <linux/iso_fs.h>
35
36 static int isofs_file_read(struct inode *, struct file *, char *, int);
37
38
39
40
41
42 static struct file_operations isofs_file_operations = {
43 NULL,
44 isofs_file_read,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 generic_mmap,
50 NULL,
51 NULL,
52 NULL
53 };
54
55 struct inode_operations isofs_file_inode_operations = {
56 &isofs_file_operations,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 isofs_bmap,
69 NULL,
70 NULL
71 };
72
73
74
75
76
77
78
79 static inline void unixify_to_fs(char * outbuf, char * buffer, int chars,
80 int mode)
81 {
82 char outchar;
83
84 while(chars--){
85 outchar = *buffer;
86 if(outchar == 0x1a) outchar = 0x0a;
87 if(outchar == 0x0d){
88 if(mode == ISOFS_FILE_TEXT_M) outchar = 0x0a;
89 if(mode == ISOFS_FILE_TEXT) outchar = ' ';
90 }
91 put_user(outchar, outbuf++);
92 buffer++;
93 }
94 }
95
96
97
98 static void isofs_determine_filetype(struct inode * inode)
99 {
100 int block;
101 int result, i;
102 struct buffer_head * bh;
103 unsigned char * pnt;
104
105 block = isofs_bmap(inode,0);
106 if (block && (bh = bread(inode->i_dev,block, ISOFS_BUFFER_SIZE(inode)))) {
107 pnt = (unsigned char *) bh->b_data;
108 result = ISOFS_FILE_TEXT_M;
109 for(i=0;i<(inode->i_size < ISOFS_BUFFER_SIZE(inode) ? inode->i_size : ISOFS_BUFFER_SIZE(inode));
110 i++,pnt++){
111 if(*pnt & 0x80) {result = ISOFS_FILE_BINARY; break;};
112 if(*pnt >= 0x20 || *pnt == 0x1a) continue;
113 if(*pnt == 0x0a) {result = ISOFS_FILE_TEXT; continue;};
114 if(*pnt >= 0x9 && *pnt <= 0x0d) continue;
115 result = ISOFS_FILE_BINARY;
116 break;
117 }
118 brelse(bh);
119 inode->u.isofs_i.i_file_format = result;
120 }
121 }
122
123 static int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
124 {
125 int read,left,chars;
126 int block, blocks, offset, total_blocks;
127 int bhrequest;
128 int ra_blocks, max_block, nextblock;
129 struct buffer_head ** bhb, ** bhe;
130 struct buffer_head * bhreq[NBUF];
131 struct buffer_head * buflist[NBUF];
132
133 if (!inode) {
134 printk("isofs_file_read: inode = NULL\n");
135 return -EINVAL;
136 }
137 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
138 printk("isofs_file_read: mode = %07o\n",inode->i_mode);
139 return -EINVAL;
140 }
141 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_UNKNOWN)
142 isofs_determine_filetype(inode);
143 if (filp->f_pos > inode->i_size)
144 left = 0;
145 else
146 left = inode->i_size - filp->f_pos;
147 if (left > count)
148 left = count;
149 if (left <= 0)
150 return 0;
151 read = 0;
152 block = filp->f_pos >> ISOFS_BUFFER_BITS(inode);
153 offset = (inode->u.isofs_i.i_first_extent + filp->f_pos)
154 & (ISOFS_BUFFER_SIZE(inode)-1);
155 blocks = (left + offset + ISOFS_BUFFER_SIZE(inode) - 1) / ISOFS_BUFFER_SIZE(inode);
156 bhb = bhe = buflist;
157
158 ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
159 if(ra_blocks > blocks) blocks = ra_blocks;
160
161
162
163
164
165
166
167
168 total_blocks = (inode->i_size + (1 << ISOFS_BUFFER_BITS(inode)) - 1)
169 >> ISOFS_BUFFER_BITS(inode);
170 if (block + blocks > total_blocks)
171 blocks = total_blocks - block;
172
173 max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
174 nextblock = -1;
175
176
177
178
179
180
181
182
183
184
185
186 do {
187 bhrequest = 0;
188 while (blocks) {
189 int uptodate;
190 --blocks;
191 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
192 uptodate = 1;
193 if (*bhb && !(*bhb)->b_uptodate) {
194 uptodate = 0;
195 bhreq[bhrequest++] = *bhb;
196 };
197
198 if (++bhb == &buflist[NBUF])
199 bhb = buflist;
200
201
202
203 if(uptodate) break;
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 brelse(*bhe);
218 if (++bhe == &buflist[NBUF])
219 bhe = buflist;
220 left = 0;
221 break;
222 }
223 }
224
225 if (left < ISOFS_BUFFER_SIZE(inode) - offset)
226 chars = left;
227 else
228 chars = ISOFS_BUFFER_SIZE(inode) - 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_to_fs(buf, offset+(*bhe)->b_data, chars,
236 inode->u.isofs_i.i_file_format);
237 else
238 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
239 brelse(*bhe);
240 buf += chars;
241 } else {
242 while (chars-->0)
243 put_user(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 }