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 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 = 0x7fffffff;
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 16
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 int blocks, left;
85 int bhrequest, uptodate;
86 struct buffer_head ** bhb, ** bhe;
87 struct buffer_head * buflist[NBUF];
88 struct buffer_head * bhreq[NBUF];
89 unsigned int chars;
90 unsigned int size;
91 unsigned int dev;
92 int read;
93
94 dev = inode->i_rdev;
95 blocksize = BLOCK_SIZE;
96 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
97 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
98 i = blocksize;
99 blocksize_bits = 0;
100 while (i != 1) {
101 blocksize_bits++;
102 i >>= 1;
103 }
104
105 offset = filp->f_pos;
106 if (blk_size[MAJOR(dev)])
107 size = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
108 else
109 size = 0x7fffffff;
110
111 if (offset > size)
112 left = 0;
113 else
114 left = size - offset;
115 if (left > count)
116 left = count;
117 if (left <= 0)
118 return 0;
119 read = 0;
120 block = offset >> blocksize_bits;
121 offset &= blocksize-1;
122 size >>= blocksize_bits;
123 blocks = (left + offset + blocksize - 1) >> blocksize_bits;
124 bhb = bhe = buflist;
125 if (filp->f_reada) {
126 blocks += read_ahead[MAJOR(dev)] / (blocksize >> 9);
127 if (block + blocks > size)
128 blocks = size - block;
129 }
130
131
132
133
134
135
136
137
138
139
140
141 do {
142 bhrequest = 0;
143 uptodate = 1;
144 while (blocks) {
145 --blocks;
146 *bhb = getblk(dev, block++, blocksize);
147 if (*bhb && !(*bhb)->b_uptodate) {
148 uptodate = 0;
149 bhreq[bhrequest++] = *bhb;
150 }
151
152 if (++bhb == &buflist[NBUF])
153 bhb = buflist;
154
155
156
157 if (uptodate)
158 break;
159 if (bhb == bhe)
160 break;
161 }
162
163
164 if (bhrequest)
165 ll_rw_block(READ, bhrequest, bhreq);
166
167 do {
168 if (*bhe) {
169 wait_on_buffer(*bhe);
170 if (!(*bhe)->b_uptodate) {
171 left = 0;
172 break;
173 }
174 }
175 if (left < blocksize - offset)
176 chars = left;
177 else
178 chars = blocksize - offset;
179 filp->f_pos += chars;
180 left -= chars;
181 read += chars;
182 if (*bhe) {
183 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
184 brelse(*bhe);
185 buf += chars;
186 } else {
187 while (chars-->0)
188 put_fs_byte(0,buf++);
189 }
190 offset = 0;
191 if (++bhe == &buflist[NBUF])
192 bhe = buflist;
193 } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
194 } while (left > 0);
195
196
197 while (bhe != bhb) {
198 brelse(*bhe);
199 if (++bhe == &buflist[NBUF])
200 bhe = buflist;
201 };
202 if (!read)
203 return -EIO;
204 filp->f_reada = 1;
205 return read;
206 }
207
208 int block_fsync(struct inode *inode, struct file *filp)
209 {
210 return fsync_dev (inode->i_rdev);
211 }