xref: /original-bsd/sys/kern/subr_xxx.c (revision d25e1985)
1 /*	subr_xxx.c	3.2	06/07/80	*/
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);
48 			bdwrite(bp);
49 			ip->i_un.i_addr[i] = nb;
50 			ip->i_flag |= IUPD|ICHG;
51 		}
52 		if(i < NADDR-4)
53 			rablock = ip->i_un.i_addr[i+1];
54 		return(nb);
55 	}
56 
57 	/*
58 	 * addresses NADDR-3, NADDR-2, and NADDR-1
59 	 * have single, double, triple indirect blocks.
60 	 * the first step is to determine
61 	 * how many levels of indirection.
62 	 */
63 	sh = 0;
64 	nb = 1;
65 	bn -= NADDR-3;
66 	for(j=3; j>0; j--) {
67 		sh += NSHIFT;
68 		nb <<= NSHIFT;
69 		if(bn < nb)
70 			break;
71 		bn -= nb;
72 	}
73 	if(j == 0) {
74 		u.u_error = EFBIG;
75 		return((daddr_t)0);
76 	}
77 
78 	/*
79 	 * fetch the address from the inode
80 	 */
81 	nb = ip->i_un.i_addr[NADDR-j];
82 	if(nb == 0) {
83 		if(rwflg==B_READ || (bp = alloc(dev))==NULL)
84 			return((daddr_t)-1);
85 		nb = dbtofsb(bp->b_blkno);
86 		bdwrite(bp);
87 		ip->i_un.i_addr[NADDR-j] = nb;
88 		ip->i_flag |= IUPD|ICHG;
89 	}
90 
91 	/*
92 	 * fetch through the indirect blocks
93 	 */
94 	for(; j<=3; j++) {
95 		bp = bread(dev, nb);
96 		if(bp->b_flags & B_ERROR) {
97 			brelse(bp);
98 			return((daddr_t)0);
99 		}
100 		bap = bp->b_un.b_daddr;
101 		sh -= NSHIFT;
102 		i = (bn>>sh) & NMASK;
103 		nb = bap[i];
104 		if(nb == 0) {
105 			if(rwflg==B_READ || (nbp = alloc(dev))==NULL) {
106 				brelse(bp);
107 				return((daddr_t)-1);
108 			}
109 			nb = dbtofsb(nbp->b_blkno);
110 			bdwrite(nbp);
111 			bap[i] = nb;
112 			bdwrite(bp);
113 		} else
114 			brelse(bp);
115 	}
116 
117 	/*
118 	 * calculate read-ahead.
119 	 */
120 	if(i < NINDIR-1)
121 		rablock = bap[i+1];
122 	return(nb);
123 }
124 
125 /*
126  * Pass back  c  to the user at his location u_base;
127  * update u_base, u_count, and u_offset.  Return -1
128  * on the last character of the user's read.
129  * u_base is in the user address space unless u_segflg is set.
130  */
131 passc(c)
132 register c;
133 {
134 	register id;
135 
136 	if((id = u.u_segflg) == 1)
137 		*u.u_base = c;
138 	else
139 		if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) {
140 			u.u_error = EFAULT;
141 			return(-1);
142 		}
143 	u.u_count--;
144 	u.u_offset++;
145 	u.u_base++;
146 	return(u.u_count == 0? -1: 0);
147 }
148 
149 /*
150  * Pick up and return the next character from the user's
151  * write call at location u_base;
152  * update u_base, u_count, and u_offset.  Return -1
153  * when u_count is exhausted.  u_base is in the user's
154  * address space unless u_segflg is set.
155  */
156 /*
157 cpass()
158 {
159 	register c, id;
160 
161 	if(u.u_count == 0)
162 		return(-1);
163 	if((id = u.u_segflg) == 1)
164 		c = *u.u_base;
165 	else
166 		if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) {
167 			u.u_error = EFAULT;
168 			return(-1);
169 		}
170 	u.u_count--;
171 	u.u_offset++;
172 	u.u_base++;
173 	return(c&0377);
174 }
175 */
176 
177 /*
178  * Routine which sets a user error; placed in
179  * illegal entries in the bdevsw and cdevsw tables.
180  */
181 nodev()
182 {
183 
184 	u.u_error = ENODEV;
185 }
186 
187 /*
188  * Null routine; placed in insignificant entries
189  * in the bdevsw and cdevsw tables.
190  */
191 nulldev()
192 {
193 
194 }
195 
196 imin(a, b)
197 {
198 
199 	return (a < b ? a : b);
200 }
201 
202 imax(a, b)
203 {
204 
205 	return (a > b ? a : b);
206 }
207 
208 struct proc *
209 pfind(pid)
210 	int pid;
211 {
212 	register struct proc *p;
213 
214 	for (p = &proc[pidhash[PIDHASH(pid)]]; p != &proc[0]; p = &proc[p->p_idhash])
215 		if (p->p_pid == pid)
216 			return (p);
217 	return ((struct proc *)0);
218 }
219