1: /*
2: * SCCS id @(#)subr.c 2.1 (Berkeley) 9/4/83
3: */
4:
5: #include "param.h"
6: #include <sys/systm.h>
7: #include <sys/conf.h>
8: #include <sys/inode.h>
9: #include <sys/dir.h>
10: #include <sys/user.h>
11: #include <sys/buf.h>
12: #include <sys/quota.h>
13:
14: #ifndef UCB_QUOTAS
15: #define qalloc(x,y) alloc(y)
16: #endif
17:
18: /*
19: * Bmap defines the structure of file system storage
20: * by returning the physical block number on a device given the
21: * inode and the logical block number in a file.
22: * When convenient, it also leaves the physical
23: * block number of the next block of the file in rablock
24: * for use in read-ahead.
25: */
26: daddr_t
27: bmap(ip, bn, rwflg)
28: register struct inode *ip;
29: daddr_t bn;
30: {
31: register i;
32: register struct buf *bp, *nbp;
33: int j, sh;
34: daddr_t nb, *bap, ra;
35: dev_t dev;
36:
37: if(bn < 0) {
38: u.u_error = EFBIG;
39: return((daddr_t)0);
40: }
41: dev = ip->i_dev;
42: ra = rablock = 0;
43:
44: /*
45: * blocks 0..NADDR-4 are direct blocks
46: */
47: if(bn < NADDR-3) {
48: i = bn;
49: nb = ip->i_un.i_addr[i];
50: if (nb == 0) {
51: if (rwflg == B_READ || (bp = qalloc(ip, dev)) == NULL)
52: return((daddr_t)-1);
53: nb = dbtofsb(bp->b_blkno);
54: #ifdef UCB_FSFIX
55: if ((ip->i_mode&IFMT) == IFDIR)
56: /*
57: * Write directory blocks synchronously
58: * so they never appear with garbage in
59: * them on the disk.
60: */
61: bwrite(bp);
62: else
63: #endif
64: bdwrite(bp);
65: ip->i_un.i_addr[i] = nb;
66: ip->i_flag |= IUPD|ICHG;
67: }
68: if(i < NADDR-4)
69: rablock = ip->i_un.i_addr[i+1];
70: return(nb);
71: }
72:
73: /*
74: * addresses NADDR-3, NADDR-2, and NADDR-1
75: * have single, double, triple indirect blocks.
76: * the first step is to determine
77: * how many levels of indirection.
78: */
79: sh = 0;
80: nb = 1;
81: bn -= NADDR-3;
82: for(j=3; j>0; j--) {
83: sh += NSHIFT;
84: nb <<= NSHIFT;
85: if(bn < nb)
86: break;
87: bn -= nb;
88: }
89: if(j == 0) {
90: u.u_error = EFBIG;
91: return((daddr_t)0);
92: }
93:
94: /*
95: * fetch the first indirect block
96: */
97: nb = ip->i_un.i_addr[NADDR-j];
98: if(nb == 0) {
99: if (rwflg == B_READ || (bp = qalloc(ip, dev)) == NULL)
100: return((daddr_t) -1);
101: nb = dbtofsb(bp->b_blkno);
102: #ifdef UCB_FSFIX
103: /*
104: * Write synchronously so that indirect blocks
105: * never point at garbage.
106: */
107: bwrite(bp);
108: #else
109: bdwrite(bp);
110: #endif
111: ip->i_un.i_addr[NADDR-j] = nb;
112: ip->i_flag |= IUPD|ICHG;
113: }
114:
115: /*
116: * fetch through the indirect blocks
117: */
118: for(; j<=3; j++) {
119: bp = bread(dev, nb);
120: if((bp->b_flags & B_ERROR) || bp->b_resid) {
121: brelse(bp);
122: return((daddr_t)0);
123: }
124: bap = (daddr_t *) mapin(bp);
125: sh -= NSHIFT;
126: i = (bn>>sh) & NMASK;
127: nb = bap[i];
128: /*
129: * calculate read-ahead
130: */
131: if(i < NINDIR-1)
132: ra = bap[i+1];
133: mapout(bp);
134: if(nb == 0) {
135: if(rwflg == B_READ || (nbp = qalloc(ip, dev)) == NULL) {
136: brelse(bp);
137: return((daddr_t) -1);
138: }
139: nb = dbtofsb(nbp->b_blkno);
140: #ifdef UCB_FSFIX
141: if (j < 3 || (ip->i_mode&IFMT) == IFDIR)
142: /*
143: * Write synchronously so indirect blocks
144: * never point at garbage and blocks
145: * in directories never contain garbage.
146: */
147: bwrite(nbp);
148: else
149: #endif
150: bdwrite(nbp);
151: bap = (daddr_t) mapin(bp);
152: bap[i] = nb;
153: mapout(bp);
154: bdwrite(bp);
155: } else
156: brelse(bp);
157: }
158:
159: rablock = ra;
160: return(nb);
161: }
162:
163: /*
164: * Pass back c to the user at his location u_base;
165: * update u_base, u_count, and u_offset. Return -1
166: * on the last character of the user's read.
167: * u_base is in the user address space unless u_segflg is 1.
168: */
169: passc(c)
170: register c;
171: {
172: register id;
173:
174: if((id = u.u_segflg) == 1)
175: *u.u_base = c;
176: else
177: if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) {
178: u.u_error = EFAULT;
179: return(-1);
180: }
181: u.u_count--;
182: u.u_offset++;
183: u.u_base++;
184: return(u.u_count == 0? -1: 0);
185: }
186:
187: /*
188: * Pick up and return the next character from the user's
189: * write call at location u_base;
190: * update u_base, u_count, and u_offset. Return -1
191: * when u_count is exhausted. u_base is in the user's
192: * address space unless u_segflg is 1.
193: */
194: cpass()
195: {
196: register c, id;
197:
198: if(u.u_count == 0)
199: return(-1);
200: if((id = u.u_segflg) == 1)
201: c = *u.u_base;
202: else
203: if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) {
204: u.u_error = EFAULT;
205: return(-1);
206: }
207: u.u_count--;
208: u.u_offset++;
209: u.u_base++;
210: return(c&0377);
211: }
212:
213: /*
214: * Routine which sets a user error; placed in
215: * illegal entries in the bdevsw and cdevsw tables.
216: */
217: nodev()
218: {
219:
220: u.u_error = ENODEV;
221: }
222:
223: /*
224: * copy count bytes from from to to.
225: */
226: bcopy(from, to, count)
227: register caddr_t from, to;
228: register count;
229: {
230: if ((from|to|count) & 1) /* copy by bytes */
231: while (count--)
232: *to++ = *from++;
233: else { /* copy by words */
234: count >>= 1;
235: while (count--)
236: *((short *)to)++ = *((short *)from)++;
237: }
238: }
Defined functions
bmap
defined in line
26; used 5 times
nodev
defined in line
217; used 310 times
- in /usr/src/sys/GENERIC/c.c line
23,
30-34(5),
42-47(6),
55-57(3),
70-75(6),
87-91(5),
104-109(5),
121-125(5),
136-146(7),
154-156(3),
167-171(5),
183-187(5),
199-204(5),
216-220(5),
230-240(7),
250-260(7),
268-271(4),
282-287(5),
299(3),
347-378(32),
384-397(4),
404-405(6),
411-414(2),
434-441(8),
451-458(8),
471
- in /usr/src/sys/GENERIC/ioconf.c line
25-26(2)
- in /usr/src/sys/conf/c.c line
23,
30-34(5),
42-47(6),
55-57(3),
70-75(6),
87-91(5),
104-109(5),
121-125(5),
136-146(7),
154-156(3),
167-171(5),
183-187(5),
199-204(5),
216-220(5),
230-240(7),
250-260(7),
268-271(4),
282-287(5),
299(3),
347-378(32),
384-397(4),
404-405(6),
411-414(2),
434-441(8),
451-458(8),
471
- in /usr/src/sys/dev/tty.c line
260,
335
Defined macros