1: /*
2: * SCCS id @(#)rdwri.c 2.1 (Berkeley) 8/5/83
3: */
4:
5: #include "param.h"
6: #include <sys/systm.h>
7: #include <sys/inode.h>
8: #include <sys/dir.h>
9: #include <sys/user.h>
10: #include <sys/buf.h>
11: #include <sys/conf.h>
12:
13: /*
14: * Read the file corresponding to
15: * the inode pointed at by the argument.
16: * The actual read arguments are found
17: * in the variables:
18: * u_base core address for destination
19: * u_offset byte offset in file
20: * u_count number of bytes to read
21: * u_segflg read to kernel/user/user I
22: */
23: readi(ip)
24: register struct inode *ip;
25: {
26: struct buf *bp;
27: dev_t dev;
28: daddr_t lbn, bn;
29: off_t diff;
30: register on, n;
31: int type;
32:
33: if(u.u_count == 0)
34: return;
35: if(u.u_offset < 0) {
36: u.u_error = EINVAL;
37: return;
38: }
39: ip->i_flag |= IACC;
40: dev = (dev_t)ip->i_un.i_rdev;
41: type = ip->i_mode&IFMT;
42: #ifdef MPX_FILS
43: if (type==IFCHR || type==IFMPC)
44: #else
45: if (type==IFCHR)
46: #endif
47: return((*cdevsw[major(dev)].d_read)(dev));
48:
49: do {
50: lbn = bn = u.u_offset >> BSHIFT;
51: on = u.u_offset & BMASK;
52: n = MIN((unsigned)(BSIZE-on), u.u_count);
53: #ifdef MPX_FILS
54: if (type!=IFBLK && type!=IFMPB)
55: #else
56: if (type!=IFBLK)
57: #endif
58: {
59: diff = ip->i_size - u.u_offset;
60: if(diff <= 0)
61: return;
62: if(diff < n)
63: n = diff;
64: bn = bmap(ip, bn, B_READ);
65: if(u.u_error)
66: return;
67: dev = ip->i_dev;
68: } else
69: rablock = bn+1;
70: if ((long)bn<0) {
71: bp = geteblk();
72: clrbuf(bp);
73: } else if (ip->i_un.i_lastr+1==lbn)
74: bp = breada(dev, bn, rablock);
75: else
76: bp = bread(dev, bn);
77: ip->i_un.i_lastr = lbn;
78: n = MIN((unsigned)n, BSIZE-bp->b_resid);
79: if (n!=0) {
80: iomove(mapin(bp)+on, n, B_READ);
81: mapout(bp);
82: }
83: if (n+on==BSIZE || u.u_offset==ip->i_size) {
84: if (ip->i_flag & IPIPE)
85: bp->b_flags &= ~B_DELWRI; /* cancel i/o */
86: bp->b_flags |= B_AGE;
87: }
88: brelse(bp);
89: } while(u.u_error==0 && u.u_count!=0 && n>0);
90: }
91:
92: /*
93: * Write the file corresponding to
94: * the inode pointed at by the argument.
95: * The actual write arguments are found
96: * in the variables:
97: * u_base core address for source
98: * u_offset byte offset in file
99: * u_count number of bytes to write
100: * u_segflg write to kernel/user/user I
101: */
102: writei(ip)
103: register struct inode *ip;
104: {
105: struct buf *bp;
106: dev_t dev;
107: daddr_t bn;
108: register n, on;
109: register type;
110: #ifdef UCB_FSFIX
111: struct direct *dp;
112: #endif
113:
114: #ifndef INSECURE
115: /*
116: * clear set-uid/gid on any write
117: */
118: ip->i_mode &= ~(ISUID|ISGID);
119: #endif
120: if(u.u_offset < 0) {
121: u.u_error = EINVAL;
122: return;
123: }
124: dev = (dev_t)ip->i_un.i_rdev;
125: type = ip->i_mode&IFMT;
126: #ifdef MPX_FILS
127: if (type==IFCHR || type==IFMPC)
128: #else
129: if (type==IFCHR)
130: #endif
131: {
132: ip->i_flag |= IUPD|ICHG;
133: (*cdevsw[major(dev)].d_write)(dev);
134: return;
135: }
136: if (u.u_count == 0)
137: return;
138: do {
139: bn = u.u_offset >> BSHIFT;
140: on = u.u_offset & BMASK;
141: n = MIN((unsigned)(BSIZE-on), u.u_count);
142: #ifdef MPX_FILS
143: if (type!=IFBLK && type!=IFMPB)
144: #else
145: if (type!=IFBLK)
146: #endif
147: {
148: #ifdef UCB_QUOTAS
149: if ((bn = bmap(ip, bn, B_WRITE)) == 0)
150: return;
151: #else
152: bn = bmap(ip, bn, B_WRITE);
153: #endif
154: if (bn < 0)
155: return;
156: dev = ip->i_dev;
157: }
158: if (n == BSIZE)
159: bp = getblk(dev, bn);
160: else {
161: bp = bread(dev, bn);
162: /*
163: * Tape drivers don't clear buffers on end-of-tape
164: * any longer (clrbuf can't be called from interrupt).
165: */
166: if (bp->b_resid == BSIZE)
167: clrbuf(bp);
168: }
169: #ifdef UCB_FSFIX
170: iomove((dp = (struct direct *)((unsigned)mapin(bp)+on)), n, B_WRITE);
171: #else
172: iomove(mapin(bp)+on, n, B_WRITE);
173: mapout(bp);
174: #endif
175: if(u.u_error != 0) {
176: #ifdef UCB_FSFIX
177: mapout(bp);
178: #endif
179: brelse(bp);
180: } else {
181: #ifdef UCB_FSFIX
182: if ((ip->i_mode&IFMT) == IFDIR && (dp->d_ino == 0)) {
183: mapout(bp);
184: /*
185: * Writing to clear a directory entry.
186: * Must insure the write occurs before
187: * the inode is freed, or may end up
188: * pointing at a new (different) file
189: * if inode is quickly allocated again
190: * and system crashes.
191: */
192: bwrite(bp);
193: } else {
194: mapout(bp);
195: if (((u.u_offset & BMASK) == 0)
196: && (ip->i_flag & IPIPE) == 0) {
197: bp->b_flags |= B_AGE;
198: bawrite(bp);
199: } else
200: bdwrite(bp);
201: }
202: #else UCB_FSFIX
203:
204: if (((u.u_offset & BMASK) == 0)
205: && (ip->i_flag & IPIPE) == 0)
206: bp->b_flags |= B_AGE;
207: bdwrite(bp);
208: #endif UCB_FSFIX
209: }
210: #ifndef UCB_SYMLINKS
211: if (u.u_offset > ip->i_size && (type == IFDIR || type == IFREG))
212: #else
213: if (u.u_offset > ip->i_size && (type == IFDIR || type == IFREG || type == IFLNK))
214: #endif
215: ip->i_size = u.u_offset;
216: ip->i_flag |= IUPD|ICHG;
217: } while(u.u_error == 0 && u.u_count != 0);
218: }
219:
220:
221: /*
222: * Move n bytes at byte location cp
223: * to/from (flag) the user/kernel (u.segflg)
224: * area starting at u.base.
225: * Update all the arguments by the number
226: * of bytes moved.
227: *
228: * There are 2 algorithms,
229: * if source address, dest address and count
230: * are all even in a user copy,
231: * then the machine language copyin/copyout
232: * is called.
233: * If not, its done byte by byte with
234: * cpass and passc.
235: */
236: iomove(cp, n, flag)
237: register caddr_t cp;
238: register n;
239: {
240: register t;
241:
242: if (n == 0)
243: return;
244: if(u.u_segflg != 1 && ((n | (int)cp | (int)u.u_base) & (NBPW-1)) == 0) {
245: if (flag == B_WRITE)
246: if (u.u_segflg == 0)
247: t = copyin(u.u_base, (caddr_t)cp, n);
248: else
249: t = copyiin(u.u_base, (caddr_t)cp, n);
250: else
251: if (u.u_segflg == 0)
252: t = copyout((caddr_t)cp, u.u_base, n);
253: else
254: t = copyiout((caddr_t)cp, u.u_base, n);
255: if (t) {
256: u.u_error = EFAULT;
257: return;
258: }
259: u.u_base += n;
260: u.u_offset += n;
261: u.u_count -= n;
262: return;
263: }
264: if (flag == B_WRITE) {
265: do {
266: if ((t = cpass()) < 0)
267: return;
268: *cp++ = t;
269: } while (--n);
270: } else
271: do {
272: if(passc(*cp++) < 0)
273: return;
274: } while (--n);
275: }
Defined functions
readi
defined in line
23; used 9 times