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