Annotation of Net2/pcfs/pcfs_vfsops.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  Written by Paul Popelka ([email protected])
        !             3:  *
        !             4:  *  You can do anything you want with this software,
        !             5:  *    just don't say you wrote it,
        !             6:  *    and don't remove this notice.
        !             7:  *
        !             8:  *  This software is provided "as is".
        !             9:  *
        !            10:  *  The author supplies this software to be publicly
        !            11:  *  redistributed on the understanding that the author
        !            12:  *  is not responsible for the correct functioning of
        !            13:  *  this software in any circumstances and is not liable
        !            14:  *  for any damages caused by this software.
        !            15:  *
        !            16:  *  October 1992
        !            17:  *
        !            18:  *  April 6, 1993:
        !            19:  *     Changed MOUNT_PCFS to MOUNT_MSDOS, this whole package should be renamed
        !            20:  *     to msdosfs, but I did not have the time to do it.  Some one please do
        !            21:  *     this and resubmit it to the patchkit!
        !            22:  *     Rodney W. Grimes
        !            23:  *
        !            24:  *     pcfs_vfsops.c,v 1.4.2.1 1993/08/05 02:37:21 cgd Exp
        !            25:  */
        !            26: 
        !            27: #include "param.h"
        !            28: #include "systm.h"
        !            29: #include "namei.h"
        !            30: #include "proc.h"
        !            31: #include "kernel.h"
        !            32: #include "vnode.h"
        !            33: #include "specdev.h"   /* defines v_rdev       */
        !            34: #include "mount.h"
        !            35: #include "buf.h"
        !            36: #include "file.h"
        !            37: #include "malloc.h"
        !            38: 
        !            39: #include "bpb.h"
        !            40: #include "bootsect.h"
        !            41: #include "direntry.h"
        !            42: #include "denode.h"
        !            43: #include "pcfsmount.h"
        !            44: #include "fat.h"
        !            45: 
        !            46: int pcfsdoforce = 0;   /* 1 = force unmount */
        !            47: 
        !            48: /*
        !            49:  *  mp -
        !            50:  *  path - addr in user space of mount point (ie /usr or whatever)
        !            51:  *  data - addr in user space of mount params including the
        !            52:  *         name of the block special file to treat as a filesystem.
        !            53:  *  ndp  - 
        !            54:  *  p    -
        !            55:  */
        !            56: int
        !            57: pcfs_mount(mp, path, data, ndp, p)
        !            58:        struct mount *mp;
        !            59:        char *path;
        !            60:        caddr_t data;
        !            61:        struct nameidata *ndp;
        !            62:        struct proc *p;
        !            63: {
        !            64:        struct vnode *devvp;    /* vnode for blk device to mount        */
        !            65:        struct pcfs_args args;  /* will hold data from mount request    */
        !            66:        struct pcfsmount *pmp;  /* pcfs specific mount control block    */
        !            67:        int error;
        !            68:        u_int size;
        !            69: 
        !            70: /*
        !            71:  *  Copy in the args for the mount request.
        !            72:  */
        !            73:        if (error = copyin(data, (caddr_t)&args, sizeof(struct pcfs_args)))
        !            74:                return error;
        !            75: 
        !            76: /*
        !            77:  *  Check to see if they want it to be an exportable
        !            78:  *  filesystem via nfs.  And, if they do, should it
        !            79:  *  be read only, and what uid is root to be mapped
        !            80:  *  to.
        !            81:  */
        !            82:        if ((args.exflags & MNT_EXPORTED)  ||  (mp->mnt_flag & MNT_EXPORTED)) {
        !            83:                if (args.exflags & MNT_EXPORTED)
        !            84:                        mp->mnt_flag |= MNT_EXPORTED;
        !            85:                else
        !            86:                        mp->mnt_flag &= ~MNT_EXPORTED;
        !            87:                if (args.exflags & MNT_EXRDONLY)
        !            88:                        mp->mnt_flag |= MNT_EXRDONLY;
        !            89:                else
        !            90:                        mp->mnt_flag &= ~MNT_EXRDONLY;
        !            91:                mp->mnt_exroot = args.exroot;
        !            92:        }
        !            93: 
        !            94: /*
        !            95:  *  If they just want to update then be sure we can
        !            96:  *  do what is asked.  Can't change a filesystem from
        !            97:  *  read/write to read only.  Why?
        !            98:  *  And if they've supplied a new device file name then we
        !            99:  *  continue, otherwise return.
        !           100:  */
        !           101:        if (mp->mnt_flag & MNT_UPDATE) {
        !           102:                pmp = (struct pcfsmount *)mp->mnt_data;
        !           103:                if (pmp->pm_ronly  &&  (mp->mnt_flag & MNT_RDONLY) == 0)
        !           104:                        pmp->pm_ronly = 0;
        !           105:                if (args.fspec == 0)
        !           106:                        return 0;
        !           107:        }
        !           108: 
        !           109: /*
        !           110:  *  Now, lookup the name of the block device this
        !           111:  *  mount or name update request is to apply to.
        !           112:  */
        !           113:        ndp->ni_nameiop = LOOKUP | FOLLOW;
        !           114:        ndp->ni_segflg  = UIO_USERSPACE;
        !           115:        ndp->ni_dirp    = args.fspec;
        !           116:        if (error = namei(ndp, p))
        !           117:                return error;
        !           118: 
        !           119: /*
        !           120:  *  Be sure they've given us a block device to treat
        !           121:  *  as a filesystem.  And, that its major number is
        !           122:  *  within the bdevsw table.
        !           123:  */
        !           124:        devvp = ndp->ni_vp;
        !           125:        if (devvp->v_type != VBLK) {
        !           126:                vrele(devvp);           /* namei() acquires this?       */
        !           127:                return ENOTBLK;
        !           128:        }
        !           129:        if (major(devvp->v_rdev) >= nblkdev) {
        !           130:                vrele(devvp);
        !           131:                return ENXIO;
        !           132:        }
        !           133: 
        !           134: /*
        !           135:  *  If this is an update, then make sure the vnode
        !           136:  *  for the block special device is the same as the
        !           137:  *  one our filesystem is in.
        !           138:  */
        !           139:        if (mp->mnt_flag & MNT_UPDATE) {
        !           140:                if (devvp != pmp->pm_devvp)
        !           141:                        error = EINVAL;
        !           142:                else
        !           143:                        vrele(devvp);
        !           144:        } else {
        !           145: 
        !           146: /*
        !           147:  *  Well, it's not an update, it's a real mount request.
        !           148:  *  Time to get dirty.
        !           149:  */
        !           150:                error = mountpcfs(devvp, mp, p);
        !           151:        }
        !           152:        if (error) {
        !           153:                vrele(devvp);
        !           154:                return error;
        !           155:        }
        !           156: 
        !           157: /*
        !           158:  *  Copy in the name of the directory the filesystem
        !           159:  *  is to be mounted on.
        !           160:  *  Then copy in the name of the block special file
        !           161:  *  representing the filesystem being mounted.
        !           162:  *  And we clear the remainder of the character strings
        !           163:  *  to be tidy.
        !           164:  *  Then, we try to fill in the filesystem stats structure
        !           165:  *  as best we can with whatever applies from a dos file
        !           166:  *  system.
        !           167:  */
        !           168:        pmp = (struct pcfsmount *)mp->mnt_data;
        !           169:        copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname,
        !           170:                sizeof(mp->mnt_stat.f_mntonname)-1, &size);
        !           171:        bzero(mp->mnt_stat.f_mntonname + size,
        !           172:                sizeof(mp->mnt_stat.f_mntonname) - size);
        !           173:        copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN-1, &size);
        !           174:        bzero(mp->mnt_stat.f_mntfromname + size,
        !           175:                MNAMELEN - size);
        !           176:        (void)pcfs_statfs(mp, &mp->mnt_stat, p);
        !           177: #if defined(PCFSDEBUG)
        !           178: printf("pcfs_mount(): mp %x, pmp %x, inusemap %x\n", mp, pmp, pmp->pm_inusemap);
        !           179: #endif /* defined(PCFSDEBUG) */
        !           180:        return 0;
        !           181: }
        !           182: 
        !           183: int
        !           184: mountpcfs(devvp, mp, p)
        !           185:        struct vnode *devvp;
        !           186:        struct mount *mp;
        !           187:        struct proc *p;
        !           188: {
        !           189:        int i;
        !           190:        u_long bpc;
        !           191:        int bit;
        !           192:        int error = 0;
        !           193:        int needclose;
        !           194:        int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
        !           195:        dev_t dev = devvp->v_rdev;
        !           196:        union bootsector *bsp;
        !           197:        struct pcfsmount *pmp = NULL;
        !           198:        struct buf *bp0 = NULL;
        !           199:        struct byte_bpb33 *b33;
        !           200:        struct byte_bpb50 *b50;
        !           201: 
        !           202: /*
        !           203:  *  Multiple mounts of the same block special file
        !           204:  *  aren't allowed.  Make sure no one else has the
        !           205:  *  special file open.  And flush any old buffers
        !           206:  *  from this filesystem.  Presumably this prevents
        !           207:  *  us from running into buffers that are the wrong
        !           208:  *  blocksize.
        !           209:  *  NOTE: mountedon() is a part of the ufs filesystem.
        !           210:  *  If the ufs filesystem is not gen'ed into the system
        !           211:  *  we will get an unresolved reference.
        !           212:  */
        !           213:        if (error = mountedon(devvp))
        !           214:                return error;
        !           215:        if (vcount(devvp) > 1)
        !           216:                return EBUSY;
        !           217:        vinvalbuf(devvp, 1);
        !           218: 
        !           219: /*
        !           220:  *  Now open the block special file.
        !           221:  */
        !           222:        if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
        !           223:                return error;
        !           224:        needclose = 1;
        !           225: 
        !           226: /*
        !           227:  *  Read the boot sector of the filesystem, and then
        !           228:  *  check the boot signature.  If not a dos boot sector
        !           229:  *  then error out.  We could also add some checking on
        !           230:  *  the bsOemName field.  So far I've seen the following
        !           231:  *  values:
        !           232:  *    "IBM  3.3"
        !           233:  *    "MSDOS3.3"
        !           234:  *    "MSDOS5.0"
        !           235:  */
        !           236:        if (error = bread(devvp, 0, 512, NOCRED, &bp0))
        !           237:                goto error_exit;
        !           238:        bp0->b_flags |= B_AGE;
        !           239:        bsp = (union bootsector *)bp0->b_un.b_addr;
        !           240:        b33 = (struct byte_bpb33 *)bsp->bs33.bsBPB;
        !           241:        b50 = (struct byte_bpb50 *)bsp->bs50.bsBPB;
        !           242:        if (bsp->bs50.bsBootSectSig != BOOTSIG) {
        !           243:                error = EINVAL;
        !           244:                goto error_exit;
        !           245:        }
        !           246: 
        !           247:        pmp = malloc(sizeof *pmp, M_MSDOSFSMNT, M_WAITOK);
        !           248:        pmp->pm_inusemap = NULL;
        !           249:        pmp->pm_mountp = mp;
        !           250: 
        !           251: /*
        !           252:  *  Compute several useful quantities from the bpb in
        !           253:  *  the bootsector.  Copy in the dos 5 variant of the
        !           254:  *  bpb then fix up the fields that are different between
        !           255:  *  dos 5 and dos 3.3.
        !           256:  */
        !           257:        pmp->pm_BytesPerSec  = getushort(b50->bpbBytesPerSec);
        !           258:        pmp->pm_SectPerClust = b50->bpbSecPerClust;
        !           259:        pmp->pm_ResSectors   = getushort(b50->bpbResSectors);
        !           260:        pmp->pm_FATs         = b50->bpbFATs;
        !           261:        pmp->pm_RootDirEnts  = getushort(b50->bpbRootDirEnts);
        !           262:        pmp->pm_Sectors      = getushort(b50->bpbSectors);
        !           263:        pmp->pm_Media        = b50->bpbMedia;
        !           264:        pmp->pm_FATsecs      = getushort(b50->bpbFATsecs);
        !           265:        pmp->pm_SecPerTrack  = getushort(b50->bpbSecPerTrack);
        !           266:        pmp->pm_Heads        = getushort(b50->bpbHeads);
        !           267:        if (pmp->pm_Sectors == 0) {
        !           268:                pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs);
        !           269:                pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors);
        !           270:        } else {
        !           271:                pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs);
        !           272:                pmp->pm_HugeSectors = pmp->pm_Sectors;
        !           273:        }
        !           274:        pmp->pm_fatblk = pmp->pm_ResSectors;
        !           275:        pmp->pm_rootdirblk = pmp->pm_fatblk +
        !           276:                (pmp->pm_FATs * pmp->pm_FATsecs);
        !           277:        pmp->pm_rootdirsize = (pmp->pm_RootDirEnts * sizeof(struct direntry))
        !           278:                                        /
        !           279:                                pmp->pm_BytesPerSec; /* in sectors */
        !           280:        pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize;
        !           281:        pmp->pm_nmbrofclusters = (pmp->pm_HugeSectors - pmp->pm_firstcluster) /
        !           282:                pmp->pm_SectPerClust;
        !           283:        pmp->pm_maxcluster = pmp->pm_nmbrofclusters + 1;
        !           284:        pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec;
        !           285:        if (FAT12(pmp))
        !           286:                /* This will usually be a floppy disk.
        !           287:                 * This size makes sure that one fat entry will not be split
        !           288:                 * across multiple blocks. */
        !           289:                pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
        !           290:        else
        !           291:                /* This will usually be a hard disk.
        !           292:                 * Reading or writing one block should be quite fast. */
        !           293:                pmp->pm_fatblocksize = MAXBSIZE;
        !           294:        pmp->pm_fatblocksec = pmp->pm_fatblocksize / pmp->pm_BytesPerSec;
        !           295:                
        !           296:        if ((pmp->pm_rootdirsize % pmp->pm_SectPerClust) != 0)
        !           297:                printf("mountpcfs(): root directory is not a multiple of the clustersize in length\n");
        !           298: 
        !           299: /*
        !           300:  *  Compute mask and shift value for isolating cluster relative
        !           301:  *  byte offsets and cluster numbers from a file offset.
        !           302:  */
        !           303:        bpc = pmp->pm_SectPerClust * pmp->pm_BytesPerSec;
        !           304:        if (!bpc || (bpc & (bpc - 1))) {
        !           305:                error = EINVAL;
        !           306:                goto error_exit;
        !           307:        }
        !           308:        pmp->pm_bpcluster = bpc;
        !           309:        pmp->pm_depclust  = bpc/sizeof(struct direntry);
        !           310:        pmp->pm_crbomask = bpc - 1;
        !           311:        pmp->pm_cnshift = ffs(bpc) - 1;
        !           312: 
        !           313:        pmp->pm_brbomask = 0x01ff;      /* 512 byte blocks only (so far) */
        !           314:        pmp->pm_bnshift = 9;            /* shift right 9 bits to get bn */
        !           315: 
        !           316: /*
        !           317:  *  Release the bootsector buffer.
        !           318:  */
        !           319:        brelse(bp0);
        !           320:        bp0 = NULL;
        !           321: 
        !           322: /*
        !           323:  *  Allocate memory for the bitmap of allocated clusters,
        !           324:  *  and then fill it in.
        !           325:  */
        !           326:        pmp->pm_inusemap = malloc((pmp->pm_maxcluster / 8) + 1,
        !           327:                M_MSDOSFSFAT, M_WAITOK);
        !           328: 
        !           329: /*
        !           330:  *  fillinusemap() needs pm_devvp.
        !           331:  */
        !           332:        pmp->pm_dev = dev;
        !           333:        pmp->pm_devvp = devvp;
        !           334: 
        !           335: /*
        !           336:  *  Have the inuse map filled in.
        !           337:  */
        !           338:        error = fillinusemap(pmp);
        !           339:        if (error)
        !           340:                goto error_exit;
        !           341: 
        !           342: /*
        !           343:  *  If they want fat updates to be synchronous then let
        !           344:  *  them suffer the performance degradation in exchange
        !           345:  *  for the on disk copy of the fat being correct just
        !           346:  *  about all the time.  I suppose this would be a good
        !           347:  *  thing to turn on if the kernel is still flakey.
        !           348:  */
        !           349:        pmp->pm_waitonfat = mp->mnt_flag & MNT_SYNCHRONOUS;
        !           350: 
        !           351: /*
        !           352:  *  Finish up.
        !           353:  */
        !           354:        pmp->pm_ronly = ronly;
        !           355:        if (ronly == 0)
        !           356:                pmp->pm_fmod = 1;
        !           357:        mp->mnt_data = (qaddr_t)pmp;
        !           358:        mp->mnt_stat.f_fsid.val[0] = (long)dev;
        !           359:        mp->mnt_stat.f_fsid.val[1] = MOUNT_MSDOS;
        !           360:        mp->mnt_flag |= MNT_LOCAL;
        !           361: #if defined(QUOTA)
        !           362: /*
        !           363:  *  If we ever do quotas for DOS filesystems this would
        !           364:  *  be a place to fill in the info in the pcfsmount
        !           365:  *  structure.
        !           366:  *  You dolt, quotas on dos filesystems make no sense
        !           367:  *  because files have no owners on dos filesystems.
        !           368:  *  of course there is some empty space in the directory
        !           369:  *  entry where we could put uid's and gid's.
        !           370:  */
        !           371: #endif /* defined(QUOTA) */
        !           372:        devvp->v_specflags |= SI_MOUNTEDON;
        !           373: 
        !           374:        return 0;
        !           375: 
        !           376: error_exit:;
        !           377:        if (bp0)
        !           378:                brelse(bp0);
        !           379:        if (needclose)
        !           380:                (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE,
        !           381:                        NOCRED, p);
        !           382:        if (pmp) {
        !           383:                if (pmp->pm_inusemap)
        !           384:                        free((caddr_t)pmp->pm_inusemap, M_MSDOSFSFAT);
        !           385:                free((caddr_t)pmp, M_MSDOSFSMNT);
        !           386:                mp->mnt_data = (qaddr_t)0;
        !           387:        }
        !           388:        return error;
        !           389: }
        !           390: 
        !           391: int
        !           392: pcfs_start(mp, flags, p)
        !           393:        struct mount *mp;
        !           394:        int flags;
        !           395:        struct proc *p;
        !           396: {
        !           397:        return 0;
        !           398: }
        !           399: 
        !           400: /*
        !           401:  *  Unmount the filesystem described by mp.
        !           402:  */
        !           403: int
        !           404: pcfs_unmount(mp, mntflags, p)
        !           405:        struct mount *mp;
        !           406:        int mntflags;
        !           407:        struct proc *p;
        !           408: {
        !           409:        int flags = 0;
        !           410:        int error;
        !           411:        struct pcfsmount *pmp = (struct pcfsmount *)mp->mnt_data;
        !           412:        struct vnode *vp = pmp->pm_devvp;
        !           413: 
        !           414:        if (mntflags & MNT_FORCE) {
        !           415:                if (!pcfsdoforce)
        !           416:                        return EINVAL;
        !           417:                flags |= FORCECLOSE;
        !           418:        }
        !           419:        mntflushbuf(mp, 0);
        !           420:        if (mntinvalbuf(mp))
        !           421:                return EBUSY;
        !           422: #if defined(QUOTA)
        !           423: #endif /* defined(QUOTA) */
        !           424:        if (error = vflush(mp, NULLVP, flags))
        !           425:                return error;
        !           426:        pmp->pm_devvp->v_specflags &= ~SI_MOUNTEDON;
        !           427: #if defined(PCFSDEBUG)
        !           428: printf("pcfs_umount(): just before calling VOP_CLOSE()\n");
        !           429: printf("flag %08x, usecount %d, writecount %d, holdcnt %d\n",
        !           430:        vp->v_flag, vp->v_usecount, vp->v_writecount, vp->v_holdcnt);
        !           431: printf("lastr %d, id %d, mount %08x, op %08x\n",
        !           432:        vp->v_lastr, vp->v_id, vp->v_mount, vp->v_op);
        !           433: printf("freef %08x, freeb %08x, mountf %08x, mountb %08x\n",
        !           434:        vp->v_freef, vp->v_freeb, vp->v_mountf, vp->v_mountb);
        !           435: printf("cleanblkhd %08x, dirtyblkhd %08x, numoutput %d, type %d\n",
        !           436:        vp->v_cleanblkhd, vp->v_dirtyblkhd, vp->v_numoutput, vp->v_type);
        !           437: printf("union %08x, tag %d, data[0] %08x, data[1] %08x\n",
        !           438:        vp->v_socket, vp->v_tag, vp->v_data[0], vp->v_data[1]);
        !           439: #endif /* defined(PCFSDEBUG) */
        !           440:        error = VOP_CLOSE(pmp->pm_devvp, pmp->pm_ronly ? FREAD : FREAD|FWRITE,
        !           441:                NOCRED, p);
        !           442:        vrele(pmp->pm_devvp);
        !           443:        free((caddr_t)pmp->pm_inusemap, M_MSDOSFSFAT);
        !           444:        free((caddr_t)pmp, M_MSDOSFSMNT);
        !           445:        mp->mnt_data = (qaddr_t)0;
        !           446:        mp->mnt_flag &= ~MNT_LOCAL;
        !           447:        return error;
        !           448: }
        !           449: 
        !           450: int
        !           451: pcfs_root(mp, vpp)
        !           452:        struct mount *mp;
        !           453:        struct vnode **vpp;
        !           454: {
        !           455:        struct denode *ndep;
        !           456:        struct pcfsmount *pmp = (struct pcfsmount *)(mp->mnt_data);
        !           457:        int error;
        !           458: 
        !           459:        error = deget(pmp, PCFSROOT, PCFSROOT_OFS, NULL, &ndep);
        !           460: #if defined(PCFSDEBUG)
        !           461: printf("pcfs_root(); mp %08x, pmp %08x, ndep %08x, vp %08x\n",
        !           462:  mp, pmp, ndep, DETOV(ndep));
        !           463: #endif /* defined(PCFSDEBUG) */
        !           464:        if (error == 0)
        !           465:                *vpp = DETOV(ndep);
        !           466:        return error;
        !           467: }
        !           468: 
        !           469: int
        !           470: pcfs_quotactl(mp, cmds, uid, arg, p)
        !           471:        struct mount *mp;
        !           472:        int cmds;
        !           473:        uid_t uid;
        !           474:        caddr_t arg;
        !           475:        struct proc *p;
        !           476: {
        !           477: #if defined(QUOTA)
        !           478: #else
        !           479:        return EOPNOTSUPP;
        !           480: #endif /* defined(QUOTA) */
        !           481: }
        !           482: 
        !           483: int
        !           484: pcfs_statfs(mp, sbp, p)
        !           485:        struct mount *mp;
        !           486:        struct statfs *sbp;
        !           487:        struct proc *p;
        !           488: {
        !           489:        struct pcfsmount *pmp = (struct pcfsmount *)mp->mnt_data;
        !           490: 
        !           491: /*
        !           492:  *  Fill in the stat block.
        !           493:  */
        !           494:        sbp->f_type   = MOUNT_MSDOS;
        !           495:        sbp->f_fsize  = pmp->pm_bpcluster;
        !           496:        sbp->f_bsize  = pmp->pm_bpcluster;
        !           497:        sbp->f_blocks = pmp->pm_nmbrofclusters;
        !           498:        sbp->f_bfree  = pmp->pm_freeclustercount;
        !           499:        sbp->f_bavail = pmp->pm_freeclustercount;
        !           500:        sbp->f_files  = pmp->pm_RootDirEnts;
        !           501:        sbp->f_ffree  = 0;              /* what to put in here? */
        !           502: 
        !           503: /*
        !           504:  *  Copy the mounted on and mounted from names into
        !           505:  *  the passed in stat block, if it is not the one
        !           506:  *  in the mount structure.
        !           507:  */
        !           508:        if (sbp != &mp->mnt_stat) {
        !           509:                bcopy((caddr_t)mp->mnt_stat.f_mntonname,
        !           510:                        (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
        !           511:                bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
        !           512:                        (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
        !           513:        }
        !           514:        return 0;
        !           515: }
        !           516: 
        !           517: int
        !           518: pcfs_sync(mp, waitfor)
        !           519:        struct mount *mp;
        !           520:        int waitfor;
        !           521: {
        !           522:        struct vnode *vp;
        !           523:        struct denode *dep;
        !           524:        struct pcfsmount *pmp;
        !           525:        int error;
        !           526:        int allerror = 0;
        !           527: 
        !           528:        pmp = (struct pcfsmount *)mp->mnt_data;
        !           529: 
        !           530: /*
        !           531:  *  If we ever switch to not updating all of the fats
        !           532:  *  all the time, this would be the place to update them
        !           533:  *  from the first one.
        !           534:  */
        !           535:        if (pmp->pm_fmod) {
        !           536:                if (pmp->pm_ronly) {
        !           537:                        printf("pcfs_sync(): writing to readonly filesystem\n");
        !           538:                        return EINVAL;
        !           539:                } else {
        !           540:                        /* update fats here */
        !           541:                }
        !           542:        }
        !           543: 
        !           544: /*
        !           545:  *  Go thru in memory denodes and write them out along
        !           546:  *  with unwritten file blocks.
        !           547:  */
        !           548: loop:
        !           549:        for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) {
        !           550:                if (vp->v_mount != mp)  /* not ours anymore     */
        !           551:                        goto loop;
        !           552:                if (VOP_ISLOCKED(vp))   /* file is busy         */
        !           553:                        continue;
        !           554:                dep = VTODE(vp);
        !           555:                if ((dep->de_flag & DEUPD) == 0  &&  vp->v_dirtyblkhd == NULL)
        !           556:                        continue;
        !           557:                if (vget(vp))           /* not there anymore?   */
        !           558:                        goto loop;
        !           559:                if (vp->v_dirtyblkhd)   /* flush dirty file blocks */
        !           560:                        vflushbuf(vp, 0);
        !           561:                if ((dep->de_flag & DEUPD)  &&
        !           562:                    (error = deupdat(dep, &time, 0)))
        !           563:                        allerror = error;
        !           564:                vput(vp);               /* done with this one   */
        !           565:        }
        !           566: 
        !           567: /*
        !           568:  *  Flush filesystem control info.
        !           569:  */
        !           570:        vflushbuf(pmp->pm_devvp, waitfor == MNT_WAIT ? B_SYNC : 0);
        !           571:        return allerror;
        !           572: }
        !           573: 
        !           574: int
        !           575: pcfs_fhtovp (mp, fhp, vpp)
        !           576:        struct mount *mp;
        !           577:        struct fid *fhp;
        !           578:        struct vnode **vpp;
        !           579: {
        !           580:        struct pcfsmount *pmp = (struct pcfsmount *)mp->mnt_data;
        !           581:        struct defid *defhp = (struct defid *)fhp;
        !           582:        struct denode *dep;
        !           583:        int error;
        !           584: 
        !           585:        error = deget (pmp, defhp->defid_dirclust, defhp->defid_dirofs,
        !           586:                        NULL, &dep);
        !           587:        if (error)
        !           588:                return (error);
        !           589:        *vpp = DETOV (dep);
        !           590:        return (0);
        !           591: }
        !           592: 
        !           593: 
        !           594: int
        !           595: pcfs_vptofh (vp, fhp)
        !           596:        struct vnode *vp;
        !           597:        struct fid *fhp;
        !           598: {
        !           599:        struct denode *dep = VTODE(vp);
        !           600:        struct defid *defhp = (struct defid *)fhp;
        !           601: 
        !           602:        defhp->defid_len = sizeof(struct defid);
        !           603:        defhp->defid_dirclust = dep->de_dirclust;
        !           604:        defhp->defid_dirofs = dep->de_diroffset;
        !           605: /*     defhp->defid_gen = ip->i_gen; */
        !           606:        return (0);
        !           607: }
        !           608: 
        !           609: struct vfsops pcfs_vfsops = {
        !           610:        pcfs_mount,
        !           611:        pcfs_start,
        !           612:        pcfs_unmount,
        !           613:        pcfs_root,
        !           614:        pcfs_quotactl,
        !           615:        pcfs_statfs,
        !           616:        pcfs_sync,
        !           617:        pcfs_fhtovp,
        !           618:        pcfs_vptofh,
        !           619:        pcfs_init
        !           620: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.