[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     ! 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