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