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;
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 max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
158 nextblock = -1;
159
160
161
162
163
164
165
166
167
168
169
170 do {
171 bhrequest = 0;
172 while (blocks) {
173 int uptodate;
174 --blocks;
175 *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
176 uptodate = 1;
177 if (*bhb && !(*bhb)->b_uptodate) {
178 uptodate = 0;
179 bhreq[bhrequest++] = *bhb;
180 };
181
182 if (++bhb == &buflist[NBUF])
183 bhb = buflist;
184
185
186
187 if(uptodate) break;
188
189 if (bhb == bhe)
190 break;
191 }
192
193
194 if (bhrequest)
195 ll_rw_block(READ, bhrequest, bhreq);
196
197 do{
198 if (*bhe) {
199 wait_on_buffer(*bhe);
200 if (!(*bhe)->b_uptodate) {
201 brelse(*bhe);
202 if (++bhe == &buflist[NBUF])
203 bhe = buflist;
204 left = 0;
205 break;
206 }
207 }
208
209 if (left < ISOFS_BUFFER_SIZE(inode) - offset)
210 chars = left;
211 else
212 chars = ISOFS_BUFFER_SIZE(inode) - offset;
213 filp->f_pos += chars;
214 left -= chars;
215 read += chars;
216 if (*bhe) {
217 if (inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT ||
218 inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT_M)
219 unixify_to_fs(buf, offset+(*bhe)->b_data, chars,
220 inode->u.isofs_i.i_file_format);
221 else
222 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
223 brelse(*bhe);
224 buf += chars;
225 } else {
226 while (chars-->0)
227 put_fs_byte(0,buf++);
228 }
229 offset = 0;
230 if (++bhe == &buflist[NBUF])
231 bhe = buflist;
232 } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
233 (left > 0));
234 } while (left > 0);
235
236
237 while (bhe != bhb) {
238 if (*bhe) brelse(*bhe);
239 if (++bhe == &buflist[NBUF])
240 bhe = buflist;
241 };
242
243 filp->f_reada = 1;
244
245 if (!read)
246 return -EIO;
247 return read;
248 }