alloc.c

6900 # 6901 /* 6902 */ 6903 6904 #include "../param.h" 6905 #include "../systm.h" 6906 #include "../filsys.h" 6907 #include "../conf.h" 6908 #include "../buf.h" 6909 #include "../inode.h" 6910 #include "../user.h" 6911 6912 /* 6913 * iinit is called once (from main) 6914 * very early in initialization. 6915 * It reads the root's super block 6916 * and initializes the current date 6917 * from the last modified date. 6918 * 6919 * panic: iinit -- cannot read the super 6920 * block. Usually because of an IO error. 6921 */ 6922 iinit() 6923 { 6924 register *cp, *bp; 6925 6926 (*bdevsw[rootdev.d_major].d_open)(rootdev, 1); 6927 bp = bread(rootdev, 1); 6928 cp = getblk(NODEV); 6929 if(u.u_error) 6930 panic("iinit"); 6931 bcopy(bp->b_addr, cp->b_addr, 256); 6932 brelse(bp); 6933 mount[0].m_bufp = cp; 6934 mount[0].m_dev = rootdev; 6935 cp = cp->b_addr; 6936 cp->s_flock = 0; 6937 cp->s_ilock = 0; 6938 cp->s_ronly = 0; 6939 time[0] = cp->s_time[0]; 6940 time[1] = cp->s_time[1]; 6941 } 6942 /* ------------------------ */ 6943 /* ------------------------ */ 6944 6945 /* 6946 * alloc will obtain the next available 6947 * free disk block from the free list of 6948 * the specified device. 6949 * The super block has up to 100 remembered 6950 * free blocks; the last of these is read to 6951 * obtain 100 more . . . 6952 * 6953 * no space on dev x/y -- when 6954 * the free list is exhausted. 6955 */ 6956 alloc(dev) 6957 { 6958 int bno; 6959 register *bp, *ip, *fp; 6960 6961 fp = getfs(dev); 6962 while(fp->s_flock) 6963 sleep(&fp->s_flock, PINOD); 6964 do { 6965 if(fp->s_nfree <= 0) 6966 goto nospace; 6967 bno = fp->s_free[--fp->s_nfree]; 6968 if(bno == 0) 6969 goto nospace; 6970 } while (badblock(fp, bno, dev)); 6971 if(fp->s_nfree <= 0) { 6972 fp->s_flock++; 6973 bp = bread(dev, bno); 6974 ip = bp->b_addr; 6975 fp->s_nfree = *ip++; 6976 bcopy(ip, fp->s_free, 100); 6977 brelse(bp); 6978 fp->s_flock = 0; 6979 wakeup(&fp->s_flock); 6980 } 6981 bp = getblk(dev, bno); 6982 clrbuf(bp); 6983 fp->s_fmod = 1; 6984 return(bp); 6985 6986 nospace: 6987 fp->s_nfree = 0; 6988 prdev("no space", dev); 6989 u.u_error = ENOSPC; 6990 return(NULL); 6991 } 6992 /* ------------------------ */ 6993 /* ------------------------ */ 6994 6995 /* 6996 * place the specified disk block 6997 * back on the free list of the 6998 * specified device. 6999 */ 7000 free(dev, bno) 7001 { 7002 register *fp, *bp, *ip; 7003 7004 fp = getfs(dev); 7005 fp->s_fmod = 1; 7006 while(fp->s_flock) 7007 sleep(&fp->s_flock, PINOD); 7008 if (badblock(fp, bno, dev)) 7009 return; 7010 if(fp->s_nfree <= 0) { 7011 fp->s_nfree = 1; 7012 fp->s_free[0] = 0; 7013 } 7014 if(fp->s_nfree >= 100) { 7015 fp->s_flock++; 7016 bp = getblk(dev, bno); 7017 ip = bp->b_addr; 7018 *ip++ = fp->s_nfree; 7019 bcopy(fp->s_free, ip, 100); 7020 fp->s_nfree = 0; 7021 bwrite(bp); 7022 fp->s_flock = 0; 7023 wakeup(&fp->s_flock); 7024 } 7025 fp->s_free[fp->s_nfree++] = bno; 7026 fp->s_fmod = 1; 7027 } 7028 /* ------------------------ */ 7029 /* ------------------------ */ 7030 7031 /* 7032 * Check that a block number is in the 7033 * range between the I list and the size 7034 * of the device. 7035 * This is used mainly to check that a 7036 * garbage file system has not been mounted. 7037 * 7038 * bad block on dev x/y -- not in range 7039 */ 7040 badblock(afp, abn, dev) 7041 { 7042 register struct filsys *fp; 7043 register char *bn; 7044 7045 fp = afp; 7046 bn = abn; 7047 if (bn < fp->s_isize+2 || bn >= fp->s_fsize) { 7048 prdev("bad block", dev); 7049 return(1); 7050 } 7051 return(0); 7052 } 7053 /* ------------------------ */ 7054 /* ------------------------ */ 7055 7056 /* 7057 * Allocate an unused I node 7058 * on the specified device. 7059 * Used with file creation. 7060 * The algorithm keeps up to 7061 * 100 spare I nodes in the 7062 * super block. When this runs out, 7063 * a linear search through the 7064 * I list is instituted to pick 7065 * up 100 more. 7066 */ 7067 ialloc(dev) 7068 { 7069 register *fp, *bp, *ip; 7070 int i, j, k, ino; 7071 7072 fp = getfs(dev); 7073 while(fp->s_ilock) 7074 sleep(&fp->s_ilock, PINOD); 7075 loop: 7076 if(fp->s_ninode > 0) { 7077 ino = fp->s_inode[--fp->s_ninode]; 7078 ip = iget(dev, ino); 7079 if (ip==NULL) 7080 return(NULL); 7081 if(ip->i_mode == 0) { 7082 for(bp = &ip->i_mode; bp < &ip->i_addr[8];) 7083 *bp++ = 0; 7084 fp->s_fmod = 1; 7085 return(ip); 7086 } 7087 /* 7088 * Inode was allocated after all. 7089 * Look some more. 7090 */ 7091 iput(ip); 7092 goto loop; 7093 } 7094 fp->s_ilock++; 7095 ino = 0; 7096 for(i=0; is_isize; i++) { 7097 bp = bread(dev, i+2); 7098 ip = bp->b_addr; 7099 for(j=0; j<256; j=+16) { 7100 ino++; 7101 if(ip[j] != 0) 7102 continue; 7103 for(k=0; k7104 if(dev==inode[k].i_dev && 7105 ino==inode[k].i_number) 7106 goto cont; 7107 fp->s_inode[fp->s_ninode++] = ino; 7108 if(fp->s_ninode >= 100) 7109 break; 7110 cont:; 7111 } 7112 brelse(bp); 7113 if(fp->s_ninode >= 100) 7114 break; 7115 } 7116 fp->s_ilock = 0; 7117 wakeup(&fp->s_ilock); 7118 if (fp->s_ninode > 0) 7119 goto loop; 7120 prdev("Out of inodes", dev); 7121 u.u_error = ENOSPC; 7122 return(NULL); 7123 } 7124 /* ------------------------ */ 7125 /* ------------------------ */ 7126 7127 /* 7128 * Free the specified I node 7129 * on the specified device. 7130 * The algorithm stores up 7131 * to 100 I nodes in the super 7132 * block and throws away any more. 7133 */ 7134 ifree(dev, ino) 7135 { 7136 register *fp; 7137 7138 fp = getfs(dev); 7139 if(fp->s_ilock) 7140 return; 7141 if(fp->s_ninode >= 100) 7142 return; 7143 fp->s_inode[fp->s_ninode++] = ino; 7144 fp->s_fmod = 1; 7145 } 7146 /* ------------------------ */ 7147 /* ------------------------ */ 7148 7149 /* 7150 * getfs maps a device number into 7151 * a pointer to the incore super 7152 * block. 7153 * The algorithm is a linear 7154 * search through the mount table. 7155 * A consistency check of the 7156 * in core free-block and i-node 7157 * counts. 7158 * 7159 * bad count on dev x/y -- the count 7160 * check failed. At this point, all 7161 * the counts are zeroed which will 7162 * almost certainly lead to "no space" 7163 * diagnostic 7164 * panic: no fs -- the device is not mounted. 7165 * this "cannot happen" 7166 */ 7167 getfs(dev) 7168 { 7169 register struct mount *p; 7170 register char *n1, *n2; 7171 7172 for(p = &mount[0]; p < &mount[NMOUNT]; p++) 7173 if(p->m_bufp != NULL && p->m_dev == dev) { 7174 p = p->m_bufp->b_addr; 7175 n1 = p->s_nfree; 7176 n2 = p->s_ninode; 7177 if(n1 > 100 || n2 > 100) { 7178 prdev("bad count", dev); 7179 p->s_nfree = 0; 7180 p->s_ninode = 0; 7181 } 7182 return(p); 7183 } 7184 panic("no fs"); 7185 } 7186 /* ------------------------ */ 7187 /* ------------------------ */ 7188 7189 /* 7190 * update is the internal name of 7191 * 'sync'. It goes through the disk 7192 * queues to initiate sandbagged IO; 7193 * goes through the I nodes to write 7194 * modified nodes; and it goes through 7195 * the mount table to initiate modified 7196 * super blocks. 7197 */ 7198 7199 7200 7201 update() 7202 { 7203 register struct inode *ip; 7204 register struct mount *mp; 7205 register *bp; 7206 7207 if(updlock) 7208 return; 7209 updlock++; 7210 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 7211 if(mp->m_bufp != NULL) { 7212 ip = mp->m_bufp->b_addr; 7213 if(ip->s_fmod==0 || ip->s_ilock!=0 || 7214 ip->s_flock!=0 || ip->s_ronly!=0) 7215 continue; 7216 bp = getblk(mp->m_dev, 1); 7217 ip->s_fmod = 0; 7218 ip->s_time[0] = time[0]; 7219 ip->s_time[1] = time[1]; 7220 bcopy(ip, bp->b_addr, 256); 7221 bwrite(bp); 7222 } 7223 for(ip = &inode[0]; ip < &inode[NINODE]; ip++) 7224 if((ip->i_flag&ILOCK) == 0) { 7225 ip->i_flag =| ILOCK; 7226 iupdat(ip, time); 7227 prele(ip); 7228 } 7229 updlock = 0; 7230 bflush(NODEV); 7231 } 7232 /* ------------------------ */ 7233 /* ------------------------ */ 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249