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