Annotation of Net2/pcfs/pcfs_denode.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:  *     pcfs_denode.c,v 1.4.2.1 1993/08/05 02:37:20 cgd Exp
        !            19:  */
        !            20: 
        !            21: #include "param.h"
        !            22: #include "systm.h"
        !            23: #include "mount.h"
        !            24: #include "proc.h"
        !            25: #include "buf.h"
        !            26: #include "vnode.h"
        !            27: #include "kernel.h"    /* defines "time"                       */
        !            28: 
        !            29: #include "bpb.h"
        !            30: #include "pcfsmount.h"
        !            31: #include "direntry.h"
        !            32: #include "denode.h"
        !            33: #include "fat.h"
        !            34: 
        !            35: #define        DEHSZ   512
        !            36: #if ((DEHSZ & (DEHSZ-1)) == 0)
        !            37: #define        DEHASH(dev, deno)       (((dev)+(deno)+((deno)>>16))&(DEHSZ-1))
        !            38: #else
        !            39: #define        DEHASH(dev, deno)       (((dev)+(deno)+((deno)>>16))%DEHSZ)
        !            40: #endif /* ((DEHSZ & (DEHSZ-1)) == 0) */
        !            41: 
        !            42: union dehead {
        !            43:        union dehead *deh_head[2];
        !            44:        struct denode *deh_chain[2];
        !            45: } dehead[DEHSZ];
        !            46: 
        !            47: pcfs_init()
        !            48: {
        !            49:        int i;
        !            50:        union dehead *deh;
        !            51: 
        !            52:        if (VN_MAXPRIVATE < sizeof(struct denode))
        !            53:                panic("pcfs_init: vnode too small");
        !            54: 
        !            55:        for (i = DEHSZ, deh = dehead; --i >= 0; deh++) {
        !            56:                deh->deh_head[0] = deh;
        !            57:                deh->deh_head[1] = deh;
        !            58:        }
        !            59: }
        !            60: 
        !            61: /*
        !            62:  *  If deget() succeeds it returns with the gotten denode
        !            63:  *  locked().
        !            64:  *  pmp - address of pcfsmount structure of the filesystem
        !            65:  *    containing the denode of interest.  The pm_dev field
        !            66:  *    and the address of the pcfsmount structure are used. 
        !            67:  *  dirclust - which cluster bp contains, if dirclust is 0
        !            68:  *    (root directory) diroffset is relative to the beginning
        !            69:  *    of the root directory, otherwise it is cluster relative.
        !            70:  *  diroffset - offset past begin of cluster of denode we
        !            71:  *    want
        !            72:  *  direntptr - address of the direntry structure of interest.
        !            73:  *    direntptr is NULL, the block is read if necessary.
        !            74:  *  depp - returns the address of the gotten denode.
        !            75:  */
        !            76: int
        !            77: deget (pmp, dirclust, diroffset, direntptr, depp)
        !            78:        struct pcfsmount *pmp;  /* so we know the maj/min number        */
        !            79:        u_long dirclust;        /* cluster this dir entry came from     */
        !            80:        u_long diroffset;       /* index of entry within the cluster    */
        !            81:        struct direntry *direntptr;
        !            82:        struct denode **depp;   /* returns the addr of the gotten denode*/
        !            83: {
        !            84:        int error;
        !            85:        dev_t dev = pmp->pm_dev;
        !            86:        union dehead *deh;
        !            87:        struct mount *mntp = pmp->pm_mountp;
        !            88:        extern struct vnodeops pcfs_vnodeops;
        !            89:        struct denode *ldep;
        !            90:        struct vnode *nvp;
        !            91:        struct buf *bp;
        !            92: #if defined(PCFSDEBUG)
        !            93: printf("deget(pmp %08x, dirclust %d, diroffset %x, direntptr %x, depp %08x)\n",
        !            94:        pmp, dirclust, diroffset, direntptr, depp);
        !            95: #endif /* defined(PCFSDEBUG) */
        !            96: 
        !            97:        /* If dir entry is given and refers to a directory, convert to 
        !            98:         * canonical form
        !            99:         */
        !           100:        if (direntptr && (direntptr->deAttributes & ATTR_DIRECTORY)) {
        !           101:                dirclust = direntptr->deStartCluster;
        !           102:                if (dirclust == PCFSROOT)
        !           103:                        diroffset = PCFSROOT_OFS;
        !           104:                else
        !           105:                        diroffset = 0;
        !           106:        }
        !           107: 
        !           108: /*
        !           109:  *  See if the denode is in the denode cache. Use the location of
        !           110:  *  the directory entry to compute the hash value.
        !           111:  *  For subdir use address of "." entry.
        !           112:  *  for root dir use cluster PCFSROOT, offset PCFSROOT_OFS
        !           113:  *  
        !           114:  *  NOTE: The check for de_refcnt > 0 below insures the denode
        !           115:  *  being examined does not represent an unlinked but
        !           116:  *  still open file.  These files are not to be accessible
        !           117:  *  even when the directory entry that represented the
        !           118:  *  file happens to be reused while the deleted file is still
        !           119:  *  open.
        !           120:  */
        !           121:        deh = &dehead[DEHASH(dev, dirclust + diroffset)];
        !           122: loop:
        !           123:        for (ldep = deh->deh_chain[0]; ldep != (struct denode *)deh;
        !           124:                ldep = ldep->de_forw) {
        !           125:                if (dev != ldep->de_dev || ldep->de_refcnt == 0)
        !           126:                        continue;
        !           127:                if (dirclust  != ldep->de_dirclust
        !           128:                    || diroffset != ldep->de_diroffset)
        !           129:                        continue;
        !           130:                if (ldep->de_flag & DELOCKED) {
        !           131:                        /* should we brelse() the passed buf hdr to
        !           132:                         *  avoid some potential deadlock? */
        !           133:                        ldep->de_flag |= DEWANT;
        !           134:                        sleep((caddr_t)ldep, PINOD);
        !           135:                        goto loop;
        !           136:                }
        !           137:                if (vget(DETOV(ldep)))
        !           138:                        goto loop;
        !           139:                *depp = ldep;
        !           140:                return 0;
        !           141:        }
        !           142: 
        !           143: 
        !           144: /*
        !           145:  *  Directory entry was not in cache, have to create
        !           146:  *  a vnode and copy it from the passed disk buffer.
        !           147:  */
        !           148:        /* getnewvnode() does a VREF() on the vnode */
        !           149:        if (error = getnewvnode(VT_MSDOSFS, mntp, &pcfs_vnodeops, &nvp)) {
        !           150:                *depp = 0;
        !           151:                return error;
        !           152:        }
        !           153:        ldep = VTODE(nvp);
        !           154:        ldep->de_vnode = nvp;
        !           155:        ldep->de_flag = 0;
        !           156:        ldep->de_devvp = 0;
        !           157:        ldep->de_lockf = 0;
        !           158:        ldep->de_dev   = dev;
        !           159:        fc_purge(ldep, 0);      /* init the fat cache for this denode */
        !           160: 
        !           161: /*
        !           162:  *  Insert the denode into the hash queue and lock the
        !           163:  *  denode so it can't be accessed until we've read it
        !           164:  *  in and have done what we need to it.
        !           165:  */
        !           166:        insque(ldep, deh);
        !           167:        DELOCK(ldep);
        !           168: 
        !           169:        /*
        !           170:         *  Copy the directory entry into the denode area of the
        !           171:         *  vnode.
        !           172:         */
        !           173:        if (dirclust == PCFSROOT && diroffset == PCFSROOT_OFS) {
        !           174:                /*  Directory entry for the root directory.
        !           175:                 *  There isn't one, so we manufacture one.
        !           176:                 *  We should probably rummage through the root directory and
        !           177:                 *  find a label entry (if it exists), and then use the time
        !           178:                 *  and date from that entry as the time and date for the
        !           179:                 *  root denode.
        !           180:                 */
        !           181:                ldep->de_Attributes = ATTR_DIRECTORY;
        !           182:                ldep->de_StartCluster = PCFSROOT;
        !           183:                ldep->de_FileSize = pmp->pm_rootdirsize * pmp->pm_BytesPerSec;
        !           184:                /* fill in time and date so that dos2unixtime() doesn't
        !           185:                 * spit up when called from pcfs_getattr() with root denode */
        !           186:                ldep->de_Time = 0x0000;         /* 00:00:00     */
        !           187:                ldep->de_Date = (0 << 9) | (1 << 5) | (1 << 0);
        !           188:                                                /* Jan 1, 1980  */
        !           189:                /* leave the other fields as garbage */
        !           190:        }
        !           191:        else {
        !           192:                bp = NULL;
        !           193:                if (!direntptr) {
        !           194:                        error = readep(pmp, dirclust, diroffset, &bp,
        !           195:                                       &direntptr);
        !           196:                        if (error)
        !           197:                                return error;
        !           198:                }
        !           199:                ldep->de_de = *direntptr;
        !           200:                if (bp)
        !           201:                        brelse (bp);
        !           202:        }
        !           203: 
        !           204: /*
        !           205:  *  Fill in a few fields of the vnode and finish filling
        !           206:  *  in the denode.  Then return the address of the found
        !           207:  *  denode.
        !           208:  */
        !           209:        ldep->de_pmp = pmp;
        !           210:        ldep->de_devvp = pmp->pm_devvp;
        !           211:        ldep->de_refcnt = 1;
        !           212:        ldep->de_dirclust = dirclust;
        !           213:        ldep->de_diroffset = diroffset;
        !           214:        if (ldep->de_Attributes & ATTR_DIRECTORY) {
        !           215:                /*
        !           216:                 *  Since DOS directory entries that describe directories
        !           217:                 *  have 0 in the filesize field, we take this opportunity
        !           218:                 *  to find out the length of the directory and plug it
        !           219:                 *  into the denode structure.
        !           220:                 */
        !           221:                u_long size;
        !           222: 
        !           223:                nvp->v_type = VDIR;
        !           224:                if (ldep->de_StartCluster == PCFSROOT)
        !           225:                        nvp->v_flag |= VROOT;
        !           226:                else {
        !           227:                        error = pcbmap(ldep, 0xffff, 0, &size);
        !           228:                        if (error == E2BIG) {
        !           229:                                ldep->de_FileSize = size << pmp->pm_cnshift;
        !           230:                                error = 0;
        !           231:                        }
        !           232:                        else
        !           233:                                printf("deget(): pcbmap returned %d\n", error);
        !           234:                }
        !           235:        }
        !           236:        else
        !           237:                nvp->v_type = VREG;
        !           238:        VREF(ldep->de_devvp);
        !           239:        *depp = ldep;
        !           240:        return 0;
        !           241: }
        !           242: 
        !           243: void
        !           244: deput(dep)
        !           245:        struct denode *dep;
        !           246: {
        !           247:        if ((dep->de_flag & DELOCKED) == 0)
        !           248:                panic("deput: denode not locked");
        !           249:        DEUNLOCK(dep);
        !           250:        vrele(DETOV(dep));
        !           251: }
        !           252: 
        !           253: int
        !           254: deupdat(dep, tp, waitfor)
        !           255:        struct denode *dep;
        !           256:        struct timeval *tp;
        !           257:        int waitfor;
        !           258: {
        !           259:        int error;
        !           260:        daddr_t bn;
        !           261:        int diro;
        !           262:        struct buf *bp;
        !           263:        struct direntry *dirp;
        !           264:        struct pcfsmount *pmp = dep->de_pmp;
        !           265:        struct vnode *vp = DETOV(dep);
        !           266: #if defined(PCFSDEBUG)
        !           267: printf("deupdat(): dep %08x\n", dep);
        !           268: #endif /* defined(PCFSDEBUG) */
        !           269: 
        !           270: /*
        !           271:  *  If the update bit is off, or this denode is from
        !           272:  *  a readonly filesystem, or this denode is for a
        !           273:  *  directory, or the denode represents an open but
        !           274:  *  unlinked file then don't do anything.  DOS directory
        !           275:  *  entries that describe a directory do not ever
        !           276:  *  get updated.  This is the way dos treats them.
        !           277:  */
        !           278:        if ((dep->de_flag & DEUPD) == 0  ||
        !           279:            vp->v_mount->mnt_flag & MNT_RDONLY  ||
        !           280:            dep->de_Attributes & ATTR_DIRECTORY  ||
        !           281:            dep->de_refcnt <= 0)
        !           282:                return 0;
        !           283: 
        !           284: /*
        !           285:  *  Read in the cluster containing the directory entry
        !           286:  *  we want to update.
        !           287:  */
        !           288:        if (error = readde(dep, &bp, &dirp))
        !           289:                return error;
        !           290: 
        !           291: /*
        !           292:  *  Put the passed in time into the directory entry.
        !           293:  */
        !           294:        unix2dostime(&time, (union dosdate *)&dep->de_Date,
        !           295:                (union dostime *)&dep->de_Time);
        !           296:        dep->de_flag &= ~DEUPD;
        !           297: 
        !           298: /*
        !           299:  *  Copy the directory entry out of the denode into
        !           300:  *  the cluster it came from.
        !           301:  */
        !           302:        *dirp = dep->de_de;     /* structure copy */
        !           303: 
        !           304: /*
        !           305:  *  Write the cluster back to disk.  If they asked
        !           306:  *  for us to wait for the write to complete, then
        !           307:  *  use bwrite() otherwise use bdwrite().
        !           308:  */
        !           309:        error = 0;      /* note that error is 0 from above, but ... */
        !           310:        if (waitfor)
        !           311:                error = bwrite(bp);
        !           312:        else
        !           313:                bdwrite(bp);
        !           314:        return error;
        !           315: }
        !           316: 
        !           317: /*
        !           318:  *  Truncate the file described by dep to the length
        !           319:  *  specified by length.
        !           320:  */
        !           321: int
        !           322: detrunc(dep, length, flags)
        !           323:        struct denode *dep;
        !           324:        u_long length;
        !           325:        int flags;
        !           326: {
        !           327:        int error;
        !           328:        int allerror;
        !           329:        u_long eofentry;
        !           330:        u_long chaintofree;
        !           331:        daddr_t bn;
        !           332:        int boff;
        !           333:        int isadir = dep->de_Attributes & ATTR_DIRECTORY;
        !           334:        struct buf *bp;
        !           335:        struct pcfsmount *pmp = dep->de_pmp;
        !           336: #if defined(PCFSDEBUG)
        !           337: printf("detrunc(): file %s, length %d, flags %d\n", dep->de_Name, length, flags);
        !           338: #endif /* defined(PCFSDEBUG) */
        !           339: 
        !           340: /*
        !           341:  *  Disallow attempts to truncate the root directory
        !           342:  *  since it is of fixed size.  That's just the way
        !           343:  *  dos filesystems are.  We use the VROOT bit in the
        !           344:  *  vnode because checking for the directory bit and
        !           345:  *  a startcluster of 0 in the denode is not adequate
        !           346:  *  to recognize the root directory at this point in
        !           347:  *  a file or directory's life.
        !           348:  */
        !           349:        if (DETOV(dep)->v_flag & VROOT) {
        !           350:                printf("detrunc(): can't truncate root directory, clust %d, offset %d\n",
        !           351:                        dep->de_dirclust, dep->de_diroffset);
        !           352:                return EINVAL;
        !           353:        }
        !           354: 
        !           355:        vnode_pager_setsize(DETOV(dep), length);
        !           356: 
        !           357:        if (dep->de_FileSize <= length) {
        !           358:                dep->de_flag |= DEUPD;
        !           359:                error = deupdat(dep, &time, 1);
        !           360: #if defined(PCFSDEBUG)
        !           361: printf("detrunc(): file is shorter return point, errno %d\n", error);
        !           362: #endif /* defined(PCFSDEBUG) */
        !           363:                return error;
        !           364:        }
        !           365: 
        !           366: /*
        !           367:  *  If the desired length is 0 then remember the starting
        !           368:  *  cluster of the file and set the StartCluster field in
        !           369:  *  the directory entry to 0.  If the desired length is
        !           370:  *  not zero, then get the number of the last cluster in
        !           371:  *  the shortened file.  Then get the number of the first
        !           372:  *  cluster in the part of the file that is to be freed.
        !           373:  *  Then set the next cluster pointer in the last cluster
        !           374:  *  of the file to CLUST_EOFE.
        !           375:  */
        !           376:        if (length == 0) {
        !           377:                chaintofree = dep->de_StartCluster;
        !           378:                dep->de_StartCluster = 0;
        !           379:                eofentry = ~0;
        !           380:        } else {
        !           381:                error = pcbmap(dep, (length-1) >> pmp->pm_cnshift,
        !           382:                                0, &eofentry);
        !           383:                if (error) {
        !           384: #if defined(PCFSDEBUG)
        !           385: printf("detrunc(): pcbmap fails %d\n", error);
        !           386: #endif /* defined(PCFSDEBUG) */
        !           387:                        return error;
        !           388:                }
        !           389:        }
        !           390: 
        !           391:        fc_purge(dep, (length + pmp->pm_crbomask) >> pmp->pm_cnshift);
        !           392: 
        !           393: /*
        !           394:  *  If the new length is not a multiple of the cluster size
        !           395:  *  then we must zero the tail end of the new last cluster in case
        !           396:  *  it becomes part of the file again because of a seek.
        !           397:  */
        !           398:        if ((boff = length & pmp->pm_crbomask) != 0) {
        !           399:                /* should read from file vnode or
        !           400:                 * filesystem vnode depending on if file or dir */
        !           401:                if (isadir) {
        !           402:                        bn = cntobn(pmp, eofentry);
        !           403:                        error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
        !           404:                                NOCRED, &bp);
        !           405:                } else {
        !           406:                        bn = (length-1) >> pmp->pm_cnshift;
        !           407:                        error = bread(DETOV(dep), bn, pmp->pm_bpcluster,
        !           408:                                NOCRED, &bp);
        !           409:                }
        !           410:                if (error) {
        !           411:                        brelse(bp);
        !           412:                        return error;
        !           413:                }
        !           414:                vnode_pager_uncache(DETOV(dep));        /* what's this for? */
        !           415:                                                        /* is this the right
        !           416:                                                         *  place for it? */
        !           417:                bzero(bp->b_un.b_addr + boff, pmp->pm_bpcluster - boff);
        !           418:                if (flags & IO_SYNC)
        !           419:                        bwrite(bp);
        !           420:                else
        !           421:                        bdwrite(bp);
        !           422:        }
        !           423: 
        !           424: /*
        !           425:  *  Write out the updated directory entry.  Even
        !           426:  *  if the update fails we free the trailing clusters.
        !           427:  */
        !           428:        dep->de_FileSize = length;
        !           429:        dep->de_flag |= DEUPD;
        !           430:        vinvalbuf(DETOV(dep), length > 0);
        !           431:        allerror = deupdat(dep, &time, MNT_WAIT);
        !           432: #if defined(PCFSDEBUG)
        !           433: printf("detrunc(): allerror %d, eofentry %d\n",
        !           434:        allerror, eofentry);
        !           435: #endif /* defined(PCFSDEBUG) */
        !           436: 
        !           437: /*
        !           438:  *  If we need to break the cluster chain for the file
        !           439:  *  then do it now.
        !           440:  */
        !           441:        if (eofentry != ~0) {
        !           442:                error = fatentry(FAT_GET_AND_SET, pmp, eofentry,
        !           443:                        &chaintofree, CLUST_EOFE);
        !           444:                if (error) {
        !           445: #if defined(PCFSDEBUG)
        !           446: printf("detrunc(): fatentry errors %d\n", error);
        !           447: #endif /* defined(PCFSDEBUG) */
        !           448:                        return error;
        !           449:                }
        !           450:                fc_setcache(dep, FC_LASTFC, (length - 1) >> pmp->pm_cnshift,
        !           451:                        eofentry);
        !           452:        }
        !           453: 
        !           454: /*
        !           455:  *  Now free the clusters removed from the file because
        !           456:  *  of the truncation.
        !           457:  */
        !           458:        if (chaintofree != 0  &&  !PCFSEOF(chaintofree))
        !           459:                freeclusterchain(pmp, chaintofree);
        !           460: 
        !           461:        return allerror;
        !           462: }
        !           463: 
        !           464: /*
        !           465:  *  Move a denode to its correct hash queue after
        !           466:  *  the file it represents has been moved to a new
        !           467:  *  directory.
        !           468:  */
        !           469: reinsert(dep)
        !           470:        struct denode *dep;
        !           471: {
        !           472:        struct pcfsmount *pmp = dep->de_pmp;
        !           473:        union dehead *deh;
        !           474: 
        !           475: /*
        !           476:  *  Fix up the denode cache.  If the denode is
        !           477:  *  for a directory, there is nothing to do since the
        !           478:  *  hash is based on the starting cluster of the directory
        !           479:  *  file and that hasn't changed.  If for a file the hash
        !           480:  *  is based on the location
        !           481:  *  of the directory entry, so we must remove it from the
        !           482:  *  cache and re-enter it with the hash based on the new
        !           483:  *  location of the directory entry.
        !           484:  */
        !           485:        if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) {
        !           486:                remque(dep);
        !           487:                deh = &dehead[DEHASH(pmp->pm_dev,
        !           488:                        dep->de_dirclust + dep->de_diroffset)];
        !           489:                insque(dep, deh);
        !           490:        }
        !           491: }
        !           492: 
        !           493: int pcfs_prtactive;    /* print reclaims of active vnodes */
        !           494: 
        !           495: int
        !           496: pcfs_reclaim(vp)
        !           497:        struct vnode *vp;
        !           498: {
        !           499:        struct denode *dep = VTODE(vp);
        !           500:        int i;
        !           501: #if defined(PCFSDEBUG)
        !           502: printf("pcfs_reclaim(): dep %08x, file %s, refcnt %d\n",
        !           503:        dep, dep->de_Name, dep->de_refcnt);
        !           504: #endif /* defined(PCFSDEBUG) */
        !           505: 
        !           506:        if (pcfs_prtactive && vp->v_usecount != 0)
        !           507:                vprint("pcfs_reclaim(): pushing active", vp);
        !           508: 
        !           509: /*
        !           510:  *  Remove the denode from the denode hash chain we
        !           511:  *  are in.
        !           512:  */
        !           513:        remque(dep);
        !           514:        dep->de_forw = dep;
        !           515:        dep->de_back = dep;
        !           516: 
        !           517:        cache_purge(vp);
        !           518: /*
        !           519:  *  Indicate that one less file on the filesystem is open.
        !           520:  */
        !           521:        if (dep->de_devvp) {
        !           522:                vrele(dep->de_devvp);
        !           523:                dep->de_devvp = 0;
        !           524:        }
        !           525: 
        !           526:        dep->de_flag = 0;
        !           527:        return 0;
        !           528: }
        !           529: 
        !           530: int
        !           531: pcfs_inactive(vp, p)
        !           532:        struct vnode *vp;
        !           533:        struct proc *p;
        !           534: {
        !           535:        struct denode *dep = VTODE(vp);
        !           536:        int error = 0;
        !           537: #if defined(PCFSDEBUG)
        !           538: printf("pcfs_inactive(): dep %08x, de_Name[0] %x\n", dep, dep->de_Name[0]);
        !           539: #endif /* defined(PCFSDEBUG) */
        !           540: 
        !           541:        if (pcfs_prtactive && vp->v_usecount != 0)
        !           542:                vprint("pcfs_inactive(): pushing active", vp);
        !           543: 
        !           544: /*
        !           545:  *  Get rid of denodes related to stale file handles.
        !           546:  *  Hmmm, what does this really do?
        !           547:  */
        !           548:        if (dep->de_Name[0] == SLOT_DELETED) {
        !           549:                if ((vp->v_flag & VXLOCK) == 0)
        !           550:                        vgone(vp);
        !           551:                return 0;
        !           552:        }
        !           553: 
        !           554: /*
        !           555:  *  If the file has been deleted and it is on a read/write
        !           556:  *  filesystem, then truncate the file, and mark the directory
        !           557:  *  slot as empty.  (This may not be necessary for the dos
        !           558:  *  filesystem.
        !           559:  */
        !           560: #if defined(PCFSDEBUG)
        !           561: printf("pcfs_inactive(): dep %08x, refcnt %d, mntflag %x, MNT_RDONLY %x\n",
        !           562:        dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
        !           563: #endif /* defined(PCFSDEBUG) */
        !           564:        DELOCK(dep);
        !           565:        if (dep->de_refcnt <= 0  &&  (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
        !           566:                error = detrunc(dep, (u_long)0, 0);
        !           567:                dep->de_flag |= DEUPD;
        !           568:                dep->de_Name[0] = SLOT_DELETED;
        !           569:        }
        !           570:        DEUPDAT(dep, &time, 0);
        !           571:        DEUNLOCK(dep);
        !           572:        dep->de_flag = 0;
        !           573: 
        !           574: /*
        !           575:  *  If we are done with the denode, then reclaim
        !           576:  *  it so that it can be reused now.
        !           577:  */
        !           578: #if defined(PCFSDEBUG)
        !           579: printf("pcfs_inactive(): v_usecount %d, de_Name[0] %x\n", vp->v_usecount,
        !           580:        dep->de_Name[0]);
        !           581: #endif /* defined(PCFSDEBUG) */
        !           582:        if (vp->v_usecount == 0  &&  dep->de_Name[0] == SLOT_DELETED)
        !           583:                vgone(vp);
        !           584:        return error;
        !           585: }
        !           586: 
        !           587: int
        !           588: delock(dep)
        !           589:        struct denode *dep;
        !           590: {
        !           591:        while (dep->de_flag & DELOCKED) {
        !           592:                dep->de_flag |= DEWANT;
        !           593:                if (dep->de_spare0 == curproc->p_pid)
        !           594:                        panic("delock: locking against myself");
        !           595:                dep->de_spare1 = curproc->p_pid;
        !           596:                (void) sleep((caddr_t)dep, PINOD);
        !           597:        }
        !           598:        dep->de_spare1 = 0;
        !           599:        dep->de_spare0 = curproc->p_pid;
        !           600:        dep->de_flag |= DELOCKED;
        !           601: 
        !           602:        return 0;
        !           603: }
        !           604: 
        !           605: int
        !           606: deunlock(dep)
        !           607:        struct denode *dep;
        !           608: {
        !           609:        if ((dep->de_flag & DELOCKED) == 0)
        !           610:                vprint("deunlock: found unlocked denode", DETOV(dep));
        !           611:        dep->de_spare0 = 0;
        !           612:        dep->de_flag &= ~DELOCKED;
        !           613:        if (dep->de_flag & DEWANT) {
        !           614:                dep->de_flag &= ~DEWANT;
        !           615:                wakeup((caddr_t)dep);
        !           616:        }
        !           617: 
        !           618:        return 0;
        !           619: }

unix.superglobalmegacorp.com

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