14359Smckusick /* Copyright (c) 1981 Regents of the University of California */ 24359Smckusick 3*4426Smckusic static char vers[] = "@(#)lfs_alloc.c 1.3 09/22/81"; 44359Smckusick 54359Smckusick /* alloc.c 4.8 81/03/08 */ 64359Smckusick 74359Smckusick #include "../h/param.h" 84359Smckusick #include "../h/systm.h" 94359Smckusick #include "../h/mount.h" 104359Smckusick #include "../h/fs.h" 114359Smckusick #include "../h/conf.h" 124359Smckusick #include "../h/buf.h" 134359Smckusick #include "../h/inode.h" 144359Smckusick #include "../h/dir.h" 154359Smckusick #include "../h/user.h" 164359Smckusick 174359Smckusick long hashalloc(); 184359Smckusick long alloccg(); 194359Smckusick long ialloccg(); 204359Smckusick 214359Smckusick struct buf * 224359Smckusick alloc(dev, ip, bpref, size) 234359Smckusick dev_t dev; 244359Smckusick struct inode *ip; 254359Smckusick daddr_t bpref; 264359Smckusick int size; 274359Smckusick { 284359Smckusick daddr_t bno; 294359Smckusick register struct fs *fs; 304359Smckusick struct buf *bp; 314359Smckusick int cg; 324359Smckusick 334359Smckusick fs = getfs(dev); 344359Smckusick if (fs->fs_nbfree == 0 && size == BSIZE) 354359Smckusick goto nospace; 364359Smckusick if (bpref == 0) 374359Smckusick cg = itog(ip->i_number, fs); 384359Smckusick else 394359Smckusick cg = dtog(bpref, fs); 404359Smckusick bno = hashalloc(dev, fs, cg, (long)bpref, size, alloccg); 414359Smckusick if (bno == 0) 424359Smckusick goto nospace; 43*4426Smckusic bp = getblk(dev, bno, size); 444359Smckusick clrbuf(bp); 454359Smckusick return (bp); 464359Smckusick nospace: 474359Smckusick fserr(fs, "file system full"); 484359Smckusick uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); 494359Smckusick u.u_error = ENOSPC; 504359Smckusick return (NULL); 514359Smckusick } 524359Smckusick 53*4426Smckusic struct buf * 54*4426Smckusic realloccg(dev, ip, bpref, osize, nsize) 55*4426Smckusic dev_t dev; 56*4426Smckusic struct inode *ip; 57*4426Smckusic daddr_t bpref; 58*4426Smckusic int osize, nsize; 59*4426Smckusic { 60*4426Smckusic daddr_t bno; 61*4426Smckusic register struct fs *fs; 62*4426Smckusic struct buf *bp; 63*4426Smckusic int cg; 64*4426Smckusic 65*4426Smckusic fs = getfs(dev); 66*4426Smckusic if (bpref == 0) 67*4426Smckusic cg = itog(ip->i_number, fs); 68*4426Smckusic else 69*4426Smckusic cg = dtog(bpref, fs); 70*4426Smckusic bno = fragalloc(dev, fs, cg, (long)bpref, osize, nsize); 71*4426Smckusic if (bno == 0) 72*4426Smckusic goto nospace; 73*4426Smckusic bp = getblk(dev, bno, osize); 74*4426Smckusic bp->b_bcount += nsize - osize; 75*4426Smckusic blkclr(bp->b_un.b_addr + osize, nsize - osize); 76*4426Smckusic return (bp); 77*4426Smckusic nospace: 78*4426Smckusic fserr(fs, "file system full"); 79*4426Smckusic uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); 80*4426Smckusic u.u_error = ENOSPC; 81*4426Smckusic return (NULL); 82*4426Smckusic } 83*4426Smckusic 844359Smckusick struct inode * 854359Smckusick ialloc(dev, ipref, mode) 864359Smckusick dev_t dev; 874359Smckusick ino_t ipref; 884359Smckusick int mode; 894359Smckusick { 904359Smckusick daddr_t ino; 914359Smckusick register struct fs *fs; 924359Smckusick register struct inode *ip; 934359Smckusick int cg; 944359Smckusick 954359Smckusick fs = getfs(dev); 964359Smckusick if (fs->fs_nifree == 0) 974359Smckusick goto noinodes; 984359Smckusick cg = itog(ipref, fs); 994359Smckusick ino = hashalloc(dev, fs, cg, (long)ipref, mode, ialloccg); 1004359Smckusick if (ino == 0) 1014359Smckusick goto noinodes; 1024359Smckusick ip = iget(dev, ino); 1034359Smckusick if (ip == NULL) { 1044359Smckusick ifree(dev, ino); 1054359Smckusick return (NULL); 1064359Smckusick } 1074359Smckusick if (ip->i_mode) 1084359Smckusick panic("ialloc: dup alloc"); 1094359Smckusick return (ip); 1104359Smckusick noinodes: 1114359Smckusick fserr(fs, "out of inodes"); 1124359Smckusick uprintf("\n%s: create failed, no inodes free\n", fs->fs_fsmnt); 1134359Smckusick u.u_error = ENOSPC; 1144359Smckusick return (NULL); 1154359Smckusick } 1164359Smckusick 1174359Smckusick dipref(dev) 1184359Smckusick dev_t dev; 1194359Smckusick { 1204359Smckusick register struct fs *fs; 1214359Smckusick int cg, minndir, mincg; 1224359Smckusick 1234359Smckusick fs = getfs(dev); 1244359Smckusick minndir = fs->fs_cs[0].cs_ndir; 1254359Smckusick mincg = 0; 1264359Smckusick for (cg = 1; cg < fs->fs_ncg; cg++) 1274359Smckusick if (fs->fs_cs[cg].cs_ndir < minndir) { 1284359Smckusick mincg = cg; 1294359Smckusick minndir = fs->fs_cs[cg].cs_ndir; 1304359Smckusick if (minndir == 0) 1314359Smckusick break; 1324359Smckusick } 1334359Smckusick return (fs->fs_ipg * mincg); 1344359Smckusick } 1354359Smckusick 1364359Smckusick long 1374359Smckusick hashalloc(dev, fs, cg, pref, size, allocator) 1384359Smckusick dev_t dev; 1394359Smckusick register struct fs *fs; 1404359Smckusick int cg; 1414359Smckusick long pref; 1424359Smckusick int size; /* size for data blocks, mode for inodes */ 1434359Smckusick long (*allocator)(); 1444359Smckusick { 1454359Smckusick long result; 1464359Smckusick int i, icg = cg; 1474359Smckusick 1484359Smckusick /* 1494359Smckusick * 1: preferred cylinder group 1504359Smckusick */ 1514359Smckusick result = (*allocator)(dev, fs, cg, pref, size); 1524359Smckusick if (result) 1534359Smckusick return (result); 1544359Smckusick /* 1554359Smckusick * 2: quadratic rehash 1564359Smckusick */ 1574359Smckusick for (i = 1; i < fs->fs_ncg; i *= 2) { 1584359Smckusick cg += i; 1594359Smckusick if (cg >= fs->fs_ncg) 1604359Smckusick cg -= fs->fs_ncg; 1614359Smckusick result = (*allocator)(dev, fs, cg, 0, size); 1624359Smckusick if (result) 1634359Smckusick return (result); 1644359Smckusick } 1654359Smckusick /* 1664359Smckusick * 3: brute force search 1674359Smckusick */ 1684359Smckusick cg = icg; 1694359Smckusick for (i = 0; i < fs->fs_ncg; i++) { 1704359Smckusick result = (*allocator)(dev, fs, cg, 0, size); 1714359Smckusick if (result) 1724359Smckusick return (result); 1734359Smckusick cg++; 1744359Smckusick if (cg == fs->fs_ncg) 1754359Smckusick cg = 0; 1764359Smckusick } 1774359Smckusick return (0); 1784359Smckusick } 1794359Smckusick 1804359Smckusick daddr_t 181*4426Smckusic fragalloc(dev, fs, cg, pref, osize, nsize) 182*4426Smckusic dev_t dev; 183*4426Smckusic register struct fs *fs; 184*4426Smckusic int cg; 185*4426Smckusic long pref; 186*4426Smckusic int osize, nsize; 187*4426Smckusic { 188*4426Smckusic struct buf *bp; 189*4426Smckusic struct cg *cgp; 190*4426Smckusic int i; 191*4426Smckusic 192*4426Smckusic if ((unsigned)osize > BSIZE || osize % FSIZE != 0 || 193*4426Smckusic (unsigned)nsize > BSIZE || nsize % FSIZE != 0) 194*4426Smckusic panic("fragalloc: bad size"); 195*4426Smckusic bp = bread(dev, cgtod(cg, fs), BSIZE); 196*4426Smckusic if (bp->b_flags & B_ERROR) 197*4426Smckusic return (0); 198*4426Smckusic cgp = bp->b_un.b_cg; 199*4426Smckusic if (pref) { 200*4426Smckusic pref %= fs->fs_fpg; 201*4426Smckusic for (i = osize / FSIZE; i < nsize / FSIZE; i++) { 202*4426Smckusic if (isclr(cgp->cg_free, pref + i)) 203*4426Smckusic break; 204*4426Smckusic } 205*4426Smckusic if (i == nsize / FSIZE) 206*4426Smckusic goto extendit; 207*4426Smckusic } 208*4426Smckusic /* 209*4426Smckusic * MUST FIND ALTERNATE LOCATION 210*4426Smckusic */ 211*4426Smckusic panic("fragalloc: reallocation too hard!"); 212*4426Smckusic brelse(bp); 213*4426Smckusic return (0); 214*4426Smckusic extendit: 215*4426Smckusic for (i = osize / FSIZE; i < nsize / FSIZE; i++) { 216*4426Smckusic clrbit(cgp->cg_free, pref + i); 217*4426Smckusic cgp->cg_nffree--; 218*4426Smckusic fs->fs_nffree--; 219*4426Smckusic } 220*4426Smckusic fs->fs_fmod++; 221*4426Smckusic bdwrite(bp); 222*4426Smckusic return (cg * fs->fs_fpg + pref); 223*4426Smckusic } 224*4426Smckusic 225*4426Smckusic daddr_t 2264359Smckusick alloccg(dev, fs, cg, bpref, size) 2274359Smckusick dev_t dev; 2284359Smckusick struct fs *fs; 2294359Smckusick int cg; 2304359Smckusick daddr_t bpref; 2314359Smckusick int size; 2324359Smckusick { 2334359Smckusick struct buf *bp; 2344359Smckusick struct cg *cgp; 2354359Smckusick int i; 2364359Smckusick 237*4426Smckusic if ((unsigned)size > BSIZE || size % FSIZE != 0) 238*4426Smckusic panic("alloccg: bad size"); 239*4426Smckusic bp = bread(dev, cgtod(cg, fs), BSIZE); 2404359Smckusick if (bp->b_flags & B_ERROR) 2414359Smckusick return (0); 2424359Smckusick cgp = bp->b_un.b_cg; 2434359Smckusick if (bpref) { 2444359Smckusick bpref %= fs->fs_fpg; 2454359Smckusick if (isblock(cgp->cg_free, bpref/FRAG)) 2464359Smckusick goto gotit; 2474359Smckusick } else 2484359Smckusick bpref = cgp->cg_rotor; 2494359Smckusick for (i = 0; i < cgp->cg_ndblk; i += FRAG) { 2504359Smckusick bpref += FRAG; 2514359Smckusick if (bpref >= cgp->cg_ndblk) 2524359Smckusick bpref = 0; 2534359Smckusick if (isblock(cgp->cg_free, bpref/FRAG)) { 2544359Smckusick cgp->cg_rotor = bpref; 2554359Smckusick goto gotit; 2564359Smckusick } 2574359Smckusick } 2584359Smckusick brelse(bp); 2594359Smckusick return (0); 2604359Smckusick gotit: 261*4426Smckusic if (size == BSIZE) { 262*4426Smckusic clrblock(cgp->cg_free, bpref/FRAG); 263*4426Smckusic cgp->cg_nbfree--; 264*4426Smckusic fs->fs_nbfree--; 265*4426Smckusic fs->fs_cs[cg].cs_nbfree--; 266*4426Smckusic i = bpref * NSPF; 267*4426Smckusic cgp->cg_b[i/fs->fs_spc][i%fs->fs_nsect*NRPOS/fs->fs_nsect]--; 268*4426Smckusic } else { 269*4426Smckusic cgp->cg_nffree += FRAG; 270*4426Smckusic fs->fs_nffree += FRAG; 271*4426Smckusic for (i = 0; i < size / FSIZE; i++) { 272*4426Smckusic clrbit(cgp->cg_free, bpref + i); 273*4426Smckusic cgp->cg_nffree--; 274*4426Smckusic fs->fs_nffree--; 275*4426Smckusic } 276*4426Smckusic cgp->cg_nbfree--; 277*4426Smckusic fs->fs_nbfree--; 278*4426Smckusic fs->fs_cs[cg].cs_nbfree--; 279*4426Smckusic i = bpref * NSPF; 280*4426Smckusic cgp->cg_b[i/fs->fs_spc][i%fs->fs_nsect*NRPOS/fs->fs_nsect]--; 281*4426Smckusic } 2824359Smckusick fs->fs_fmod++; 2834359Smckusick bdwrite(bp); 2844359Smckusick return (cg * fs->fs_fpg + bpref); 2854359Smckusick } 2864359Smckusick 2874359Smckusick long 2884359Smckusick ialloccg(dev, fs, cg, ipref, mode) 2894359Smckusick dev_t dev; 2904359Smckusick struct fs *fs; 2914359Smckusick int cg; 2924359Smckusick daddr_t ipref; 2934359Smckusick int mode; 2944359Smckusick { 2954359Smckusick struct buf *bp; 2964359Smckusick struct cg *cgp; 2974359Smckusick int i; 2984359Smckusick 299*4426Smckusic bp = bread(dev, cgtod(cg, fs), BSIZE); 3004359Smckusick if (bp->b_flags & B_ERROR) 3014359Smckusick return (0); 3024359Smckusick cgp = bp->b_un.b_cg; 3034359Smckusick if (cgp->cg_nifree == 0) { 3044359Smckusick brelse(bp); 3054359Smckusick return (0); 3064359Smckusick } 3074359Smckusick if (ipref) { 3084359Smckusick ipref %= fs->fs_ipg; 3094359Smckusick if (isclr(cgp->cg_iused, ipref)) 3104359Smckusick goto gotit; 3114359Smckusick } else 3124359Smckusick ipref = cgp->cg_irotor; 3134359Smckusick for (i = 0; i < fs->fs_ipg; i++) { 3144359Smckusick ipref++; 3154359Smckusick if (ipref >= fs->fs_ipg) 3164359Smckusick ipref = 0; 3174359Smckusick if (isclr(cgp->cg_iused, ipref)) { 3184359Smckusick cgp->cg_irotor = ipref; 3194359Smckusick goto gotit; 3204359Smckusick } 3214359Smckusick } 3224359Smckusick brelse(bp); 3234359Smckusick return (0); 3244359Smckusick gotit: 3254359Smckusick setbit(cgp->cg_iused, ipref); 3264359Smckusick cgp->cg_nifree--; 3274359Smckusick fs->fs_nifree--; 3284359Smckusick fs->fs_cs[cg].cs_nifree--; 3294359Smckusick fs->fs_fmod++; 3304359Smckusick if ((mode & IFMT) == IFDIR) { 3314359Smckusick cgp->cg_ndir++; 3324359Smckusick fs->fs_cs[cg].cs_ndir++; 3334359Smckusick } 3344359Smckusick bdwrite(bp); 3354359Smckusick return (cg * fs->fs_ipg + ipref); 3364359Smckusick } 3374359Smckusick 3384359Smckusick fre(dev, bno, size) 3394359Smckusick dev_t dev; 3404359Smckusick daddr_t bno; 3414359Smckusick int size; 3424359Smckusick { 3434359Smckusick register struct fs *fs; 3444359Smckusick register struct cg *cgp; 3454359Smckusick register struct buf *bp; 3464359Smckusick int i; 3474359Smckusick int cg; 3484359Smckusick 349*4426Smckusic if ((unsigned)size > BSIZE || size % FSIZE != 0) 350*4426Smckusic panic("free: bad size"); 3514359Smckusick fs = getfs(dev); 3524359Smckusick cg = dtog(bno, fs); 3534359Smckusick if (badblock(fs, bno)) 3544359Smckusick return; 355*4426Smckusic bp = bread(dev, cgtod(cg, fs), BSIZE); 3564359Smckusick if (bp->b_flags & B_ERROR) 3574359Smckusick return; 3584359Smckusick cgp = bp->b_un.b_cg; 3594359Smckusick bno %= fs->fs_fpg; 360*4426Smckusic if (size == BSIZE) { 361*4426Smckusic if (isblock(cgp->cg_free, bno/FRAG)) 362*4426Smckusic panic("free: freeing free block"); 363*4426Smckusic setblock(cgp->cg_free, bno/FRAG); 364*4426Smckusic cgp->cg_nbfree++; 365*4426Smckusic fs->fs_nbfree++; 366*4426Smckusic fs->fs_cs[cg].cs_nbfree++; 367*4426Smckusic i = bno * NSPF; 368*4426Smckusic cgp->cg_b[i/fs->fs_spc][i%fs->fs_nsect*NRPOS/fs->fs_nsect]++; 369*4426Smckusic } else { 370*4426Smckusic for (i = 0; i < size / FSIZE; i++) { 371*4426Smckusic if (isset(cgp->cg_free, bno + i)) 372*4426Smckusic panic("free: freeing free frag"); 373*4426Smckusic setbit(cgp->cg_free, bno + i); 374*4426Smckusic cgp->cg_nffree++; 375*4426Smckusic fs->fs_nffree++; 376*4426Smckusic } 377*4426Smckusic if (isblock(cgp->cg_free, (bno - bno % FRAG) / FRAG)) { 378*4426Smckusic cgp->cg_nffree -= FRAG; 379*4426Smckusic fs->fs_nffree -= FRAG; 380*4426Smckusic cgp->cg_nbfree++; 381*4426Smckusic fs->fs_nbfree++; 382*4426Smckusic fs->fs_cs[cg].cs_nbfree++; 383*4426Smckusic i = bno * NSPF; 384*4426Smckusic cgp->cg_b[i / fs->fs_spc] 385*4426Smckusic [i % fs->fs_nsect * NRPOS / fs->fs_nsect]++; 386*4426Smckusic } 387*4426Smckusic } 3884359Smckusick fs->fs_fmod++; 3894359Smckusick bdwrite(bp); 3904359Smckusick } 3914359Smckusick 3924359Smckusick ifree(dev, ino, mode) 3934359Smckusick dev_t dev; 3944359Smckusick ino_t ino; 3954359Smckusick int mode; 3964359Smckusick { 3974359Smckusick register struct fs *fs; 3984359Smckusick register struct cg *cgp; 3994359Smckusick register struct buf *bp; 4004359Smckusick int i; 4014359Smckusick int cg; 4024359Smckusick 4034359Smckusick fs = getfs(dev); 4044359Smckusick if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg) 4054359Smckusick panic("ifree: range"); 4064359Smckusick cg = itog(ino, fs); 407*4426Smckusic bp = bread(dev, cgtod(cg, fs), BSIZE); 4084359Smckusick if (bp->b_flags & B_ERROR) 4094359Smckusick return; 4104359Smckusick cgp = bp->b_un.b_cg; 4114359Smckusick ino %= fs->fs_ipg; 4124359Smckusick if (isclr(cgp->cg_iused, ino)) 4134359Smckusick panic("ifree: freeing free inode"); 4144359Smckusick clrbit(cgp->cg_iused, ino); 4154359Smckusick cgp->cg_nifree++; 4164359Smckusick fs->fs_nifree++; 4174359Smckusick fs->fs_cs[cg].cs_nifree++; 4184359Smckusick if ((mode & IFMT) == IFDIR) { 4194359Smckusick cgp->cg_ndir--; 4204359Smckusick fs->fs_cs[cg].cs_ndir--; 4214359Smckusick } 4224359Smckusick fs->fs_fmod++; 4234359Smckusick bdwrite(bp); 4244359Smckusick } 4254359Smckusick 4264359Smckusick badblock(fs, bn) 4274359Smckusick register struct fs *fs; 4284359Smckusick daddr_t bn; 4294359Smckusick { 4304359Smckusick 4314359Smckusick if ((unsigned)bn >= fs->fs_size || bn < cgdmin(dtog(bn, fs), fs)) { 4324359Smckusick fserr(fs, "bad block"); 4334359Smckusick return (1); 4344359Smckusick } 4354359Smckusick return (0); 4364359Smckusick } 4374359Smckusick 4384359Smckusick /* 4394359Smckusick * getfs maps a device number into 4404359Smckusick * a pointer to the incore super 4414359Smckusick * block. The algorithm is a linear 4424359Smckusick * search through the mount table. 4434359Smckusick * A consistency check of the 4444359Smckusick * in core free-block and i-node 4454359Smckusick * counts is performed. 4464359Smckusick * 4474359Smckusick * panic: no fs -- the device is not mounted. 4484359Smckusick * this "cannot happen" 4494359Smckusick */ 4504359Smckusick struct fs * 4514359Smckusick getfs(dev) 4524359Smckusick dev_t dev; 4534359Smckusick { 4544359Smckusick register struct mount *mp; 4554359Smckusick register struct fs *fs; 4564359Smckusick 4574359Smckusick for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 4584359Smckusick if (mp->m_bufp != NULL && mp->m_dev == dev) { 4594359Smckusick fs = mp->m_bufp->b_un.b_fs; 4604359Smckusick if (fs->fs_magic != FS_MAGIC) 4614359Smckusick panic("getfs: bad magic"); 4624359Smckusick return (fs); 4634359Smckusick } 4644359Smckusick panic("getfs: no fs"); 4654359Smckusick return (NULL); 4664359Smckusick } 4674359Smckusick 4684359Smckusick /* 4694359Smckusick * Fserr prints the name of a file system 4704359Smckusick * with an error diagnostic, in the form 4714359Smckusick * fs: error message 4724359Smckusick */ 4734359Smckusick fserr(fs, cp) 4744359Smckusick struct fs *fs; 4754359Smckusick char *cp; 4764359Smckusick { 4774359Smckusick 4784359Smckusick printf("%s: %s\n", fs->fs_fsmnt, cp); 4794359Smckusick } 4804359Smckusick 4814359Smckusick /* 4824359Smckusick * Getfsx returns the index in the file system 4834359Smckusick * table of the specified device. The swap device 4844359Smckusick * is also assigned a pseudo-index. The index may 4854359Smckusick * be used as a compressed indication of the location 4864359Smckusick * of a block, recording 4874359Smckusick * <getfsx(dev),blkno> 4884359Smckusick * rather than 4894359Smckusick * <dev, blkno> 4904359Smckusick * provided the information need remain valid only 4914359Smckusick * as long as the file system is mounted. 4924359Smckusick */ 4934359Smckusick getfsx(dev) 4944359Smckusick dev_t dev; 4954359Smckusick { 4964359Smckusick register struct mount *mp; 4974359Smckusick 4984359Smckusick if (dev == swapdev) 4994359Smckusick return (MSWAPX); 5004359Smckusick for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 5014359Smckusick if (mp->m_dev == dev) 5024359Smckusick return (mp - &mount[0]); 5034359Smckusick return (-1); 5044359Smckusick } 5054359Smckusick 5064359Smckusick /* 5074359Smckusick * Update is the internal name of 'sync'. It goes through the disk 5084359Smckusick * queues to initiate sandbagged IO; goes through the inodes to write 5094359Smckusick * modified nodes; and it goes through the mount table to initiate modified 5104359Smckusick * super blocks. 5114359Smckusick */ 5124359Smckusick update() 5134359Smckusick { 5144359Smckusick register struct inode *ip; 5154359Smckusick register struct mount *mp; 5164359Smckusick register struct buf *bp; 5174359Smckusick struct fs *fs; 5184359Smckusick time_t tim; 5194359Smckusick int i; 5204359Smckusick 5214359Smckusick if (updlock) 5224359Smckusick return; 5234359Smckusick updlock++; 5244359Smckusick /* 5254359Smckusick * Write back modified superblocks. 5264359Smckusick * Consistency check that the superblock 5274359Smckusick * of each file system is still in the buffer cache. 5284359Smckusick */ 5294359Smckusick for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 5304359Smckusick if (mp->m_bufp != NULL) { 5314359Smckusick fs = mp->m_bufp->b_un.b_fs; 5324359Smckusick if (fs->fs_fmod == 0) 5334359Smckusick continue; 5344359Smckusick if (fs->fs_ronly != 0) 5354359Smckusick panic("update: rofs mod"); 536*4426Smckusic bp = getblk(mp->m_dev, SBLOCK, BSIZE); 5374359Smckusick fs->fs_fmod = 0; 5384359Smckusick fs->fs_time = TIME; 5394359Smckusick if (bp->b_un.b_fs != fs) 5404359Smckusick panic("update: bad b_fs"); 5414359Smckusick bwrite(bp); 5424359Smckusick for (i = 0; i < cssize(fs); i += BSIZE) { 543*4426Smckusic bp = getblk(mp->m_dev, csaddr(fs) + i / FSIZE, 544*4426Smckusic BSIZE); 5454359Smckusick bcopy(fs->fs_cs + i, bp->b_un.b_addr, BSIZE); 5464359Smckusick bwrite(bp); 5474359Smckusick } 5484359Smckusick } 5494359Smckusick /* 5504359Smckusick * Write back each (modified) inode. 5514359Smckusick */ 5524359Smckusick for (ip = inode; ip < inodeNINODE; ip++) 5534359Smckusick if((ip->i_flag&ILOCK)==0 && ip->i_count) { 5544359Smckusick ip->i_flag |= ILOCK; 5554359Smckusick ip->i_count++; 5564359Smckusick tim = TIME; 5574359Smckusick iupdat(ip, &tim, &tim, 0); 5584359Smckusick iput(ip); 5594359Smckusick } 5604359Smckusick updlock = 0; 5614359Smckusick /* 5624359Smckusick * Force stale buffer cache information to be flushed, 5634359Smckusick * for all devices. 5644359Smckusick */ 5654359Smckusick bflush(NODEV); 5664359Smckusick } 567