123400Smckusick /* 2*37737Smckusick * Copyright (c) 1989 The Regents of the University of California. 3*37737Smckusick * All rights reserved. 423400Smckusick * 5*37737Smckusick * Redistribution and use in source and binary forms are permitted 6*37737Smckusick * provided that the above copyright notice and this paragraph are 7*37737Smckusick * duplicated in all such forms and that any documentation, 8*37737Smckusick * advertising materials, and other materials related to such 9*37737Smckusick * distribution and use acknowledge that the software was developed 10*37737Smckusick * by the University of California, Berkeley. The name of the 11*37737Smckusick * University may not be used to endorse or promote products derived 12*37737Smckusick * from this software without specific prior written permission. 13*37737Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*37737Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*37737Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*37737Smckusick * 17*37737Smckusick * @(#)lfs_vfsops.c 7.13 (Berkeley) 05/09/89 1823400Smckusick */ 1912795Ssam 20*37737Smckusick 2117100Sbloom #include "param.h" 2217100Sbloom #include "systm.h" 23*37737Smckusick #include "time.h" 24*37737Smckusick #include "kernel.h" 25*37737Smckusick #include "namei.h" 26*37737Smckusick #include "vnode.h" 27*37737Smckusick #include "mount.h" 2817100Sbloom #include "buf.h" 2917100Sbloom #include "file.h" 30*37737Smckusick #include "disklabel.h" 3130749Skarels #include "ioctl.h" 32*37737Smckusick #include "errno.h" 3331660Smckusick #include "malloc.h" 34*37737Smckusick #include "../ufs/fs.h" 35*37737Smckusick #include "../ufs/ufsmount.h" 36*37737Smckusick #include "../ufs/inode.h" 3712795Ssam 38*37737Smckusick /* 39*37737Smckusick * ufs vfs operations. 40*37737Smckusick */ 41*37737Smckusick int ufs_mount(); 42*37737Smckusick int ufs_unmount(); 43*37737Smckusick int ufs_root(); 44*37737Smckusick int ufs_statfs(); 45*37737Smckusick int ufs_sync(); 46*37737Smckusick int ufs_fhtovp(); 47*37737Smckusick int ufs_vptofh(); 48*37737Smckusick 49*37737Smckusick struct vfsops ufs_vfsops = { 50*37737Smckusick ufs_mount, 51*37737Smckusick ufs_unmount, 52*37737Smckusick ufs_root, 53*37737Smckusick ufs_statfs, 54*37737Smckusick ufs_sync, 55*37737Smckusick ufs_fhtovp, 56*37737Smckusick ufs_vptofh 57*37737Smckusick }; 58*37737Smckusick 59*37737Smckusick /* 60*37737Smckusick * ufs mount table. 61*37737Smckusick */ 62*37737Smckusick struct ufsmount mounttab[NMOUNT]; 63*37737Smckusick 64*37737Smckusick /* 65*37737Smckusick * Called by vfs_mountroot when ufs is going to be mounted as root 66*37737Smckusick * 67*37737Smckusick * XXX - Need to have a way of figuring the name of the root device 68*37737Smckusick */ 69*37737Smckusick #define ROOTNAME "root device" 70*37737Smckusick 71*37737Smckusick ufs_mountroot() 7212795Ssam { 73*37737Smckusick register struct mount *mp; 74*37737Smckusick extern struct vnode *rootvp; 75*37737Smckusick struct ufsmount *ump; 7612795Ssam register struct fs *fs; 77*37737Smckusick u_int size; 78*37737Smckusick int error; 7912795Ssam 80*37737Smckusick mp = (struct mount *)malloc((u_long)sizeof(struct mount), 81*37737Smckusick M_MOUNT, M_WAITOK); 82*37737Smckusick mp->m_op = &ufs_vfsops; 83*37737Smckusick mp->m_flag = 0; 84*37737Smckusick mp->m_exroot = 0; 85*37737Smckusick error = mountfs(rootvp, mp); 86*37737Smckusick if (error) { 87*37737Smckusick free((caddr_t)mp, M_MOUNT); 88*37737Smckusick return (error); 8912795Ssam } 90*37737Smckusick error = vfs_add((struct vnode *)0, mp, 0); 91*37737Smckusick if (error) { 92*37737Smckusick (void)ufs_unmount(mp, 0); 93*37737Smckusick free((caddr_t)mp, M_MOUNT); 94*37737Smckusick return (error); 9521013Smckusick } 96*37737Smckusick ump = VFSTOUFS(mp); 97*37737Smckusick fs = ump->um_fs; 98*37737Smckusick fs->fs_fsmnt[0] = '/'; 99*37737Smckusick bzero(fs->fs_fsmnt + 1, sizeof(fs->fs_fsmnt) - 1); 100*37737Smckusick (void) copystr(ROOTNAME, ump->um_mntname, MNAMELEN - 1, &size); 101*37737Smckusick bzero(ump->um_mntname + size, MNAMELEN - size); 102*37737Smckusick vfs_unlock(mp); 103*37737Smckusick inittodr(fs->fs_time); 104*37737Smckusick return (0); 105*37737Smckusick } 106*37737Smckusick 107*37737Smckusick /* 108*37737Smckusick * VFS Operations. 109*37737Smckusick * 110*37737Smckusick * mount system call 111*37737Smckusick */ 112*37737Smckusick ufs_mount(mp, path, data, ndp) 113*37737Smckusick struct mount *mp; 114*37737Smckusick char *path; 115*37737Smckusick caddr_t data; 116*37737Smckusick struct nameidata *ndp; 117*37737Smckusick { 118*37737Smckusick struct vnode *devvp; 119*37737Smckusick struct ufs_args args; 120*37737Smckusick struct ufsmount *ump; 121*37737Smckusick register struct fs *fs; 122*37737Smckusick u_int size; 123*37737Smckusick int error; 124*37737Smckusick 125*37737Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) 126*37737Smckusick return (error); 127*37737Smckusick if ((error = getmdev(&devvp, args.fspec, ndp)) != 0) 128*37737Smckusick return (error); 129*37737Smckusick error = mountfs(devvp, mp); 130*37737Smckusick if (error) { 131*37737Smckusick vrele(devvp); 132*37737Smckusick return (error); 13332721Smckusick } 134*37737Smckusick ump = VFSTOUFS(mp); 135*37737Smckusick fs = ump->um_fs; 136*37737Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 137*37737Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 138*37737Smckusick (void) copyinstr(args.fspec, ump->um_mntname, MNAMELEN - 1, &size); 139*37737Smckusick bzero(ump->um_mntname + size, MNAMELEN - size); 140*37737Smckusick return (0); 14112795Ssam } 14212795Ssam 143*37737Smckusick /* 144*37737Smckusick * Common code for mount and mountroot 145*37737Smckusick */ 146*37737Smckusick mountfs(devvp, mp) 147*37737Smckusick struct vnode *devvp; 148*37737Smckusick struct mount *mp; 14912795Ssam { 150*37737Smckusick register struct ufsmount *ump; 151*37737Smckusick struct ufsmount *fmp = NULL; 152*37737Smckusick struct buf *bp = NULL; 15312795Ssam register struct fs *fs; 154*37737Smckusick dev_t dev = devvp->v_rdev; 15530749Skarels struct partinfo dpart; 156*37737Smckusick caddr_t base, space; 15730749Skarels int havepart = 0, blks; 158*37737Smckusick int error, i, size; 15921013Smckusick int needclose = 0; 160*37737Smckusick int ronly = (mp->m_flag & M_RDONLY) != 0; 16112795Ssam 162*37737Smckusick for (ump = &mounttab[0]; ump < &mounttab[NMOUNT]; ump++) { 163*37737Smckusick if (ump->um_fs == NULL) { 16432721Smckusick if (fmp == NULL) 165*37737Smckusick fmp = ump; 166*37737Smckusick } else if (dev == ump->um_dev) { 167*37737Smckusick return (EBUSY); /* needs translation */ 16832721Smckusick } 16932721Smckusick } 170*37737Smckusick if ((ump = fmp) == NULL) 171*37737Smckusick return (EMFILE); /* needs translation */ 172*37737Smckusick ump->um_fs = (struct fs *)1; /* just to reserve this slot */ 173*37737Smckusick error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, 174*37737Smckusick (struct ucred *)0); 17532721Smckusick if (error) { 176*37737Smckusick ump->um_fs = NULL; 177*37737Smckusick return (error); 17832721Smckusick } 17921013Smckusick needclose = 1; 180*37737Smckusick if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, 181*37737Smckusick (struct ucred *)0) != 0) 182*37737Smckusick size = DEV_BSIZE; 183*37737Smckusick else { 18430749Skarels havepart = 1; 18530749Skarels size = dpart.disklab->d_secsize; 186*37737Smckusick } 187*37737Smckusick if (error = bread(devvp, SBLOCK, SBSIZE, &bp)) { 188*37737Smckusick ump->um_fs = NULL; 18912795Ssam goto out; 19032721Smckusick } 19134421Skarels fs = bp->b_un.b_fs; 19230749Skarels if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 19330749Skarels fs->fs_bsize < sizeof(struct fs)) { 194*37737Smckusick ump->um_fs = NULL; 195*37737Smckusick error = EINVAL; /* XXX also needs translation */ 19616639Skarels goto out; 19716639Skarels } 198*37737Smckusick ump->um_fs = (struct fs *)malloc((u_long)fs->fs_sbsize, M_SUPERBLK, 19934473Smckusick M_WAITOK); 200*37737Smckusick bcopy((caddr_t)bp->b_un.b_addr, (caddr_t)ump->um_fs, 20112795Ssam (u_int)fs->fs_sbsize); 20234421Skarels brelse(bp); 20334421Skarels bp = NULL; 204*37737Smckusick fs = ump->um_fs; 205*37737Smckusick fs->fs_ronly = ronly; 20612795Ssam if (ronly == 0) 20712795Ssam fs->fs_fmod = 1; 20830749Skarels if (havepart) { 20930749Skarels dpart.part->p_fstype = FS_BSDFFS; 21030749Skarels dpart.part->p_fsize = fs->fs_fsize; 21130749Skarels dpart.part->p_frag = fs->fs_frag; 21231385Skarels dpart.part->p_cpg = fs->fs_cpg; 21330749Skarels } 21412795Ssam blks = howmany(fs->fs_cssize, fs->fs_fsize); 21534473Smckusick base = space = (caddr_t)malloc((u_long)fs->fs_cssize, M_SUPERBLK, 21634473Smckusick M_WAITOK); 21712795Ssam for (i = 0; i < blks; i += fs->fs_frag) { 21812795Ssam size = fs->fs_bsize; 21912795Ssam if (i + fs->fs_frag > blks) 22012795Ssam size = (blks - i) * fs->fs_fsize; 221*37737Smckusick error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, &bp); 222*37737Smckusick if (error) { 22334473Smckusick free((caddr_t)base, M_SUPERBLK); 22412795Ssam goto out; 22512795Ssam } 22634421Skarels bcopy((caddr_t)bp->b_un.b_addr, space, (u_int)size); 22717225Smckusick fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 22812795Ssam space += size; 22934421Skarels brelse(bp); 23034421Skarels bp = NULL; 23112795Ssam } 232*37737Smckusick mp->m_data = (qaddr_t)ump; 233*37737Smckusick mp->m_bsize = fs->fs_bsize; 234*37737Smckusick mp->m_fsize = fs->fs_fsize; 235*37737Smckusick mp->m_fsid.val[0] = (long)dev; 236*37737Smckusick mp->m_fsid.val[1] = MOUNT_UFS; 237*37737Smckusick ump->um_mountp = mp; 238*37737Smckusick ump->um_dev = dev; 239*37737Smckusick ump->um_devvp = devvp; 240*37737Smckusick ump->um_qinod = NULL; 241*37737Smckusick 24230383Smckusick /* Sanity checks for old file systems. XXX */ 24330383Smckusick fs->fs_npsect = MAX(fs->fs_npsect, fs->fs_nsect); /* XXX */ 24430383Smckusick fs->fs_interleave = MAX(fs->fs_interleave, 1); /* XXX */ 24534145Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 24634145Smckusick fs->fs_nrpos = 8; /* XXX */ 247*37737Smckusick return (0); 24812795Ssam out: 24932721Smckusick if (needclose) 250*37737Smckusick (void) VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, 251*37737Smckusick (struct ucred *)0); 252*37737Smckusick if (ump->um_fs) { 253*37737Smckusick free((caddr_t)ump->um_fs, M_SUPERBLK); 254*37737Smckusick ump->um_fs = NULL; 25532721Smckusick } 25634421Skarels if (bp) 25734421Skarels brelse(bp); 258*37737Smckusick return (error); 25912795Ssam } 26012795Ssam 26112795Ssam 262*37737Smckusick /* 263*37737Smckusick * unmount system call 264*37737Smckusick */ 265*37737Smckusick ufs_unmount(mp, flags) 266*37737Smckusick struct mount *mp; 267*37737Smckusick int flags; 26812795Ssam { 269*37737Smckusick register struct ufsmount *ump; 270*37737Smckusick register struct fs *fs; 27112795Ssam dev_t dev; 272*37737Smckusick int error, ronly; 27312795Ssam 274*37737Smckusick if (flags & MNT_FORCE) 275*37737Smckusick return (EINVAL); 276*37737Smckusick ump = VFSTOUFS(mp); 277*37737Smckusick dev = ump->um_dev; 27812795Ssam #ifdef QUOTA 279*37737Smckusick if (error = iflush(dev, ump->um_qinod)) 28012795Ssam #else 281*37737Smckusick if (error = iflush(dev)) 28212795Ssam #endif 28330749Skarels return (error); 28412795Ssam #ifdef QUOTA 285*37737Smckusick (void)closedq(ump); 28612795Ssam /* 28712795Ssam * Here we have to iflush again to get rid of the quota inode. 288*37737Smckusick * A drag, but it would be ugly to cheat, & this doesn't happen often 28912795Ssam */ 29012795Ssam (void)iflush(dev, (struct inode *)NULL); 29112795Ssam #endif 292*37737Smckusick fs = ump->um_fs; 293*37737Smckusick ronly = !fs->fs_ronly; 29431660Smckusick free((caddr_t)fs->fs_csp[0], M_SUPERBLK); 295*37737Smckusick free((caddr_t)fs, M_SUPERBLK); 296*37737Smckusick ump->um_fs = NULL; 297*37737Smckusick ump->um_dev = NODEV; 298*37737Smckusick error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, 299*37737Smckusick (struct ucred *)0); 300*37737Smckusick vrele(ump->um_devvp); 301*37737Smckusick ump->um_devvp = (struct vnode *)0; 30230749Skarels return (error); 30312795Ssam } 30412795Ssam 305*37737Smckusick /* 306*37737Smckusick * Return root of a filesystem 307*37737Smckusick */ 308*37737Smckusick ufs_root(mp, vpp) 30912795Ssam struct mount *mp; 310*37737Smckusick struct vnode **vpp; 31112795Ssam { 312*37737Smckusick struct inode tip, *ip; 313*37737Smckusick int error; 314*37737Smckusick 315*37737Smckusick tip.i_dev = VFSTOUFS(mp)->um_dev; 316*37737Smckusick tip.i_vnode.v_mount = mp; 317*37737Smckusick error = iget(&tip, (ino_t)ROOTINO, &ip); 318*37737Smckusick if (error) 319*37737Smckusick return (error); 320*37737Smckusick *vpp = ITOV(ip); 321*37737Smckusick return (0); 322*37737Smckusick } 323*37737Smckusick 324*37737Smckusick /* 325*37737Smckusick * Get file system statistics. 326*37737Smckusick */ 327*37737Smckusick ufs_statfs(mp, sbp) 328*37737Smckusick struct mount *mp; 329*37737Smckusick register struct statfs *sbp; 330*37737Smckusick { 331*37737Smckusick register struct ufsmount *ump; 332*37737Smckusick register struct fs *fs; 333*37737Smckusick 334*37737Smckusick ump = VFSTOUFS(mp); 335*37737Smckusick fs = ump->um_fs; 336*37737Smckusick if (fs->fs_magic != FS_MAGIC) 337*37737Smckusick panic("ufs_statfs"); 338*37737Smckusick sbp->f_type = MOUNT_UFS; 339*37737Smckusick sbp->f_flags = mp->m_flag &~ (M_MLOCK|M_MWAIT); 340*37737Smckusick sbp->f_fsize = fs->fs_fsize; 341*37737Smckusick sbp->f_bsize = fs->fs_bsize; 342*37737Smckusick sbp->f_blocks = fs->fs_dsize; 343*37737Smckusick sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 344*37737Smckusick fs->fs_cstotal.cs_nffree; 345*37737Smckusick sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) - 346*37737Smckusick (fs->fs_dsize - sbp->f_bfree); 347*37737Smckusick if (sbp->f_bavail < 0) 348*37737Smckusick sbp->f_bavail = 0; 349*37737Smckusick sbp->f_files = fs->fs_ncg * fs->fs_ipg; 350*37737Smckusick sbp->f_ffree = fs->fs_cstotal.cs_nifree; 351*37737Smckusick sbp->f_fsid = mp->m_fsid; 352*37737Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 353*37737Smckusick bcopy((caddr_t)ump->um_mntname, (caddr_t)&sbp->f_mntfromname[0], 354*37737Smckusick MNAMELEN); 355*37737Smckusick return (0); 356*37737Smckusick } 357*37737Smckusick 358*37737Smckusick int syncprt = 0; 359*37737Smckusick 360*37737Smckusick /* 361*37737Smckusick * Go through the disk queues to initiate sandbagged IO; 362*37737Smckusick * go through the inodes to write those that have been modified; 363*37737Smckusick * initiate the writing of the super block if it has been modified. 364*37737Smckusick */ 365*37737Smckusick ufs_sync(mp, waitfor) 366*37737Smckusick struct mount *mp; 367*37737Smckusick int waitfor; 368*37737Smckusick { 369*37737Smckusick register struct inode *ip; 370*37737Smckusick register struct ufsmount *ump = VFSTOUFS(mp); 371*37737Smckusick register struct fs *fs; 372*37737Smckusick int error = 0; 373*37737Smckusick static int updlock = 0; 374*37737Smckusick 375*37737Smckusick if (syncprt) 376*37737Smckusick bufstats(); 377*37737Smckusick if (updlock) 378*37737Smckusick return (EBUSY); 379*37737Smckusick fs = ump->um_fs; 380*37737Smckusick if (fs == (struct fs *)1) 381*37737Smckusick return (0); 382*37737Smckusick updlock++; 383*37737Smckusick /* 384*37737Smckusick * Write back modified superblock. 385*37737Smckusick * Consistency check that the superblock 386*37737Smckusick * is still in the buffer cache. 387*37737Smckusick */ 388*37737Smckusick if (fs->fs_fmod != 0) { 389*37737Smckusick if (fs->fs_ronly != 0) { /* XXX */ 390*37737Smckusick printf("fs = %s\n", fs->fs_fsmnt); 391*37737Smckusick panic("update: rofs mod"); 392*37737Smckusick } 393*37737Smckusick fs->fs_fmod = 0; 394*37737Smckusick fs->fs_time = time.tv_sec; 395*37737Smckusick error = sbupdate(ump, waitfor); 396*37737Smckusick } 397*37737Smckusick /* 398*37737Smckusick * Write back each (modified) inode. 399*37737Smckusick */ 400*37737Smckusick for (ip = inode; ip < inodeNINODE; ip++) { 401*37737Smckusick if (ip->i_devvp != ump->um_devvp || 402*37737Smckusick (ip->i_flag & ILOCKED) != 0 || ITOV(ip)->v_count == 0 || 403*37737Smckusick (ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0) 404*37737Smckusick continue; 405*37737Smckusick ip->i_flag |= ILOCKED; 406*37737Smckusick ITOV(ip)->v_count++; 407*37737Smckusick error = iupdat(ip, &time, &time, waitfor == MNT_WAIT); 408*37737Smckusick iput(ip); 409*37737Smckusick } 410*37737Smckusick updlock = 0; 411*37737Smckusick /* 412*37737Smckusick * Force stale buffer cache information to be flushed. 413*37737Smckusick */ 414*37737Smckusick bflush(ump->um_devvp->v_rdev); 415*37737Smckusick return (error); 416*37737Smckusick } 417*37737Smckusick 418*37737Smckusick /* 419*37737Smckusick * Write a superblock and associated information back to disk. 420*37737Smckusick */ 421*37737Smckusick sbupdate(mp, waitfor) 422*37737Smckusick struct ufsmount *mp; 423*37737Smckusick int waitfor; 424*37737Smckusick { 425*37737Smckusick register struct fs *fs = mp->um_fs; 42612795Ssam register struct buf *bp; 42712795Ssam int blks; 42812795Ssam caddr_t space; 429*37737Smckusick int i, size, error = 0; 43012795Ssam 431*37737Smckusick bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize); 43212795Ssam bcopy((caddr_t)fs, bp->b_un.b_addr, (u_int)fs->fs_sbsize); 43334145Smckusick /* Restore compatibility to old file systems. XXX */ 43434145Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 43534145Smckusick bp->b_un.b_fs->fs_nrpos = -1; /* XXX */ 436*37737Smckusick if (waitfor == MNT_WAIT) 437*37737Smckusick error = bwrite(bp); 438*37737Smckusick else 439*37737Smckusick bawrite(bp); 44012795Ssam blks = howmany(fs->fs_cssize, fs->fs_fsize); 44112795Ssam space = (caddr_t)fs->fs_csp[0]; 44212795Ssam for (i = 0; i < blks; i += fs->fs_frag) { 44312795Ssam size = fs->fs_bsize; 44412795Ssam if (i + fs->fs_frag > blks) 44512795Ssam size = (blks - i) * fs->fs_fsize; 446*37737Smckusick bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), size); 44712795Ssam bcopy(space, bp->b_un.b_addr, (u_int)size); 44812795Ssam space += size; 449*37737Smckusick if (waitfor == MNT_WAIT) 450*37737Smckusick error = bwrite(bp); 451*37737Smckusick else 452*37737Smckusick bawrite(bp); 45312795Ssam } 454*37737Smckusick return (error); 45512795Ssam } 45612795Ssam 45712795Ssam /* 458*37737Smckusick * Print out statistics on the current allocation of the buffer pool. 459*37737Smckusick * Can be enabled to print out on every ``sync'' by setting "syncprt" 460*37737Smckusick * above. 461*37737Smckusick */ 462*37737Smckusick bufstats() 463*37737Smckusick { 464*37737Smckusick int s, i, j, count; 465*37737Smckusick register struct buf *bp, *dp; 466*37737Smckusick int counts[MAXBSIZE/CLBYTES+1]; 467*37737Smckusick static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" }; 468*37737Smckusick 469*37737Smckusick for (bp = bfreelist, i = 0; bp < &bfreelist[BQUEUES]; bp++, i++) { 470*37737Smckusick count = 0; 471*37737Smckusick for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 472*37737Smckusick counts[j] = 0; 473*37737Smckusick s = splbio(); 474*37737Smckusick for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) { 475*37737Smckusick counts[dp->b_bufsize/CLBYTES]++; 476*37737Smckusick count++; 477*37737Smckusick } 478*37737Smckusick splx(s); 479*37737Smckusick printf("%s: total-%d", bname[i], count); 480*37737Smckusick for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 481*37737Smckusick if (counts[j] != 0) 482*37737Smckusick printf(", %d-%d", j * CLBYTES, counts[j]); 483*37737Smckusick printf("\n"); 484*37737Smckusick } 485*37737Smckusick } 486*37737Smckusick 487*37737Smckusick /* 488*37737Smckusick * File handle to vnode 489*37737Smckusick */ 490*37737Smckusick ufs_fhtovp(mp, fhp, vpp) 491*37737Smckusick struct mount *mp; 492*37737Smckusick struct fid *fhp; 493*37737Smckusick struct vnode **vpp; 494*37737Smckusick { 495*37737Smckusick register struct ufid *ufhp; 496*37737Smckusick struct inode tip, *ip; 497*37737Smckusick int error; 498*37737Smckusick 499*37737Smckusick ufhp = (struct ufid *)fhp; 500*37737Smckusick tip.i_dev = VFSTOUFS(mp)->um_dev; 501*37737Smckusick tip.i_vnode.v_mount = mp; 502*37737Smckusick if (error = iget(&tip, ufhp->ufid_ino, &ip)) { 503*37737Smckusick *vpp = NULL; 504*37737Smckusick return (error); 505*37737Smckusick } 506*37737Smckusick if (ip->i_gen != ufhp->ufid_gen) { 507*37737Smckusick iput(ip); 508*37737Smckusick *vpp = NULL; 509*37737Smckusick return (EINVAL); 510*37737Smckusick } 511*37737Smckusick *vpp = ITOV(ip); 512*37737Smckusick return (0); 513*37737Smckusick } 514*37737Smckusick 515*37737Smckusick /* 516*37737Smckusick * Vnode pointer to File handle, should never happen. 517*37737Smckusick */ 518*37737Smckusick /* ARGSUSED */ 519*37737Smckusick ufs_vptofh(mp, fhp, vpp) 520*37737Smckusick struct mount *mp; 521*37737Smckusick struct fid *fhp; 522*37737Smckusick struct vnode **vpp; 523*37737Smckusick { 524*37737Smckusick 525*37737Smckusick return (EINVAL); 526*37737Smckusick } 527*37737Smckusick 528*37737Smckusick /* 529*37737Smckusick * Common code for mount and quota. 53012795Ssam * Check that the user's argument is a reasonable 53112795Ssam * thing on which to mount, and return the device number if so. 53212795Ssam */ 533*37737Smckusick getmdev(devvpp, fname, ndp) 534*37737Smckusick struct vnode **devvpp; 53516697Smckusick caddr_t fname; 536*37737Smckusick register struct nameidata *ndp; 53712795Ssam { 538*37737Smckusick register struct vnode *vp; 539*37737Smckusick int error; 54012795Ssam 541*37737Smckusick ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW; 54216697Smckusick ndp->ni_segflg = UIO_USERSPACE; 54316697Smckusick ndp->ni_dirp = fname; 544*37737Smckusick if (error = namei(ndp)) { 545*37737Smckusick if (error == ENOENT) 546*37737Smckusick return (ENODEV); /* needs translation */ 547*37737Smckusick return (error); 54821013Smckusick } 549*37737Smckusick vp = ndp->ni_vp; 550*37737Smckusick if (vp->v_type != VBLK) { 551*37737Smckusick vput(vp); 55212795Ssam return (ENOTBLK); 55315956Skarels } 554*37737Smckusick if (major(vp->v_rdev) >= nblkdev) 55512795Ssam return (ENXIO); 556*37737Smckusick iunlock(VTOI(vp)); 557*37737Smckusick *devvpp = vp; 55812795Ssam return (0); 55912795Ssam } 560