Annotation of Net2/pcfs/pcfs_denode.c, revision 1.1.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.