Research V6 development
[unix-history] / usr / sys / ken / rdwri.c
CommitLineData
d99e8b3c
KT
1#
2/*
3 */
4
5#include "../param.h"
6#include "../inode.h"
7#include "../user.h"
8#include "../buf.h"
9#include "../conf.h"
10#include "../systm.h"
11
12/*
13 * Read the file corresponding to
14 * the inode pointed at by the argument.
15 * The actual read arguments are found
16 * in the variables:
17 * u_base core address for destination
18 * u_offset byte offset in file
19 * u_count number of bytes to read
20 * u_segflg read to kernel/user
21 */
22readi(aip)
23struct inode *aip;
24{
25 int *bp;
26 int lbn, bn, on;
27 register dn, n;
28 register struct inode *ip;
29
30 ip = aip;
31 if(u.u_count == 0)
32 return;
33 ip->i_flag =| IACC;
34 if((ip->i_mode&IFMT) == IFCHR) {
35 (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]);
36 return;
37 }
38
39 do {
40 lbn = bn = lshift(u.u_offset, -9);
41 on = u.u_offset[1] & 0777;
42 n = min(512-on, u.u_count);
43 if((ip->i_mode&IFMT) != IFBLK) {
44 dn = dpcmp(ip->i_size0&0377, ip->i_size1,
45 u.u_offset[0], u.u_offset[1]);
46 if(dn <= 0)
47 return;
48 n = min(n, dn);
49 if ((bn = bmap(ip, lbn)) == 0)
50 return;
51 dn = ip->i_dev;
52 } else {
53 dn = ip->i_addr[0];
54 rablock = bn+1;
55 }
56 if (ip->i_lastr+1 == lbn)
57 bp = breada(dn, bn, rablock);
58 else
59 bp = bread(dn, bn);
60 ip->i_lastr = lbn;
61 iomove(bp, on, n, B_READ);
62 brelse(bp);
63 } while(u.u_error==0 && u.u_count!=0);
64}
65
66/*
67 * Write the file corresponding to
68 * the inode pointed at by the argument.
69 * The actual write arguments are found
70 * in the variables:
71 * u_base core address for source
72 * u_offset byte offset in file
73 * u_count number of bytes to write
74 * u_segflg write to kernel/user
75 */
76writei(aip)
77struct inode *aip;
78{
79 int *bp;
80 int n, on;
81 register dn, bn;
82 register struct inode *ip;
83
84 ip = aip;
85 ip->i_flag =| IACC|IUPD;
86 if((ip->i_mode&IFMT) == IFCHR) {
87 (*cdevsw[ip->i_addr[0].d_major].d_write)(ip->i_addr[0]);
88 return;
89 }
90 if (u.u_count == 0)
91 return;
92
93 do {
94 bn = lshift(u.u_offset, -9);
95 on = u.u_offset[1] & 0777;
96 n = min(512-on, u.u_count);
97 if((ip->i_mode&IFMT) != IFBLK) {
98 if ((bn = bmap(ip, bn)) == 0)
99 return;
100 dn = ip->i_dev;
101 } else
102 dn = ip->i_addr[0];
103 if(n == 512)
104 bp = getblk(dn, bn); else
105 bp = bread(dn, bn);
106 iomove(bp, on, n, B_WRITE);
107 if(u.u_error != 0)
108 brelse(bp); else
109 if ((u.u_offset[1]&0777)==0)
110 bawrite(bp); else
111 bdwrite(bp);
112 if(dpcmp(ip->i_size0&0377, ip->i_size1,
113 u.u_offset[0], u.u_offset[1]) < 0 &&
114 (ip->i_mode&(IFBLK&IFCHR)) == 0) {
115 ip->i_size0 = u.u_offset[0];
116 ip->i_size1 = u.u_offset[1];
117 }
118 ip->i_flag =| IUPD;
119 } while(u.u_error==0 && u.u_count!=0);
120}
121
122/*
123 * Return the logical maximum
124 * of the 2 arguments.
125 */
126max(a, b)
127char *a, *b;
128{
129
130 if(a > b)
131 return(a);
132 return(b);
133}
134
135/*
136 * Return the logical minimum
137 * of the 2 arguments.
138 */
139min(a, b)
140char *a, *b;
141{
142
143 if(a < b)
144 return(a);
145 return(b);
146}
147
148/*
149 * Move 'an' bytes at byte location
150 * &bp->b_addr[o] to/from (flag) the
151 * user/kernel (u.segflg) area starting at u.base.
152 * Update all the arguments by the number
153 * of bytes moved.
154 *
155 * There are 2 algorithms,
156 * if source address, dest address and count
157 * are all even in a user copy,
158 * then the machine language copyin/copyout
159 * is called.
160 * If not, its done byte-by-byte with
161 * cpass and passc.
162 */
163iomove(bp, o, an, flag)
164struct buf *bp;
165{
166 register char *cp;
167 register int n, t;
168
169 n = an;
170 cp = bp->b_addr + o;
171 if(u.u_segflg==0 && ((n | cp | u.u_base)&01)==0) {
172 if (flag==B_WRITE)
173 cp = copyin(u.u_base, cp, n);
174 else
175 cp = copyout(cp, u.u_base, n);
176 if (cp) {
177 u.u_error = EFAULT;
178 return;
179 }
180 u.u_base =+ n;
181 dpadd(u.u_offset, n);
182 u.u_count =- n;
183 return;
184 }
185 if (flag==B_WRITE) {
186 while(n--) {
187 if ((t = cpass()) < 0)
188 return;
189 *cp++ = t;
190 }
191 } else
192 while (n--)
193 if(passc(*cp++) < 0)
194 return;
195}