# 2.11BSD#431 - /usr/src/sys/sys/ufs_alloc.c

##### Functions

    balloc            X
    free              X
    fserr             X
    ialloc            X
    ifree             X

##### typedef's

    FBLKP             X

       1: /*
       2:  * Copyright (c) 1986 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  *
       6:  *	@(#)ufs_alloc.c	1.3 (2.11BSD GTE) 1996/9/19
       7:  */
       8:
       9: #include "param.h"
      10: #include "../machine/seg.h"
      11:
      12: #include "fs.h"
      13: #include "dir.h"
      14: #include "inode.h"
      15: #include "buf.h"
      16: #include "user.h"
      17: #include "kernel.h"
      18: #include "mount.h"
      19: #ifdef QUOTA
      20: #include "quota.h"
      21: #endif
      22:
      23: typedef struct fblk *FBLKP;
      24:
      25: /*
      26:  * Allocate a block in the file system.
      27:  *
      28:  * alloc will obtain the next available free disk block from the
      29:  * free list of the specified device.  The super block has up to
      30:  * NICFREE remembered free blocks; the last of these is read to
      31:  * obtain NICFREE more...
      32:  */
      33: struct buf *
      34: balloc(ip, flags)
      35:     struct inode *ip;
      36:     int flags;
      37: {
      38:     register struct fs *fs;
      39:     register struct buf *bp;
      40:     int async;
      41:     daddr_t bno;
      42:
      43:     fs = ip->i_fs;
      44:     async = fs->fs_flags & MNT_ASYNC;
      45:
      46:     while (fs->fs_flock)
      47:         sleep((caddr_t)&fs->fs_flock, PINOD);
      48:     do {
      49:         if (fs->fs_nfree <= 0)
      50:             goto nospace;
      51:         if (fs->fs_nfree > NICFREE) {
      52:             fserr(fs, "bad free count");
      53:             goto nospace;
      54:         }
      55:         bno = fs->fs_free[--fs->fs_nfree];
      56:         if (bno == 0)
      57:             goto nospace;
      58:     } while (badblock(fs, bno));
      59:     if (fs->fs_nfree <= 0) {
      60:         fs->fs_flock++;
      61:         bp = bread(ip->i_dev, bno);
      62:         if (((bp->b_flags&B_ERROR) == 0) && (bp->b_resid==0)) {
      63:             register struct fblk *fbp;
      64:
      65:             fbp = (FBLKP) mapin(bp);
      66:             *((FBLKP)&fs->fs_nfree) = *fbp;
      67:             mapout(bp);
      68:         }
      69:         brelse(bp);
      70:         /*
      71: 		 * Write the superblock back, synchronously if requested,
      72: 		 * so that the free list pointer won't point at garbage.
      73: 		 * We can still end up with dups in free if we then
      74: 		 * use some of the blocks in this freeblock, then crash
      75: 		 * without a sync.
      76: 		 */
      77:         bp = getblk(ip->i_dev, SUPERB);
      78:         fs->fs_fmod = 0;
      79:         fs->fs_time = time.tv_sec;
      80:         {
      81:             register struct fs *fps;
      82:
      83:             fps = (struct fs *)mapin(bp);
      84:             *fps = *fs;
      85:         }
      86:         mapout(bp);
      87:         if (!async)
      88:             bwrite(bp);
      89:         else
      90:             bdwrite(bp);
      91:         fs->fs_flock = 0;
      92:         wakeup((caddr_t)&fs->fs_flock);
      93:         if (fs->fs_nfree <=0)
      94:             goto nospace;
      95:     }
      96:     bp = getblk(ip->i_dev, bno);
      97:     bp->b_resid = 0;
      98:     if (flags & B_CLRBUF)
      99:         clrbuf(bp);
     100:     fs->fs_fmod = 1;
     101:     fs->fs_tfree--;
     102:     return(bp);
     103:
     104: nospace:
     105:     fs->fs_nfree = 0;
     106:     fs->fs_tfree = 0;
     107:     fserr(fs, "file system full");
     108:     /*
     109: 	 * THIS IS A KLUDGE...
     110: 	 * SHOULD RATHER SEND A SIGNAL AND SUSPEND THE PROCESS IN A
     111: 	 * STATE FROM WHICH THE SYSTEM CALL WILL RESTART
     112: 	 */
     113:     uprintf("\n%s: write failed, file system full\n", fs->fs_fsmnt);
     114:     {
     115:         register int i;
     116:
     117:         for (i = 0; i < 5; i++)
     118:             sleep((caddr_t)&lbolt, PRIBIO);
     119:     }
     120:     u.u_error = ENOSPC;
     121:     return(NULL);
     122: }
     123:
     124: /*
     125:  * Allocate an inode in the file system.
     126:  *
     127:  * Allocate an unused I node on the specified device.  Used with file
     128:  * creation.  The algorithm keeps up to NICINOD spare I nodes in the
     129:  * super block.  When this runs out, a linear search through the I list
     130:  * is instituted to pick up NICINOD more.
     131:  */
     132: struct inode *
     133: ialloc(pip)
     134:     struct inode *pip;
     135: {
     136:     register struct fs *fs;
     137:     register struct buf *bp;
     138:     register struct inode *ip;
     139:     int i;
     140:     struct dinode *dp;
     141:     ino_t ino;
     142:     daddr_t adr;
     143:     ino_t inobas;
     144:     int first;
     145:     struct inode *ifind();
     146:     char    *emsg = "no inodes free";
     147:
     148:     fs = pip->i_fs;
     149:     while (fs->fs_ilock)
     150:         sleep((caddr_t)&fs->fs_ilock, PINOD);
     151: #ifdef QUOTA
     152:     QUOTAMAP();
     153:     u.u_error = chkiq(pip->i_dev, NULL, u.u_uid, 0);
     154:     QUOTAUNMAP();
     155:     if (u.u_error)
     156:         return(NULL);
     157: #endif
     158: loop:
     159:     if (fs->fs_ninode > 0) {
     160:         ino = fs->fs_inode[--fs->fs_ninode];
     161:         if (ino <= ROOTINO)
     162:             goto loop;
     163:         ip = iget(pip->i_dev, fs, ino);
     164:         if (ip == NULL)
     165:             return(NULL);
     166:         if (ip->i_mode == 0) {
     167:             bzero((caddr_t)ip->i_addr,sizeof(ip->i_addr));
     168:             ip->i_flags = 0;
     169:             fs->fs_fmod = 1;
     170:             fs->fs_tinode--;
     171:             return(ip);
     172:         }
     173:         /*
     174: 		 * Inode was allocated after all.
     175: 		 * Look some more.
     176: 		 */
     177:         iput(ip);
     178:         goto loop;
     179:     }
     180:     fs->fs_ilock++;
     181:     if (fs->fs_nbehind < 4 * NICINOD) {
     182:         first = 1;
     183:         ino = fs->fs_lasti;
     184: #ifdef DIAGNOSTIC
     185:         if (itoo(ino))
     186:             panic("ialloc");
     187: #endif DIAGNOSTIC
     188:         adr = itod(ino);
     189:     } else {
     190: fromtop:
     191:         first = 0;
     192:         ino = 1;
     193:         adr = SUPERB+1;
     194:         fs->fs_nbehind = 0;
     195:     }
     196:     for (;adr < fs->fs_isize;adr++) {
     197:         inobas = ino;
     198:         bp = bread(pip->i_dev, adr);
     199:         if ((bp->b_flags & B_ERROR) || bp->b_resid) {
     200:             brelse(bp);
     201:             ino += INOPB;
     202:             continue;
     203:         }
     204:         dp = (struct dinode *)mapin(bp);
     205:         for (i = 0;i < INOPB;i++) {
     206:             if (dp->di_mode != 0)
     207:                 goto cont;
     208:             if (ifind(pip->i_dev, ino))
     209:                 goto cont;
     210:             fs->fs_inode[fs->fs_ninode++] = ino;
     211:             if (fs->fs_ninode >= NICINOD)
     212:                 break;
     213:         cont:
     214:             ino++;
     215:             dp++;
     216:         }
     217:         mapout(bp);
     218:         brelse(bp);
     219:         if (fs->fs_ninode >= NICINOD)
     220:             break;
     221:     }
     222:     if (fs->fs_ninode < NICINOD && first)
     223:         goto fromtop;
     224:     fs->fs_lasti = inobas;
     225:     fs->fs_ilock = 0;
     226:     wakeup((caddr_t)&fs->fs_ilock);
     227:     if (fs->fs_ninode > 0)
     228:         goto loop;
     229:     fserr(fs, emsg);
     230:     uprintf("\n%s: %s\n", fs->fs_fsmnt, emsg);
     231:     u.u_error = ENOSPC;
     232:     return(NULL);
     233: }
     234:
     235: /*
     236:  * Free a block or fragment.
     237:  *
     238:  * Place the specified disk block back on the free list of the
     239:  * specified device.
     240:  */
     241: free(ip, bno)
     242:     struct inode *ip;
     243:     daddr_t bno;
     244: {
     245:     register struct fs *fs;
     246:     register struct buf *bp;
     247:     struct fblk *fbp;
     248:
     249:     fs = ip->i_fs;
     250:     if (badblock(fs, bno)) {
     251:         printf("bad block %D, ino %d\n", bno, ip->i_number);
     252:         return;
     253:     }
     254:     while (fs->fs_flock)
     255:         sleep((caddr_t)&fs->fs_flock, PINOD);
     256:     if (fs->fs_nfree <= 0) {
     257:         fs->fs_nfree = 1;
     258:         fs->fs_free[0] = 0;
     259:     }
     260:     if (fs->fs_nfree >= NICFREE) {
     261:         fs->fs_flock++;
     262:         bp = getblk(ip->i_dev, bno);
     263:         fbp = (FBLKP)mapin(bp);
     264:         *fbp = *((FBLKP)&fs->fs_nfree);
     265:         mapout(bp);
     266:         fs->fs_nfree = 0;
     267:         if (fs->fs_flags & MNT_ASYNC)
     268:             bdwrite(bp);
     269:         else
     270:             bwrite(bp);
     271:         fs->fs_flock = 0;
     272:         wakeup((caddr_t)&fs->fs_flock);
     273:     }
     274:     fs->fs_free[fs->fs_nfree++] = bno;
     275:     fs->fs_tfree++;
     276:     fs->fs_fmod = 1;
     277: }
     278:
     279: /*
     280:  * Free an inode.
     281:  *
     282:  * Free the specified I node on the specified device.  The algorithm
     283:  * stores up to NICINOD I nodes in the super block and throws away any more.
     284:  */
     285: ifree(ip, ino)
     286:     struct inode *ip;
     287:     ino_t ino;
     288: {
     289:     register struct fs *fs;
     290:
     291:     fs = ip->i_fs;
     292:     fs->fs_tinode++;
     293:     if (fs->fs_ilock)
     294:         return;
     295:     if (fs->fs_ninode >= NICINOD) {
     296:         if (fs->fs_lasti > ino)
     297:             fs->fs_nbehind++;
     298:         return;
     299:     }
     300:     fs->fs_inode[fs->fs_ninode++] = ino;
     301:     fs->fs_fmod = 1;
     302: }
     303:
     304: /*
     305:  * Fserr prints the name of a file system with an error diagnostic.
     306:  *
     307:  * The form of the error message is:
     308:  *	fs: error message
     309:  */
     310: fserr(fp, cp)
     311:     struct fs *fp;
     312:     char *cp;
     313: {
     314:     printf("%s: %s\n", fp->fs_fsmnt, cp);
     315: }

#### Defined functions

balloc defined in line 33; used 4 times

- in /usr/src/sys/h/buf.h line 87
- in /usr/src/sys/sys/ufs_bmap.c line 56, 102, 137

free defined in line 241; used 4 times

- in /usr/src/sys/sys/ufs_inode.c line 543, 558, 676, 714

fserr defined in line 310; used 5 times

- in line 52, 107, 229
- in /usr/src/sys/sys/ufs_subr.c line 113, 140

ialloc defined in line 132; used 4 times

- in /usr/src/sys/h/inode.h line 171
- in /usr/src/sys/sys/sys_pipe.c line 62
- in /usr/src/sys/sys/ufs_syscalls.c line 1095, 1183

ifree defined in line 285; used 1 times

- in /usr/src/sys/sys/ufs_inode.c line 326

#### Defined typedef's

FBLKP defined in line 23; used 4 times

- in line 65-66(2), 263-264(2)

Last modified: 1996-09-20 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1081 |