This source file includes following definitions.
- block_write
- block_read
- block_fsync
1
2
3
4
5
6
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/locks.h>
11 #include <asm/segment.h>
12 #include <asm/system.h>
13
14 extern int *blk_size[];
15 extern int *blksize_size[];
16
17 int block_write(struct inode * inode, struct file * filp, char * buf, int count)
18 {
19 int blocksize, blocksize_bits, i;
20 int block;
21 int offset;
22 int chars;
23 int written = 0;
24 unsigned int size;
25 unsigned int dev;
26 struct buffer_head * bh;
27 register char * p;
28
29 dev = inode->i_rdev;
30 blocksize = BLOCK_SIZE;
31 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
32 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
33
34 i = blocksize;
35 blocksize_bits = 0;
36 while(i != 1) {
37 blocksize_bits++;
38 i >>= 1;
39 }
40
41 block = filp->f_pos >> blocksize_bits;
42 offset = filp->f_pos & (blocksize-1);
43
44 if (blk_size[MAJOR(dev)])
45 size = (blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
46 else
47 size = INT_MAX;
48 while (count>0) {
49 if (block >= size)
50 return written;
51 chars = blocksize - offset;
52 if (chars > count)
53 chars=count;
54 if (chars == blocksize)
55 bh = getblk(dev, block, blocksize);
56 else
57 bh = breada(dev,block,block+1,block+2,-1);
58 block++;
59 if (!bh)
60 return written?written:-EIO;
61 p = offset + bh->b_data;
62 offset = 0;
63 filp->f_pos += chars;
64 written += chars;
65 count -= chars;
66 memcpy_fromfs(p,buf,chars);
67 p += chars;
68 buf += chars;
69 bh->b_uptodate = 1;
70 bh->b_dirt = 1;
71 brelse(bh);
72 }
73 return written;
74 }
75
76 #define NBUF 32
77
78 int block_read(struct inode * inode, struct file * filp, char * buf, int count)
79 {
80 unsigned int block;
81 unsigned int offset;
82 int blocksize;
83 int blocksize_bits, i;
84 unsigned int left;
85 unsigned int blocks;
86 int bhrequest, uptodate;
87 struct buffer_head ** bhb, ** bhe;
88 struct buffer_head * buflist[NBUF];
89 struct buffer_head * bhreq[NBUF];
90 unsigned int chars;
91 unsigned int size;
92 unsigned int dev;
93 int read;
94
95 dev = inode->i_rdev;
96 blocksize = BLOCK_SIZE;
97 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
98 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
99 i = blocksize;
100 blocksize_bits = 0;
101 while (i != 1) {
102 blocksize_bits++;
103 i >>= 1;
104 }
105
106 offset = filp->f_pos;
107 if (blk_size[MAJOR(dev)])
108 size = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
109 else
110 size = INT_MAX;
111
112 if (offset > size)
113 left = 0;
114 else
115 left = size - offset;
116 if (left > count)
117 left = count;
118 if (left <= 0)
119 return 0;
120 read = 0;
121 block = offset >> blocksize_bits;
122 offset &= blocksize-1;
123 size >>= blocksize_bits;
124 blocks = (left + offset + blocksize - 1) >> blocksize_bits;
125 bhb = bhe = buflist;
126 if (filp->f_reada) {
127 blocks += read_ahead[MAJOR(dev)] / (blocksize >> 9);
128 if (block + blocks > size)
129 blocks = size - block;
130 }
131
132
133
134
135
136
137
138
139
140
141
142 do {
143 bhrequest = 0;
144 uptodate = 1;
145 while (blocks) {
146 --blocks;
147 *bhb = getblk(dev, block++, blocksize);
148 if (*bhb && !(*bhb)->b_uptodate) {
149 uptodate = 0;
150 bhreq[bhrequest++] = *bhb;
151 }
152
153 if (++bhb == &buflist[NBUF])
154 bhb = buflist;
155
156
157
158 if (uptodate)
159 break;
160 if (bhb == bhe)
161 break;
162 }
163
164
165 if (bhrequest)
166 ll_rw_block(READ, bhrequest, bhreq);
167
168 do {
169 if (*bhe) {
170 wait_on_buffer(*bhe);
171 if (!(*bhe)->b_uptodate) {
172 brelse(*bhe);
173 if (++bhe == &buflist[NBUF])
174 bhe = buflist;
175 left = 0;
176 break;
177 }
178 }
179 if (left < blocksize - offset)
180 chars = left;
181 else
182 chars = blocksize - offset;
183 filp->f_pos += chars;
184 left -= chars;
185 read += chars;
186 if (*bhe) {
187 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
188 brelse(*bhe);
189 buf += chars;
190 } else {
191 while (chars-->0)
192 put_fs_byte(0,buf++);
193 }
194 offset = 0;
195 if (++bhe == &buflist[NBUF])
196 bhe = buflist;
197 } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
198 } while (left > 0);
199
200
201 while (bhe != bhb) {
202 brelse(*bhe);
203 if (++bhe == &buflist[NBUF])
204 bhe = buflist;
205 };
206 if (!read)
207 return -EIO;
208 filp->f_reada = 1;
209 return read;
210 }
211
212 int block_fsync(struct inode *inode, struct file *filp)
213 {
214 return fsync_dev (inode->i_rdev);
215 }