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