[BACK]Return to xfs_node-bsd.c CVS log [TXT][DIR] Up to [local] / sys / xfs

Annotation of sys/xfs/xfs_node-bsd.c, Revision 1.1.1.1

1.1       nbrk        1: /*
                      2:  * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
                      3:  * (Royal Institute of Technology, Stockholm, Sweden).
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  *
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  *
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * 3. Neither the name of the Institute nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/queue.h>
                     35: #include <xfs/xfs_locl.h>
                     36: #include <xfs/xfs_common.h>
                     37: #include <xfs/xfs_fs.h>
                     38: #include <xfs/xfs_deb.h>
                     39: #include <xfs/xfs_vnodeops.h>
                     40:
                     41: RCSID("$arla: xfs_node-bsd.c,v 1.70 2003/02/28 02:01:06 lha Exp $");
                     42:
                     43: extern vop_t **xfs_vnodeop_p;
                     44:
                     45: #ifndef LK_NOPAUSE
                     46: #define LK_NOPAUSE 0
                     47: #endif
                     48:
                     49: /*
                     50:  * Allocate a new vnode with handle `handle' in `mp' and return it in
                     51:  * `vpp'.  Return 0 or error.
                     52:  */
                     53:
                     54: int
                     55: xfs_getnewvnode(struct xfs *xfsp, struct vnode **vpp,
                     56:                struct xfs_handle *handle)
                     57: {
                     58:     struct xfs_node *result, *check;
                     59:     int error;
                     60:
                     61:     error = getnewvnode(VT_XFS, NNPFS_TO_VFS(xfsp), xfs_vnodeop_p, vpp);
                     62:     if (error)
                     63:        return error;
                     64:
                     65:     result = xfs_alloc(sizeof(*result), M_NNPFS_NODE);
                     66:     bzero(result, sizeof(*result));
                     67:
                     68:     (*vpp)->v_data = result;
                     69:     result->vn = *vpp;
                     70:
                     71:     result->handle = *handle;
                     72:     result->flags = 0;
                     73:     result->tokens = 0;
                     74:     result->offset = 0;
                     75: #if defined(HAVE_KERNEL_LOCKMGR) || defined(HAVE_KERNEL_DEBUGLOCKMGR)
                     76:     lockinit (&result->lock, PVFS, "xfs_lock", 0, LK_NOPAUSE);
                     77: #else
                     78:     result->vnlocks = 0;
                     79: #endif
                     80:     result->anonrights = 0;
                     81:     result->rd_cred = NULL;
                     82:     result->wr_cred = NULL;
                     83:
                     84: #if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105280000
                     85:     genfs_node_init(*vpp, &xfs_genfsops);
                     86: #endif
                     87:
                     88:     check = xfs_node_find(&xfsp->nodehead, handle);
                     89:     if (check) {
                     90:        vput(*vpp);
                     91:        *vpp = result->vn;
                     92:        return 0;
                     93:     }
                     94:
                     95:     xfs_insert(&xfs->nodehead, result);
                     96:
                     97:     return 0;
                     98: }
                     99:
                    100: /*
                    101:  * Create a new xfs_node and make a vget
                    102:  *
                    103:  * Also prevents creation of duplicates. This happens
                    104:  * whenever there are more than one name to a file,
                    105:  * "." and ".." are common cases.  */
                    106:
                    107: int
                    108: new_xfs_node(struct xfs *xfsp,
                    109:             struct xfs_msg_node *node,
                    110:             struct xfs_node **xpp,
                    111:             d_thread_t *p)
                    112: {
                    113:     struct xfs_node *result;
                    114:
                    115:     NNPFSDEB(XDEBNODE, ("new_xfs_node (%d,%d,%d,%d)\n",
                    116:                      node->handle.a,
                    117:                      node->handle.b,
                    118:                      node->handle.c,
                    119:                      node->handle.d));
                    120:
                    121: retry:
                    122:     /* Does not allow duplicates */
                    123:     result = xfs_node_find(&xfsp->nodehead, &node->handle);
                    124:     if (result == 0) {
                    125:        int error;
                    126:        struct vnode *v;
                    127:
                    128:        error = xfs_getnewvnode(xfsp, &v, &node->handle);
                    129:        if (error)
                    130:            return error;
                    131:
                    132:        result = VNODE_TO_XNODE(v);
                    133:        result->anonrights = node->anonrights;
                    134:
                    135:        xfsp->nnodes++;
                    136:     } else {
                    137:        /* Node is already cached */
                    138:        if(xfs_do_vget(XNODE_TO_VNODE(result), 0, p))
                    139:            goto retry;
                    140:     }
                    141:
                    142:     /* Init other fields */
                    143:     xfs_attr2vattr(&node->attr, &result->attr, 1);
                    144:     result->vn->v_type = result->attr.va_type;
                    145:     result->tokens = node->tokens;
                    146:     bcopy(node->id, result->id, sizeof(result->id));
                    147:     bcopy(node->rights, result->rights, sizeof(result->rights));
                    148:
                    149: #ifdef __APPLE__
                    150:     if (result->vn->v_type == VREG && (!UBCINFOEXISTS(result->vn)))
                    151:        ubc_info_init(result->vn);
                    152: #endif
                    153:
                    154:     *xpp = result;
                    155:     NNPFSDEB(XDEBNODE, ("return: new_xfs_node\n"));
                    156:     return 0;
                    157: }
                    158:
                    159: void
                    160: free_xfs_node(struct xfs_node *node)
                    161: {
                    162:     struct xfs *xfsp = NNPFS_FROM_XNODE(node);
                    163:
                    164:     NNPFSDEB(XDEBNODE, ("free_xfs_node(%lx) (%d,%d,%d,%d)\n",
                    165:                      (unsigned long)node,
                    166:                      node->handle.a,
                    167:                      node->handle.b,
                    168:                      node->handle.c,
                    169:                      node->handle.d));
                    170:
                    171:     /* XXX Really need to put back dirty data first. */
                    172:
                    173:     if (DATA_FROM_XNODE(node)) {
                    174:        vrele(DATA_FROM_XNODE(node));
                    175:        DATA_FROM_XNODE(node) = NULL;
                    176:     }
                    177:     xfsp->nnodes--;
                    178:     XNODE_TO_VNODE(node)->v_data = NULL;
                    179:     if (node->rd_cred) {
                    180:        crfree (node->rd_cred);
                    181:        node->rd_cred = NULL;
                    182:     }
                    183:     if (node->wr_cred) {
                    184:        crfree (node->wr_cred);
                    185:        node->wr_cred = NULL;
                    186:     }
                    187:
                    188:     xfs_free(node, sizeof(*node), M_NNPFS_NODE);
                    189:
                    190:     NNPFSDEB(XDEBNODE, ("free_xfs_node done\n"));
                    191: }
                    192:
                    193: /*
                    194:  * FreeBSD 4.4 and newer changed to API to vflush around June 2001
                    195:  */
                    196:
                    197: static int
                    198: xfs_vflush(struct mount *mp, int flags)
                    199: {
                    200: #if __FreeBSD__ && __FreeBSD_version > 430000
                    201:     return vflush(mp, 0, flags);
                    202: #else
                    203:     return vflush(mp, NULL, flags);
                    204: #endif
                    205: }
                    206:
                    207: int
                    208: free_all_xfs_nodes(struct xfs *xfsp, int flags, int unmountp)
                    209: {
                    210:     int error = 0;
                    211:     struct mount *mp = NNPFS_TO_VFS(xfsp);
                    212:
                    213:     if (mp == NULL) {
                    214:        NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n"));
                    215:        return 0;
                    216:     }
                    217:
                    218:     NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n"));
                    219:
                    220:     xfs_dnlc_purge_mp(mp);
                    221:
                    222:     if (xfsp->root) {
                    223:        NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n"));
                    224:
                    225:        vgone(XNODE_TO_VNODE(xfsp->root));
                    226:        xfsp->root = NULL;
                    227:     }
                    228:
                    229:     NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n"));
                    230:     NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes now killing all remaining nodes\n"));
                    231:
                    232:     /*
                    233:      * If we have a syncer vnode, release it (to emulate dounmount)
                    234:      * and the create it again when if we are going to need it.
                    235:      */
                    236:
                    237: #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER
                    238:     if (!unmountp) {
                    239:        if (mp->mnt_syncer != NULL) {
                    240: #ifdef HAVE_KERNEL_VFS_DEALLOCATE_SYNCVNODE
                    241:            vfs_deallocate_syncvnode(mp);
                    242: #else
                    243:            /*
                    244:             * FreeBSD and OpenBSD uses different semantics,
                    245:             * FreeBSD does vrele, and OpenBSD does vgone.
                    246:             */
                    247: #if defined(__OpenBSD__)
                    248:            vgone(mp->mnt_syncer);
                    249: #elif defined(__FreeBSD__)
                    250:            vrele(mp->mnt_syncer);
                    251: #else
                    252: #error what os do you use ?
                    253: #endif
                    254:            mp->mnt_syncer = NULL;
                    255: #endif
                    256:        }
                    257:     }
                    258: #endif
                    259:     error = xfs_vflush(mp, flags);
                    260: #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER
                    261:     if (!unmountp) {
                    262:        NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes not flushing syncer vnode\n"));
                    263:        if (mp->mnt_syncer == NULL)
                    264:            if (vfs_allocate_syncvnode(mp))
                    265:                panic("failed to allocate syncer node when xfs daemon died");
                    266:     }
                    267: #endif
                    268:
                    269:     if (error) {
                    270:        NNPFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush() error == %d\n",
                    271:                          error));
                    272:        return error;
                    273:     }
                    274:
                    275:     NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n"));
                    276:     return error;
                    277: }
                    278:
                    279: void
                    280: vattr2xfs_attr(const struct vattr *va, struct xfs_attr *xa)
                    281: {
                    282:     bzero(xa, sizeof(*xa));
                    283:     if (va->va_mode != (mode_t)VNOVAL)
                    284:        XA_SET_MODE(xa, va->va_mode);
                    285:     if (va->va_nlink != VNOVAL)
                    286:        XA_SET_NLINK(xa, va->va_nlink);
                    287:     if (va->va_size != VNOVAL)
                    288:        XA_SET_SIZE(xa, va->va_size);
                    289:     if (va->va_uid != VNOVAL)
                    290:        XA_SET_UID(xa, va->va_uid);
                    291:     if (va->va_gid != VNOVAL)
                    292:        XA_SET_GID(xa, va->va_gid);
                    293:     if (va->va_atime.tv_sec != VNOVAL)
                    294:        XA_SET_ATIME(xa, va->va_atime.tv_sec);
                    295:     if (va->va_mtime.tv_sec != VNOVAL)
                    296:        XA_SET_MTIME(xa, va->va_mtime.tv_sec);
                    297:     if (va->va_ctime.tv_sec != VNOVAL)
                    298:        XA_SET_CTIME(xa, va->va_ctime.tv_sec);
                    299:     if (va->va_fileid != VNOVAL)
                    300:        XA_SET_FILEID(xa, va->va_fileid);
                    301:     switch (va->va_type) {
                    302:     case VNON:
                    303:        xa->xa_type = NNPFS_FILE_NON;
                    304:        break;
                    305:     case VREG:
                    306:        xa->xa_type = NNPFS_FILE_REG;
                    307:        break;
                    308:     case VDIR:
                    309:        xa->xa_type = NNPFS_FILE_DIR;
                    310:        break;
                    311:     case VBLK:
                    312:        xa->xa_type = NNPFS_FILE_BLK;
                    313:        break;
                    314:     case VCHR:
                    315:        xa->xa_type = NNPFS_FILE_CHR;
                    316:        break;
                    317:     case VLNK:
                    318:        xa->xa_type = NNPFS_FILE_LNK;
                    319:        break;
                    320:     case VSOCK:
                    321:        xa->xa_type = NNPFS_FILE_SOCK;
                    322:        break;
                    323:     case VFIFO:
                    324:        xa->xa_type = NNPFS_FILE_FIFO;
                    325:        break;
                    326:     case VBAD:
                    327:        xa->xa_type = NNPFS_FILE_BAD;
                    328:        break;
                    329:     default:
                    330:        panic("xfs_attr2attr: bad value");
                    331:     }
                    332: }
                    333:
                    334: #define SET_TIMEVAL(X, S, N) do { (X)->tv_sec = (S); (X)->tv_nsec = (N); } while(0)
                    335:
                    336: void
                    337: xfs_attr2vattr(const struct xfs_attr *xa, struct vattr *va, int clear_node)
                    338: {
                    339:     if (clear_node)
                    340:        VATTR_NULL(va);
                    341:     if (XA_VALID_MODE(xa))
                    342:        va->va_mode = xa->xa_mode;
                    343:     if (XA_VALID_NLINK(xa))
                    344:        va->va_nlink = xa->xa_nlink;
                    345:     if (XA_VALID_SIZE(xa)) {
                    346:        va->va_size = xa->xa_size;
                    347:        va->va_bytes = va->va_size;
                    348:     }
                    349:     if (XA_VALID_UID(xa))
                    350:        va->va_uid = xa->xa_uid;
                    351:     if (XA_VALID_GID(xa))
                    352:        va->va_gid = xa->xa_gid;
                    353:     if (XA_VALID_ATIME(xa)) {
                    354:        SET_TIMEVAL(&va->va_atime, xa->xa_atime, 0);
                    355:     }
                    356:     if (XA_VALID_MTIME(xa)) {
                    357:        SET_TIMEVAL(&va->va_mtime, xa->xa_mtime, 0);
                    358:     }
                    359:     if (XA_VALID_CTIME(xa)) {
                    360:        SET_TIMEVAL(&va->va_ctime, xa->xa_ctime, 0);
                    361:     }
                    362:     if (XA_VALID_FILEID(xa)) {
                    363:        va->va_fileid = xa->xa_fileid;
                    364:     }
                    365:     if (XA_VALID_TYPE(xa)) {
                    366:        switch (xa->xa_type) {
                    367:        case NNPFS_FILE_NON:
                    368:            va->va_type = VNON;
                    369:            break;
                    370:        case NNPFS_FILE_REG:
                    371:            va->va_type = VREG;
                    372:            break;
                    373:        case NNPFS_FILE_DIR:
                    374:            va->va_type = VDIR;
                    375:            break;
                    376:        case NNPFS_FILE_BLK:
                    377:            va->va_type = VBLK;
                    378:            break;
                    379:        case NNPFS_FILE_CHR:
                    380:            va->va_type = VCHR;
                    381:            break;
                    382:        case NNPFS_FILE_LNK:
                    383:            va->va_type = VLNK;
                    384:            break;
                    385:        case NNPFS_FILE_SOCK:
                    386:            va->va_type = VSOCK;
                    387:            break;
                    388:        case NNPFS_FILE_FIFO:
                    389:            va->va_type = VFIFO;
                    390:            break;
                    391:        case NNPFS_FILE_BAD:
                    392:            va->va_type = VBAD;
                    393:            break;
                    394:        default:
                    395:            panic("xfs_attr2vattr: bad value");
                    396:        }
                    397:     }
                    398:     va->va_flags = 0;
                    399:     va->va_blocksize = 8192;
                    400: }
                    401:
                    402: /*
                    403:  * A single entry DNLC for systems for handling long names that don't
                    404:  * get put into the system DNLC.
                    405:  */
                    406:
                    407: struct long_entry {
                    408:     struct vnode *dvp, *vp;
                    409:     char name[MAXNAMLEN + 1];
                    410:     size_t len;
                    411:     u_long dvpid, vpid;
                    412: };
                    413:
                    414: static struct long_entry tbl;
                    415:
                    416: /*
                    417:  * Nuke the `tbl'
                    418:  */
                    419:
                    420: static void
                    421: tbl_clear (void)
                    422: {
                    423:     tbl.dvp = tbl.vp = NULL;
                    424:     tbl.name[0] = '\0';
                    425:     tbl.len = 0;
                    426:     tbl.dvpid = tbl.vpid = 0;
                    427: }
                    428:
                    429: /*
                    430:  * Set the entry in the `tbl'
                    431:  */
                    432:
                    433: static void
                    434: tbl_enter (size_t len, const char *name, struct vnode *dvp, struct vnode *vp)
                    435: {
                    436:     tbl.len = len;
                    437:     bcopy(name, tbl.name, len);
                    438:     tbl.dvp = dvp;
                    439:     tbl.vp = vp;
                    440:     tbl.dvpid = dvp->v_id;
                    441:     tbl.vpid = vp->v_id;
                    442: }
                    443:
                    444: /*
                    445:  * Lookup in tbl (`dvp', `name', `len') and return result in `res'.
                    446:  * Return -1 if successful, otherwise 0.
                    447:  */
                    448:
                    449: static int
                    450: tbl_lookup (struct componentname *cnp,
                    451:            struct vnode *dvp,
                    452:            struct vnode **res)
                    453: {
                    454:     if (tbl.dvp == dvp
                    455:        && tbl.len == cnp->cn_namelen
                    456:        && strncmp(tbl.name, cnp->cn_nameptr, tbl.len) == 0
                    457:        && tbl.dvpid == tbl.dvp->v_id
                    458:        && tbl.vpid == tbl.vp->v_id) {
                    459:
                    460:        *res = tbl.vp;
                    461:        return -1;
                    462:     } else
                    463:        return 0;
                    464: }
                    465:
                    466: /*
                    467:  * Store a componentname in the DNLC
                    468:  */
                    469:
                    470: int
                    471: xfs_dnlc_enter(struct vnode *dvp,
                    472:               xfs_componentname *cnp,
                    473:               struct vnode *vp)
                    474: {
                    475:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter_cnp(%lx, %lx, %lx)\n",
                    476:                      (unsigned long)dvp,
                    477:                      (unsigned long)cnp,
                    478:                      (unsigned long)vp));
                    479:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %lu\n", (u_long)dvp->v_id));
                    480:
                    481:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:"
                    482:                      "dvp = %lx, vp = %lx, cnp = (%s, %ld), "
                    483:                      "nameiop = %lu, flags = %lx\n",
                    484:                      (unsigned long)dvp,
                    485:                      (unsigned long)vp,
                    486:                      cnp->cn_nameptr, cnp->cn_namelen,
                    487:                      cnp->cn_nameiop, cnp->cn_flags));
                    488:
                    489: #ifdef NCHNAMLEN
                    490:     if (cnp->cn_namelen <= NCHNAMLEN)
                    491: #endif
                    492:     {
                    493:        /*
                    494:         * This is to make sure there's no negative entry already in the dnlc
                    495:         */
                    496:        u_long save_nameiop;
                    497:        u_long save_flags;
                    498:        struct vnode *dummy;
                    499:
                    500:        save_nameiop    = cnp->cn_nameiop;
                    501:        save_flags      = cnp->cn_flags;
                    502:        cnp->cn_nameiop = CREATE;
                    503:        cnp->cn_flags  &= ~MAKEENTRY;
                    504:
                    505: /*
                    506:  * The version number here is not entirely correct, but it's conservative.
                    507:  * The real change is sys/kern/vfs_cache:1.20
                    508:  */
                    509:
                    510: #if __NetBSD_Version__ >= 104120000 || OpenBSD > 200211
                    511:        if (cache_lookup(dvp, &dummy, cnp) != -1) {
                    512:            xfs_vfs_unlock(dummy, xfs_cnp_to_proc(cnp));
                    513:            printf ("NNPFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n",
                    514:                    cnp->cn_nameptr);
                    515:        }
                    516: #else
                    517:        if (cache_lookup(dvp, &dummy, cnp) != 0) {
                    518:            printf ("NNPFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n",
                    519:                    cnp->cn_nameptr);
                    520:        }
                    521: #endif
                    522:
                    523:
                    524:        cnp->cn_nameiop = save_nameiop;
                    525:        cnp->cn_flags   = save_flags;
                    526:        cache_enter(dvp, vp, cnp);
                    527:     }
                    528:
                    529:     if (vp != NULL)
                    530:        tbl_enter (cnp->cn_namelen, cnp->cn_nameptr, dvp, vp);
                    531:
                    532:     return 0;
                    533: }
                    534:
                    535:
                    536: static void
                    537: xfs_cnp_init (struct componentname *cn,
                    538:              const char *name,
                    539:              d_thread_t *proc, struct ucred *cred,
                    540:              int nameiop)
                    541: {
                    542:     bzero(cn, sizeof(*cn));
                    543:     cn->cn_nameptr = (char *)name;
                    544:     cn->cn_namelen = strlen(name);
                    545:     cn->cn_flags   = 0;
                    546: #if __APPLE__
                    547:     {
                    548:        const unsigned char *p;
                    549:        int i;
                    550:
                    551:        cn->cn_hash = 0;
                    552:        for (p = cn->cn_nameptr, i = 1; *p; ++p, ++i)
                    553:            cn->cn_hash += *p * i;
                    554:     }
                    555: #elif defined(HAVE_KERNEL_NAMEI_HASH)
                    556:     {
                    557:        const char *cp = name + cn->cn_namelen;
                    558:        cn->cn_hash = namei_hash(name, &cp);
                    559:     }
                    560: #elif defined(HAVE_STRUCT_COMPONENTNAME_CN_HASH)
                    561:     {
                    562:        const unsigned char *p;
                    563:
                    564:        cn->cn_hash = 0;
                    565:        for (p = cn->cn_nameptr; *p; ++p)
                    566:            cn->cn_hash += *p;
                    567:     }
                    568: #endif
                    569:     cn->cn_nameiop = nameiop;
                    570: #ifdef HAVE_FREEBSD_THREAD
                    571:     cn->cn_thread = proc;
                    572: #else
                    573:     cn->cn_proc = proc;
                    574: #endif
                    575:     cn->cn_cred = cred;
                    576: }
                    577:
                    578:
                    579: /*
                    580:  * Store (dvp, name, vp) in the DNLC
                    581:  */
                    582:
                    583: int
                    584: xfs_dnlc_enter_name(struct vnode *dvp,
                    585:                    const char *name,
                    586:                    struct vnode *vp)
                    587: {
                    588:     struct componentname cn;
                    589:
                    590:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter_name(%lx, \"%s\", %lx)\n",
                    591:                      (unsigned long)dvp,
                    592:                      name,
                    593:                      (unsigned long)vp));
                    594:
                    595:     xfs_cnp_init (&cn, name, NULL, NULL, LOOKUP);
                    596:     return xfs_dnlc_enter (dvp, &cn, vp);
                    597: }
                    598:
                    599: /*
                    600:  * Lookup (dvp, cnp) in the DNLC and return the result in `res'.
                    601:  * Return the result from cache_lookup.
                    602:  */
                    603:
                    604: static int
                    605: xfs_dnlc_lookup_int(struct vnode *dvp,
                    606:                    xfs_componentname *cnp,
                    607:                    struct vnode **res)
                    608: {
                    609:     int error;
                    610:     u_long saved_flags;
                    611:
                    612:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(%lx, \"%s\")\n",
                    613:                      (unsigned long)dvp, cnp->cn_nameptr));
                    614:
                    615:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %lu\n", (u_long)dvp->v_id));
                    616:
                    617:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:"
                    618:                      "dvp = %lx, cnp = (%s, %ld), flags = %lx\n",
                    619:                      (unsigned long)dvp,
                    620:                      cnp->cn_nameptr, cnp->cn_namelen,
                    621:                      cnp->cn_flags));
                    622:
                    623:     saved_flags = cnp->cn_flags;
                    624:     cnp->cn_flags |= MAKEENTRY | LOCKPARENT | ISLASTCN;
                    625:
                    626:     error = cache_lookup(dvp, res, cnp);
                    627:
                    628:     cnp->cn_flags = saved_flags;
                    629:
                    630:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. "
                    631:                      "error = %d, *res = %lx\n", error,
                    632:                      (unsigned long)*res));
                    633:     return error;
                    634: }
                    635:
                    636: /*
                    637:  * do the last (and locking protocol) portion of xnlc_lookup
                    638:  *
                    639:  * return:
                    640:  * -1 for successful
                    641:  * 0  for failed
                    642:  */
                    643:
                    644: static int
                    645: xfs_dnlc_lock(struct vnode *dvp,
                    646:              xfs_componentname *cnp,
                    647:              struct vnode **res)
                    648: {
                    649:     int error = 0;
                    650:
                    651:     /*
                    652:      * Try to handle the (complex) BSD locking protocol.
                    653:      */
                    654:
                    655:     if (*res == dvp) {         /* "." */
                    656:        VREF(dvp);
                    657:     } else if (cnp->cn_flags & ISDOTDOT) { /* ".." */
                    658:        u_long vpid = dvp->v_id;
                    659:
                    660: #ifdef HAVE_FREEBSD_THREAD
                    661:        xfs_vfs_unlock(dvp, xfs_cnp_to_thread(cnp));
                    662:        error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp));
                    663:        xfs_vfs_writelock(dvp, xfs_cnp_to_thread(cnp));
                    664: #else
                    665:        xfs_vfs_unlock(dvp, xfs_cnp_to_proc(cnp));
                    666:        error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp));
                    667:        xfs_vfs_writelock(dvp, xfs_cnp_to_proc(cnp));
                    668: #endif
                    669:
                    670:        if (error == 0 && dvp->v_id != vpid) {
                    671:            vput(*res);
                    672:            return 0;
                    673:        }
                    674:     } else {
                    675: #ifdef HAVE_FREEBSD_THREAD
                    676:        error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp));
                    677: #else
                    678:        error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp));
                    679: #endif
                    680:     }
                    681:
                    682:     if (error == 0)
                    683:        return -1;
                    684:     else
                    685:        return 0;
                    686: }
                    687:
                    688: /*
                    689:  * Lookup (`dvp', `cnp') in the DNLC (and the local cache).
                    690:  *
                    691:  * Return -1 if successful, 0 if not and ENOENT if the entry is known
                    692:  * not to exist.
                    693:  *
                    694:  * On modern NetBSD, cache_lookup has been changed to return 0 for
                    695:  * successful and -1 for not.
                    696:  * (see the comment above for version information).
                    697:  */
                    698:
                    699: #if __NetBSD_Version__ >= 104120000 || defined(__OpenBSD__)
                    700:
                    701: int
                    702: xfs_dnlc_lookup(struct vnode *dvp,
                    703:                xfs_componentname *cnp,
                    704:                struct vnode **res)
                    705: {
                    706:     int error = xfs_dnlc_lookup_int (dvp, cnp, res);
                    707:
                    708:     if (error == 0)
                    709:        return -1;
                    710:     else if (error == ENOENT)
                    711:        return error;
                    712:
                    713:     error = tbl_lookup (cnp, dvp, res);
                    714:
                    715:     if (error != -1)
                    716:        return error;
                    717:
                    718:     return xfs_dnlc_lock (dvp, cnp, res);
                    719: }
                    720:
                    721: #else /* !  __NetBSD_Version__ >= 104120000 && ! OpenBSD > 200211 */
                    722:
                    723: int
                    724: xfs_dnlc_lookup(struct vnode *dvp,
                    725:                xfs_componentname *cnp,
                    726:                struct vnode **res)
                    727: {
                    728:     int error = xfs_dnlc_lookup_int (dvp, cnp, res);
                    729:
                    730:     if (error == 0)
                    731:        error = tbl_lookup (cnp, dvp, res);
                    732:
                    733:     if (error != -1)
                    734:        return error;
                    735:
                    736:     return xfs_dnlc_lock (dvp, cnp, res);
                    737: }
                    738:
                    739: #endif /*  __NetBSD_Version__ >= 104120000 || OpenBSD > 200211 */
                    740:
                    741: /*
                    742:  * Remove one entry from the DNLC
                    743:  */
                    744:
                    745: void
                    746: xfs_dnlc_purge (struct vnode *vp)
                    747: {
                    748:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_purge\n"));
                    749:
                    750:     if (tbl.dvp == vp || tbl.vp == vp)
                    751:        tbl_clear ();
                    752:
                    753:     cache_purge(vp);
                    754: }
                    755:
                    756: /*
                    757:  * Remove all entries belong to `mp' from the DNLC
                    758:  */
                    759:
                    760: void
                    761: xfs_dnlc_purge_mp(struct mount *mp)
                    762: {
                    763:     NNPFSDEB(XDEBDNLC, ("xfs_dnlc_purge_mp()\n"));
                    764:
                    765:     tbl_clear ();
                    766:     cache_purgevfs(mp);
                    767: }
                    768:
                    769: /*
                    770:  * Returns 1 if pag has any rights set in the node
                    771:  */
                    772:
                    773: int
                    774: xfs_has_pag(const struct xfs_node *xn, xfs_pag_t pag)
                    775: {
                    776:     int i;
                    777:
                    778:     for (i = 0; i < MAXRIGHTS; i++)
                    779:        if (xn->id[i] == pag)
                    780:            return 1;
                    781:
                    782:     return 0;
                    783: }
                    784:
                    785: void
                    786: xfs_update_write_cred(struct xfs_node *xn, struct ucred *cred)
                    787: {
                    788:     if (xn->wr_cred)
                    789:        crfree (xn->wr_cred);
                    790:     crhold (cred);
                    791:     xn->wr_cred = cred;
                    792: }
                    793:
                    794: void
                    795: xfs_update_read_cred(struct xfs_node *xn, struct ucred *cred)
                    796: {
                    797:     if (xn->rd_cred)
                    798:        crfree (xn->rd_cred);
                    799:     crhold (cred);
                    800:     xn->rd_cred = cred;
                    801: }

CVSweb