Research V6 development
[unix-history] / usr / sys / ken / subr.c
CommitLineData
64d0f71e
KT
1#
2/*
3 */
4
5#include "../param.h"
6#include "../conf.h"
7#include "../inode.h"
8#include "../user.h"
9#include "../buf.h"
10#include "../systm.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 */
20bmap(ip, bn)
21struct inode *ip;
22int bn;
23{
24 register *bp, *bap, nb;
25 int *nbp, d, i;
26
27 d = ip->i_dev;
28 if(bn & ~077777) {
29 u.u_error = EFBIG;
30 return(0);
31 }
32
33 if((ip->i_mode&ILARG) == 0) {
34
35 /*
36 * small file algorithm
37 */
38
39 if((bn & ~7) != 0) {
40
41 /*
42 * convert small to large
43 */
44
45 if ((bp = alloc(d)) == NULL)
46 return(NULL);
47 bap = bp->b_addr;
48 for(i=0; i<8; i++) {
49 *bap++ = ip->i_addr[i];
50 ip->i_addr[i] = 0;
51 }
52 ip->i_addr[0] = bp->b_blkno;
53 bdwrite(bp);
54 ip->i_mode =| ILARG;
55 goto large;
56 }
57 nb = ip->i_addr[bn];
58 if(nb == 0 && (bp = alloc(d)) != NULL) {
59 bdwrite(bp);
60 nb = bp->b_blkno;
61 ip->i_addr[bn] = nb;
62 ip->i_flag =| IUPD;
63 }
64 rablock = 0;
65 if (bn<7)
66 rablock = ip->i_addr[bn+1];
67 return(nb);
68 }
69
70 /*
71 * large file algorithm
72 */
73
74 large:
75 i = bn>>8;
76 if(bn & 0174000)
77 i = 7;
78 if((nb=ip->i_addr[i]) == 0) {
79 ip->i_flag =| IUPD;
80 if ((bp = alloc(d)) == NULL)
81 return(NULL);
82 ip->i_addr[i] = bp->b_blkno;
83 } else
84 bp = bread(d, nb);
85 bap = bp->b_addr;
86
87 /*
88 * "huge" fetch of double indirect block
89 */
90
91 if(i == 7) {
92 i = ((bn>>8) & 0377) - 7;
93 if((nb=bap[i]) == 0) {
94 if((nbp = alloc(d)) == NULL) {
95 brelse(bp);
96 return(NULL);
97 }
98 bap[i] = nbp->b_blkno;
99 bdwrite(bp);
100 } else {
101 brelse(bp);
102 nbp = bread(d, nb);
103 }
104 bp = nbp;
105 bap = bp->b_addr;
106 }
107
108 /*
109 * normal indirect fetch
110 */
111
112 i = bn & 0377;
113 if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
114 nb = nbp->b_blkno;
115 bap[i] = nb;
116 bdwrite(nbp);
117 bdwrite(bp);
118 } else
119 brelse(bp);
120 rablock = 0;
121 if(i < 255)
122 rablock = bap[i+1];
123 return(nb);
124}
125
126/*
127 * Pass back c to the user at his location u_base;
128 * update u_base, u_count, and u_offset. Return -1
129 * on the last character of the user's read.
130 * u_base is in the user address space unless u_segflg is set.
131 */
132passc(c)
133char c;
134{
135
136 if(u.u_segflg)
137 *u.u_base = c; else
138 if(subyte(u.u_base, c) < 0) {
139 u.u_error = EFAULT;
140 return(-1);
141 }
142 u.u_count--;
143 if(++u.u_offset[1] == 0)
144 u.u_offset[0]++;
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 */
156cpass()
157{
158 register c;
159
160 if(u.u_count == 0)
161 return(-1);
162 if(u.u_segflg)
163 c = *u.u_base; else
164 if((c=fubyte(u.u_base)) < 0) {
165 u.u_error = EFAULT;
166 return(-1);
167 }
168 u.u_count--;
169 if(++u.u_offset[1] == 0)
170 u.u_offset[0]++;
171 u.u_base++;
172 return(c&0377);
173}
174
175/*
176 * Routine which sets a user error; placed in
177 * illegal entries in the bdevsw and cdevsw tables.
178 */
179nodev()
180{
181
182 u.u_error = ENODEV;
183}
184
185/*
186 * Null routine; placed in insignificant entries
187 * in the bdevsw and cdevsw tables.
188 */
189nulldev()
190{
191}
192
193/*
194 * copy count words from from to to.
195 */
196bcopy(from, to, count)
197int *from, *to;
198{
199 register *a, *b, c;
200
201 a = from;
202 b = to;
203 c = count;
204 do
205 *b++ = *a++;
206 while(--c);
207}