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

Annotation of sys/xfs/xfs_vnodeops-common.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: /*
        !            35:  * NNPFS operations.
        !            36:  */
        !            37:
        !            38: #include <xfs/xfs_locl.h>
        !            39: #include <xfs/xfs_message.h>
        !            40: #include <xfs/xfs_common.h>
        !            41: #include <xfs/xfs_fs.h>
        !            42: #include <xfs/xfs_dev.h>
        !            43: #include <xfs/xfs_deb.h>
        !            44: #include <xfs/xfs_syscalls.h>
        !            45: #include <xfs/xfs_vnodeops.h>
        !            46:
        !            47: RCSID("$arla: xfs_vnodeops-common.c,v 1.94 2003/01/27 11:58:50 lha Exp $");
        !            48:
        !            49: static void
        !            50: xfs_handle_stale(struct xfs_node *xn)
        !            51: {
        !            52: #if __APPLE__
        !            53:     struct vnode *vp = XNODE_TO_VNODE(xn);
        !            54: #endif
        !            55:
        !            56:     if ((xn->flags & NNPFS_STALE) == 0)
        !            57:        return;
        !            58:
        !            59: #if __APPLE__
        !            60:     if (UBCISVALID(vp) && !ubc_isinuse(vp, 1)) {
        !            61:        xn->flags &= ~NNPFS_STALE;
        !            62:        ubc_setsize(vp, 0);
        !            63:        NNPFS_TOKEN_CLEAR(xn, ~0,
        !            64:                        NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
        !            65:                        NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
        !            66:     }
        !            67: #endif
        !            68: }
        !            69:
        !            70: int
        !            71: xfs_open_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
        !            72:               u_int tok)
        !            73: {
        !            74:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !            75:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !            76:     int error = 0;
        !            77:
        !            78:     NNPFSDEB(XDEBVFOPS, ("xfs_open_valid\n"));
        !            79:
        !            80:     xfs_handle_stale(xn);
        !            81:
        !            82:     do {
        !            83:        if (!NNPFS_TOKEN_GOT(xn, tok)) {
        !            84:            struct xfs_message_open msg;
        !            85:
        !            86:            msg.header.opcode = NNPFS_MSG_OPEN;
        !            87:            msg.cred.uid = cred->cr_uid;
        !            88:            msg.cred.pag = xfs_get_pag(cred);
        !            89:            msg.handle = xn->handle;
        !            90:            msg.tokens = tok;
        !            91:
        !            92:            error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !            93:
        !            94:            if (error == 0)
        !            95:                error = ((struct xfs_message_wakeup *) & msg)->error;
        !            96:        } else {
        !            97:            goto done;
        !            98:        }
        !            99:     } while (error == 0);
        !           100:
        !           101: done:
        !           102:     NNPFSDEB(XDEBVFOPS, ("xfs_open_valid: error = %d\n", error));
        !           103:
        !           104:     return error;
        !           105: }
        !           106:
        !           107: int
        !           108: xfs_attr_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
        !           109:               u_int tok)
        !           110: {
        !           111:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !           112:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           113:     int error = 0;
        !           114:     xfs_pag_t pag = xfs_get_pag(cred);
        !           115:
        !           116:     do {
        !           117:        if (!NNPFS_TOKEN_GOT(xn, tok) || !xfs_has_pag(xn, pag)) {
        !           118:            struct xfs_message_getattr msg;
        !           119:
        !           120:            msg.header.opcode = NNPFS_MSG_GETATTR;
        !           121:            msg.cred.uid = cred->cr_uid;
        !           122:            msg.cred.pag = pag;
        !           123:            msg.handle = xn->handle;
        !           124:            error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           125:            if (error == 0)
        !           126:                error = ((struct xfs_message_wakeup *) & msg)->error;
        !           127:        } else {
        !           128:            goto done;
        !           129:        }
        !           130:     } while (error == 0);
        !           131:
        !           132: done:
        !           133:     return error;
        !           134: }
        !           135:
        !           136: int
        !           137: xfs_data_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
        !           138:               u_int tok, uint32_t want_offset)
        !           139: {
        !           140:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !           141:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           142:     int error = 0;
        !           143:     uint32_t offset;
        !           144:     struct xfs_message_getdata msg;
        !           145:
        !           146:     do {
        !           147:        offset = want_offset;
        !           148:        if (NNPFS_TOKEN_GOT(xn, tok|NNPFS_ATTR_R) && offset > xn->attr.va_size) {
        !           149:            offset = xn->attr.va_size;
        !           150:        }
        !           151:
        !           152:        NNPFSDEB(XDEBVNOPS, ("xfs_data_valid: offset: want %ld has %ld, "
        !           153:                           "tokens: want %lx has %lx length: %ld\n",
        !           154:                           (long) offset, (long) xn->offset,
        !           155:                           (long) tok, (long) xn->tokens,
        !           156:                           (long) xn->attr.va_size));
        !           157:
        !           158:        if (NNPFS_TOKEN_GOT(xn, tok)) {
        !           159:            if (offset <= xn->offset || xn->attr.va_type == VDIR) {
        !           160:                break;
        !           161:            }
        !           162:        }
        !           163:
        !           164:        msg.header.opcode = NNPFS_MSG_GETDATA;
        !           165:        msg.cred.uid = cred->cr_uid;
        !           166:        msg.cred.pag = xfs_get_pag(cred);
        !           167:        msg.handle = xn->handle;
        !           168:        msg.tokens = tok;
        !           169:        msg.offset = offset;
        !           170:
        !           171:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           172:
        !           173:        if (error == 0)
        !           174:            error = ((struct xfs_message_wakeup *) & msg)->error;
        !           175:
        !           176:     } while (error == 0);
        !           177:
        !           178:     return error;
        !           179: }
        !           180:
        !           181: int
        !           182: xfs_open_common(struct vnode *vp,
        !           183:                int mode,
        !           184:                struct ucred *cred,
        !           185:                d_thread_t *p)
        !           186: {
        !           187:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           188:     int ret;
        !           189:
        !           190:     NNPFSDEB(XDEBVNOPS, ("xfs_open\n"));
        !           191:
        !           192:     if (mode & FWRITE) {
        !           193:        ret = xfs_open_valid(vp, cred, p, NNPFS_OPEN_NW);
        !           194:     } else {
        !           195:        ret = xfs_open_valid(vp, cred, p, NNPFS_OPEN_NR);
        !           196:     }
        !           197:
        !           198:     /* always update the read cred */
        !           199:
        !           200:     if (mode & FWRITE)
        !           201:        xfs_update_write_cred(xn, cred);
        !           202:     xfs_update_read_cred(xn, cred);
        !           203:
        !           204:     return ret;
        !           205: }
        !           206:
        !           207: static int
        !           208: do_fsync(struct xfs *xfsp,
        !           209:         struct xfs_node *xn,
        !           210:         struct ucred *cred,
        !           211:         d_thread_t *p,
        !           212:         u_int flag)
        !           213: {
        !           214:     int error;
        !           215:     struct xfs_message_putdata msg;
        !           216:
        !           217:     msg.header.opcode = NNPFS_MSG_PUTDATA;
        !           218:     if (cred != NOCRED) {
        !           219:        msg.cred.uid = cred->cr_uid;
        !           220:        msg.cred.pag = xfs_get_pag(cred);
        !           221:     } else {
        !           222:        msg.cred.uid = 0;
        !           223:        msg.cred.pag = NNPFS_ANONYMOUSID;
        !           224:     }
        !           225:     msg.handle = xn->handle;
        !           226:     vattr2xfs_attr(&xn->attr, &msg.attr);
        !           227:     msg.flag   = flag;
        !           228:
        !           229:     error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           230:
        !           231:     if (error == 0)
        !           232:        error = ((struct xfs_message_wakeup *) & msg)->error;
        !           233:
        !           234:     if (error == 0)
        !           235:        xn->flags &= ~NNPFS_DATA_DIRTY;
        !           236:
        !           237:     return error;
        !           238: }
        !           239:
        !           240: int
        !           241: xfs_fsync_common(struct vnode *vp, struct ucred *cred,
        !           242:                 int waitfor, d_thread_t *proc)
        !           243: {
        !           244:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !           245:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           246:     int error = 0;
        !           247:
        !           248:     NNPFSDEB(XDEBVNOPS, ("xfs_fsync: %lx\n", (unsigned long)vp));
        !           249:
        !           250:     /*
        !           251:      * It seems that fsync is sometimes called after reclaiming a node.
        !           252:      * In that case we just look happy.
        !           253:      */
        !           254:
        !           255:     if (xn == NULL) {
        !           256:        printf("NNPFS PANIC WARNING! xfs_fsync called after reclaiming!\n");
        !           257:        return 0;
        !           258:     }
        !           259:
        !           260:     xfs_pushdirty(vp, cred, proc);
        !           261:
        !           262:     if (xn->flags & NNPFS_DATA_DIRTY) {
        !           263: #ifdef FSYNC_RECLAIM
        !           264:        /* writing back the data from this vnode failed */
        !           265:        if (waitfor & FSYNC_RECLAIM) {
        !           266:            printf("xfs_fsync: data lost, failed to write back\n");
        !           267:            xn->flags &= ~NNPFS_DATA_DIRTY;
        !           268:            return 0;
        !           269:        }
        !           270: #endif
        !           271:        error = do_fsync(xfsp, xn, cred, proc, NNPFS_WRITE | NNPFS_FSYNC);
        !           272:     }
        !           273:
        !           274:     return error;
        !           275: }
        !           276:
        !           277: int
        !           278: xfs_close_common(struct vnode *vp, int fflag,
        !           279:                 d_thread_t *proc, struct ucred *cred)
        !           280: {
        !           281:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !           282:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           283:     int error = 0;
        !           284:
        !           285:     NNPFSDEB(XDEBVNOPS,
        !           286:           ("xfs_close cred = %lx, fflag = %x, xn->flags = %x\n",
        !           287:            (unsigned long)cred, fflag, xn->flags));
        !           288:
        !           289:     if (vp->v_type == VREG)
        !           290:        xfs_pushdirty(vp, cred, proc);
        !           291:
        !           292:     if (fflag & FWRITE && xn->flags & NNPFS_DATA_DIRTY)
        !           293:        error = do_fsync(xfsp, xn, cred, proc, NNPFS_WRITE);
        !           294:
        !           295:     return error;
        !           296: }
        !           297:
        !           298: size_t
        !           299: xfs_uio_end_length (struct uio *uio)
        !           300: {
        !           301: #ifdef DIAGNOSTIC
        !           302:     size_t sz = 0;
        !           303:     int i;
        !           304:
        !           305:     for (i = 0; i < uio->uio_iovcnt; i++)
        !           306:        sz += uio->uio_iov[i].iov_len;
        !           307:     if (sz != uio->uio_resid)
        !           308:        panic("xfs_uio_end_length");
        !           309: #endif
        !           310:     return uio->uio_offset + uio->uio_resid;
        !           311: }
        !           312:
        !           313:
        !           314: int
        !           315: xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag,
        !           316:                struct ucred *cred)
        !           317: {
        !           318:     int error = 0;
        !           319:     int i;
        !           320:
        !           321:     NNPFSDEB(XDEBVNOPS, ("xfs_read\n"));
        !           322:
        !           323:     xfs_update_read_cred(VNODE_TO_XNODE(vp), cred);
        !           324:
        !           325: #ifdef HAVE_FREEBSD_THREAD
        !           326:     error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uio), NNPFS_DATA_R,
        !           327:                           xfs_uio_end_length(uio));
        !           328: #else
        !           329:     error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uio), NNPFS_DATA_R,
        !           330:                           xfs_uio_end_length(uio));
        !           331: #endif
        !           332:
        !           333:     NNPFSDEB(XDEBVNOPS, ("xfs_read: iovcnt: %d\n", uio->uio_iovcnt));
        !           334:     for (i = 0; i < uio->uio_iovcnt; i++)
        !           335:        NNPFSDEB(XDEBVNOPS, ("  base: %lx len: %lu\n",
        !           336:                           (unsigned long)uio->uio_iov[i].iov_base,
        !           337:                           (unsigned long)uio->uio_iov[i].iov_len));
        !           338:
        !           339:     if (error == 0) {
        !           340:        struct vnode *t = DATA_FROM_VNODE(vp);
        !           341:
        !           342: #ifdef HAVE_FREEBSD_THREAD
        !           343:        xfs_vfs_readlock(t, xfs_uio_to_thread(uio));
        !           344:        xfs_vop_read(t, uio, ioflag, cred, error);
        !           345:        xfs_vfs_unlock(t, xfs_uio_to_thread(uio));
        !           346: #else
        !           347:        xfs_vfs_readlock(t, xfs_uio_to_proc(uio));
        !           348:        xfs_vop_read(t, uio, ioflag, cred, error);
        !           349:        xfs_vfs_unlock(t, xfs_uio_to_proc(uio));
        !           350: #endif
        !           351:     }
        !           352:
        !           353:     NNPFSDEB(XDEBVNOPS, ("xfs_read offset: %lu resid: %lu\n",
        !           354:                       (unsigned long)uio->uio_offset,
        !           355:                       (unsigned long)uio->uio_resid));
        !           356:     NNPFSDEB(XDEBVNOPS, ("xfs_read error: %d\n", error));
        !           357:
        !           358:     return error;
        !           359: }
        !           360:
        !           361: int
        !           362: xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag,
        !           363:                 struct ucred *cred)
        !           364: {
        !           365:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           366:     int error = 0;
        !           367:
        !           368:     NNPFSDEB(XDEBVNOPS, ("xfs_write\n"));
        !           369:
        !           370:     xfs_update_write_cred(xn, cred);
        !           371:
        !           372: #ifdef HAVE_FREEBSD_THREAD
        !           373:     error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_W,
        !           374:                           VNODE_TO_XNODE(vp)->attr.va_size);
        !           375: #else
        !           376:     error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_W,
        !           377:                           VNODE_TO_XNODE(vp)->attr.va_size);
        !           378: #endif
        !           379:
        !           380:     if (error == 0) {
        !           381:        struct vnode *t = DATA_FROM_XNODE(xn);
        !           382:        struct vattr sub_attr;
        !           383:        int error2 = 0;
        !           384:
        !           385:  #ifdef HAVE_FREEBSD_THREAD
        !           386:        xfs_vfs_writelock(t, xfs_uio_to_thread(uiop));
        !           387:        xfs_vop_write(t, uiop, ioflag, cred, error);
        !           388:        VNODE_TO_XNODE(vp)->flags |= NNPFS_DATA_DIRTY;
        !           389:        xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_thread(uiop), error2);
        !           390:  #else
        !           391:        xfs_vfs_writelock(t, xfs_uio_to_proc(uiop));
        !           392:        xfs_vop_write(t, uiop, ioflag, cred, error);
        !           393:        VNODE_TO_XNODE(vp)->flags |= NNPFS_DATA_DIRTY;
        !           394:        xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_proc(uiop), error2);
        !           395:  #endif
        !           396:
        !           397:        if (error2 == 0) {
        !           398:            xn->attr.va_size  = sub_attr.va_size;
        !           399:            xn->attr.va_bytes = sub_attr.va_size;
        !           400:            xn->attr.va_mtime = sub_attr.va_mtime;
        !           401:            xfs_set_vp_size(vp, sub_attr.va_size);
        !           402:            xn->offset = sub_attr.va_size;
        !           403:        }
        !           404: #ifdef HAVE_FREEBSD_THREAD
        !           405:        xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
        !           406: #else
        !           407:        xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
        !           408: #endif
        !           409:     }
        !           410:
        !           411:     return error;
        !           412: }
        !           413:
        !           414: int
        !           415: xfs_getattr_common(struct vnode *vp, struct vattr *vap,
        !           416:                   struct ucred *cred, d_thread_t *p)
        !           417: {
        !           418:     int error = 0;
        !           419:
        !           420:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           421:
        !           422:     NNPFSDEB(XDEBVNOPS, ("xfs_getattr\n"));
        !           423:
        !           424:     error = xfs_attr_valid(vp, cred, p, NNPFS_ATTR_R);
        !           425:     if (error == 0)
        !           426:        *vap = xn->attr;
        !           427:     return error;
        !           428: }
        !           429:
        !           430: int
        !           431: xfs_setattr_common(struct vnode *vp, struct vattr *vap,
        !           432:                   struct ucred *cred, d_thread_t *p)
        !           433: {
        !           434:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !           435:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           436:     int error = 0;
        !           437:
        !           438:     NNPFSDEB(XDEBVNOPS, ("xfs_setattr\n"));
        !           439:
        !           440: #define CHECK_NNPFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A)
        !           441:        if (CHECK_NNPFSATTR(va_mode,(mode_t)) &&
        !           442:            CHECK_NNPFSATTR(va_nlink,(short)) &&
        !           443:            CHECK_NNPFSATTR(va_size,(va_size_t)) &&
        !           444:            CHECK_NNPFSATTR(va_uid,(uid_t)) &&
        !           445:            CHECK_NNPFSATTR(va_gid,(gid_t)) &&
        !           446:            CHECK_NNPFSATTR(va_mtime.tv_sec,(unsigned int)) &&
        !           447:            CHECK_NNPFSATTR(va_fileid,(long)) &&
        !           448:            CHECK_NNPFSATTR(va_type,(enum vtype)))
        !           449:                return 0;               /* Nothing to do */
        !           450: #undef CHECK_NNPFSATTR
        !           451:
        !           452:     if (NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_W)) {
        !           453:        /* Update attributes and mark them dirty. */
        !           454:        VNODE_TO_XNODE(vp)->flags |= NNPFS_ATTR_DIRTY;
        !           455:        error = EINVAL;                /* XXX not yet implemented */
        !           456:        goto done;
        !           457:     } else {
        !           458:        struct xfs_message_putattr msg;
        !           459:
        !           460:        msg.header.opcode = NNPFS_MSG_PUTATTR;
        !           461:        if (cred != NOCRED) {
        !           462:            msg.cred.uid = cred->cr_uid;
        !           463:            msg.cred.pag = xfs_get_pag(cred);
        !           464:        } else {
        !           465:            msg.cred.uid = 0;
        !           466:            msg.cred.pag = NNPFS_ANONYMOUSID;
        !           467:        }
        !           468:        msg.handle = xn->handle;
        !           469:        vattr2xfs_attr(vap, &msg.attr);
        !           470:        if (NNPFS_TOKEN_GOT(xn, NNPFS_DATA_R)) {
        !           471:            if (vp->v_type == VREG) {
        !           472:                if (vap->va_size != (va_size_t)VNOVAL)
        !           473:                    XA_SET_SIZE(&msg.attr, vap->va_size);
        !           474:                else
        !           475:                    XA_SET_SIZE(&msg.attr, xn->attr.va_size);
        !           476: #ifdef __APPLE__
        !           477:                /* XXX needed ? */
        !           478:                if (UBCINFOEXISTS(vp))
        !           479:                    ubc_setsize(vp, msg.attr.xa_size);
        !           480: #endif
        !           481:            }
        !           482:            if (vap->va_mtime.tv_sec != (unsigned int)VNOVAL)
        !           483:                XA_SET_MTIME(&msg.attr, vap->va_mtime.tv_sec);
        !           484:            else
        !           485:                XA_SET_MTIME(&msg.attr, xn->attr.va_mtime.tv_sec);
        !           486:        }
        !           487:
        !           488:        NNPFS_TOKEN_CLEAR(xn, NNPFS_ATTR_VALID, NNPFS_ATTR_MASK);
        !           489:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           490:        if (error == 0)
        !           491:            error = ((struct xfs_message_wakeup *) & msg)->error;
        !           492:     }
        !           493:
        !           494: done:
        !           495:     return error;
        !           496: }
        !           497:
        !           498: static int
        !           499: check_rights (u_char rights, int mode)
        !           500: {
        !           501:     int error = 0;
        !           502:
        !           503:     if (mode & VREAD)
        !           504:        if ((rights & NNPFS_RIGHT_R) == 0)
        !           505:            error = EACCES;
        !           506:     if (mode & VWRITE)
        !           507:        if ((rights & NNPFS_RIGHT_W) == 0)
        !           508:            error = EACCES;
        !           509:     if (mode & VEXEC)
        !           510:        if ((rights & NNPFS_RIGHT_X) == 0)
        !           511:            error = EACCES;
        !           512:     return error;
        !           513: }
        !           514:
        !           515: int
        !           516: xfs_access_common(struct vnode *vp, int mode, struct ucred *cred,
        !           517:                  d_thread_t *p)
        !           518: {
        !           519:     int error = 0;
        !           520:     xfs_pag_t pag = xfs_get_pag(cred);
        !           521:
        !           522:     NNPFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode));
        !           523:
        !           524:     error = xfs_attr_valid(vp, cred, p, NNPFS_ATTR_R);
        !           525:     if (error == 0) {
        !           526:        struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           527:        int i;
        !           528:
        !           529:        error = check_rights (xn->anonrights, mode);
        !           530:
        !           531:        if (error == 0)
        !           532:            goto done;
        !           533:
        !           534:        NNPFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n"));
        !           535:
        !           536:        error = EACCES;         /* default to EACCES if pag isn't in xn->id */
        !           537:
        !           538:        for (i = 0; i < MAXRIGHTS; i++)
        !           539:            if (xn->id[i] == pag) {
        !           540:                error = check_rights (xn->rights[i], mode);
        !           541:                break;
        !           542:            }
        !           543:     }
        !           544:
        !           545: done:
        !           546:     NNPFSDEB(XDEBVNOPS, ("xfs_access(0%o) = %d\n", mode, error));
        !           547:
        !           548:     return error;
        !           549: }
        !           550:
        !           551: int
        !           552: xfs_lookup_common(struct vnode *dvp,
        !           553:                  xfs_componentname *cnp,
        !           554:                  struct vnode **vpp)
        !           555: {
        !           556:     struct xfs_message_getnode msg;
        !           557:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !           558:     struct xfs_node *d = VNODE_TO_XNODE(dvp);
        !           559:     int error = 0;
        !           560: #ifdef HAVE_FREEBSD_THREAD
        !           561:     d_thread_t *proc  = xfs_cnp_to_thread(cnp);
        !           562:     struct ucred *cred = xfs_thread_to_cred(proc);
        !           563: #else
        !           564:     d_thread_t *proc  = xfs_cnp_to_proc(cnp);
        !           565:     struct ucred *cred = xfs_proc_to_cred(proc);
        !           566: #endif
        !           567:
        !           568:     NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: enter\n"));
        !           569:
        !           570:     *vpp = NULL;
        !           571:
        !           572:     if (cnp->cn_namelen >= NNPFS_MAX_NAME)
        !           573:        return ENAMETOOLONG;
        !           574:
        !           575:     if (dvp->v_type != VDIR)
        !           576:        return ENOTDIR;
        !           577:
        !           578:     if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
        !           579:        *vpp = dvp;
        !           580:        VREF(*vpp);
        !           581:        return 0;
        !           582:     }
        !           583:
        !           584:     do {
        !           585:        xfs_vop_access(dvp, VEXEC, cred, proc, error);
        !           586:        if (error != 0)
        !           587:            goto done;
        !           588:
        !           589:        NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: dvp = %lx\n",
        !           590:                           (unsigned long) dvp));
        !           591:        NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: cnp = %lx, "
        !           592:                           "cnp->cn_nameiop = %d\n",
        !           593:                           (unsigned long) cnp, (int)cnp->cn_nameiop));
        !           594:
        !           595:
        !           596:        error = xfs_dnlc_lookup(dvp, cnp, vpp);
        !           597:        if (error == 0) {
        !           598:
        !           599:            /*
        !           600:             * Doesn't quite work.
        !           601:             */
        !           602:
        !           603: #if 0
        !           604:            if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
        !           605:                && (cnp->cn_flags & ISLASTCN)) {
        !           606:                error = EJUSTRETURN;
        !           607:                goto done;
        !           608:            }
        !           609: #endif
        !           610:
        !           611:            msg.header.opcode = NNPFS_MSG_GETNODE;
        !           612:            if (cnp->cn_cred != NOCRED) {
        !           613:                msg.cred.uid = cnp->cn_cred->cr_uid;
        !           614:                msg.cred.pag = xfs_get_pag(cnp->cn_cred);
        !           615:            } else {
        !           616:                msg.cred.uid = 0;
        !           617:                msg.cred.pag = NNPFS_ANONYMOUSID;
        !           618:            }
        !           619:            msg.parent_handle = d->handle;
        !           620:            memcpy(msg.name, cnp->cn_nameptr, cnp->cn_namelen);
        !           621:            msg.name[cnp->cn_namelen] = '\0';
        !           622:            error = xfs_message_rpc(xfsp->fd, &msg.header,
        !           623:                                    sizeof(msg), proc);
        !           624:            if (error == 0)
        !           625:                error = ((struct xfs_message_wakeup *) & msg)->error;
        !           626:            if(error == ENOENT && cnp->cn_nameiop != CREATE) {
        !           627:                NNPFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %lx (%s, %ld)\n",
        !           628:                                   (unsigned long)dvp,
        !           629:                                   cnp->cn_nameptr, cnp->cn_namelen));
        !           630:                xfs_dnlc_enter (dvp, cnp, NULL);
        !           631:            }
        !           632:        } else if (error == -1) {
        !           633:            error = 0;
        !           634:            goto done;
        !           635:        }
        !           636:     } while (error == 0);
        !           637:
        !           638: done:
        !           639:     NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: return error = %d\n", error));
        !           640:     return error;
        !           641: }
        !           642:
        !           643: int
        !           644: xfs_create_common(struct vnode *dvp,
        !           645:                  const char *name,
        !           646:                  struct vattr *vap,
        !           647:                  struct ucred *cred,
        !           648:                  d_thread_t *p)
        !           649: {
        !           650:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !           651:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           652:     int error = 0;
        !           653:
        !           654:     NNPFSDEB(XDEBVNOPS, ("xfs_create: (%lx, %s)\n",
        !           655:                       (unsigned long)dvp, name));
        !           656:     {
        !           657:        struct xfs_message_create msg;
        !           658:
        !           659:        msg.header.opcode = NNPFS_MSG_CREATE;
        !           660:        msg.parent_handle = xn->handle;
        !           661:        if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
        !           662:            return ENAMETOOLONG;
        !           663:        vattr2xfs_attr(vap, &msg.attr);
        !           664:
        !           665:        msg.mode = 0;                  /* XXX - mode */
        !           666:        if (cred != NOCRED) {
        !           667:            msg.cred.uid = cred->cr_uid;
        !           668:            msg.cred.pag = xfs_get_pag(cred);
        !           669:        } else {
        !           670:            msg.cred.uid = 0;
        !           671:            msg.cred.pag = NNPFS_ANONYMOUSID;
        !           672:        }
        !           673:
        !           674:
        !           675:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           676:
        !           677:        if (error == 0)
        !           678:            error = ((struct xfs_message_wakeup *) & msg)->error;
        !           679:     }
        !           680:
        !           681: #if 0
        !           682:     if (error == EEXIST)
        !           683:        error = 0;
        !           684: #endif
        !           685:
        !           686:     return error;
        !           687: }
        !           688:
        !           689: int
        !           690: xfs_remove_common(struct vnode *dvp,
        !           691:                  struct vnode *vp,
        !           692:                  const char *name,
        !           693:                  struct ucred *cred,
        !           694:                  d_thread_t *p)
        !           695: {
        !           696:     struct xfs *xfsp  = NNPFS_FROM_VNODE(dvp);
        !           697:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           698:     struct xfs_message_remove msg;
        !           699:     int error;
        !           700:
        !           701:     NNPFSDEB(XDEBVNOPS, ("xfs_remove: %s\n", name));
        !           702:
        !           703:     msg.header.opcode = NNPFS_MSG_REMOVE;
        !           704:     msg.parent_handle = xn->handle;
        !           705:     msg.cred.uid = cred->cr_uid;
        !           706:     msg.cred.pag = xfs_get_pag(cred);
        !           707:
        !           708:     if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
        !           709:        error = ENAMETOOLONG;
        !           710:     else
        !           711:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           712:     if (error == 0)
        !           713:        error = ((struct xfs_message_wakeup *) &msg)->error;
        !           714:
        !           715:     if (error == 0)
        !           716:        xfs_dnlc_purge (vp);
        !           717:
        !           718:     return error;
        !           719: }
        !           720:
        !           721: int
        !           722: xfs_rename_common(struct vnode *fdvp,
        !           723:                  struct vnode *fvp,
        !           724:                  const char *fname,
        !           725:                  struct vnode *tdvp,
        !           726:                  struct vnode *tvp,
        !           727:                  const char *tname,
        !           728:                  struct ucred *cred,
        !           729:                  d_thread_t *p)
        !           730: {
        !           731:     struct xfs *xfsp = NNPFS_FROM_VNODE(fdvp);
        !           732:     int error;
        !           733:
        !           734:     NNPFSDEB(XDEBVNOPS, ("xfs_rename: %s %s\n", fname, tname));
        !           735:
        !           736:     if ((fvp->v_mount != tdvp->v_mount)
        !           737:        || (tvp && (fvp->v_mount != tvp->v_mount))) {
        !           738:        return  EXDEV;
        !           739:     }
        !           740:
        !           741:     {
        !           742:        struct xfs_message_rename msg;
        !           743:
        !           744:        msg.header.opcode = NNPFS_MSG_RENAME;
        !           745:        msg.old_parent_handle = VNODE_TO_XNODE(fdvp)->handle;
        !           746:        if (strlcpy(msg.old_name, fname, sizeof(msg.old_name)) >= NNPFS_MAX_NAME)
        !           747:            return ENAMETOOLONG;
        !           748:        msg.new_parent_handle = VNODE_TO_XNODE(tdvp)->handle;
        !           749:        if (strlcpy(msg.new_name, tname, sizeof(msg.new_name)) >= NNPFS_MAX_NAME)
        !           750:            return ENAMETOOLONG;
        !           751:        msg.cred.uid = cred->cr_uid;
        !           752:        msg.cred.pag = xfs_get_pag(cred);
        !           753:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           754:        if (error == 0)
        !           755:            error = ((struct xfs_message_wakeup *) &msg)->error;
        !           756:
        !           757:     }
        !           758:
        !           759:     NNPFSDEB(XDEBVNOPS, ("xfs_rename: error = %d\n", error));
        !           760:
        !           761:     return error;
        !           762: }
        !           763:
        !           764: int
        !           765: xfs_mkdir_common(struct vnode *dvp,
        !           766:                 const char *name,
        !           767:                 struct vattr *vap,
        !           768:                 struct ucred *cred,
        !           769:                 d_thread_t *p)
        !           770: {
        !           771:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !           772:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           773:     int error = 0;
        !           774:
        !           775:     NNPFSDEB(XDEBVNOPS, ("xfs_mkdir: %s\n", name));
        !           776:     {
        !           777:        struct xfs_message_mkdir msg;
        !           778:
        !           779:        msg.header.opcode = NNPFS_MSG_MKDIR;
        !           780:        msg.parent_handle = xn->handle;
        !           781:        if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
        !           782:            return ENAMETOOLONG;
        !           783:        vattr2xfs_attr(vap, &msg.attr);
        !           784:        if (cred != NOCRED) {
        !           785:            msg.cred.uid = cred->cr_uid;
        !           786:            msg.cred.pag = xfs_get_pag(cred);
        !           787:        } else {
        !           788:            msg.cred.uid = 0;
        !           789:            msg.cred.pag = NNPFS_ANONYMOUSID;
        !           790:        }
        !           791:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           792:        if (error == 0)
        !           793:            error = ((struct xfs_message_wakeup *) & msg)->error;
        !           794:     }
        !           795:
        !           796:     return error;
        !           797: }
        !           798:
        !           799: int
        !           800: xfs_rmdir_common(struct vnode *dvp,
        !           801:                 struct vnode *vp,
        !           802:                 const char *name,
        !           803:                 struct ucred *cred,
        !           804:                 d_thread_t *p)
        !           805: {
        !           806:     struct xfs *xfsp  = NNPFS_FROM_VNODE(dvp);
        !           807:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           808:     struct xfs_message_rmdir msg;
        !           809:     int error;
        !           810:
        !           811:     NNPFSDEB(XDEBVNOPS, ("xfs_rmdir: %s\n", name));
        !           812:
        !           813:     msg.header.opcode = NNPFS_MSG_RMDIR;
        !           814:     msg.parent_handle = xn->handle;
        !           815:     msg.cred.uid = cred->cr_uid;
        !           816:     msg.cred.pag = xfs_get_pag(cred);
        !           817:     if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
        !           818:        error = ENAMETOOLONG;
        !           819:     else
        !           820:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           821:     if (error == 0)
        !           822:        error = ((struct xfs_message_wakeup *) &msg)->error;
        !           823:
        !           824:     if (error == 0)
        !           825:        xfs_dnlc_purge (vp);
        !           826:
        !           827:     NNPFSDEB(XDEBVNOPS, ("xfs_rmdir error: %d\n", error));
        !           828:
        !           829:     return error;
        !           830: }
        !           831:
        !           832: int
        !           833: xfs_readdir_common(struct vnode *vp,
        !           834:                   struct uio *uiop,
        !           835:                   struct ucred *cred,
        !           836:                   d_thread_t *p,
        !           837:                   int *eofflag)
        !           838: {
        !           839:     int error = 0;
        !           840:
        !           841:     NNPFSDEB(XDEBVNOPS, ("xfs_readdir\n"));
        !           842:
        !           843:     if(eofflag)
        !           844:        *eofflag = 0;
        !           845: #ifdef HAVE_FREEBSD_THREAD
        !           846:     error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_R,
        !           847:                           xfs_uio_end_length(uiop));
        !           848: #else
        !           849:     error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_R,
        !           850:                           xfs_uio_end_length(uiop));
        !           851: #endif
        !           852:     if (error == 0) {
        !           853:        struct vnode *t = DATA_FROM_VNODE(vp);
        !           854:
        !           855: #ifdef HAVE_FREEBSD_THREAD
        !           856:        xfs_vfs_readlock(t, xfs_uio_to_thread(uiop));
        !           857: #else
        !           858:        xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
        !           859: #endif
        !           860:        xfs_vop_read(t, uiop, 0, cred, error);
        !           861:        if (eofflag) {
        !           862:            struct vattr t_attr;
        !           863:            int error2;
        !           864:
        !           865: #ifdef HAVE_FREEBSD_THREAD
        !           866:            xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_thread(uiop), error2);
        !           867: #else
        !           868:            xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_proc(uiop), error2);
        !           869: #endif
        !           870:            if (error2 == 0)
        !           871:                *eofflag = t_attr.va_size <= uiop->uio_offset;
        !           872:        }
        !           873: #ifdef HAVE_FREEBSD_THREAD
        !           874:        xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
        !           875: #else
        !           876:        xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
        !           877: #endif
        !           878:     }
        !           879:     return error;
        !           880: }
        !           881:
        !           882: int
        !           883: xfs_link_common(struct vnode *dvp,
        !           884:                struct vnode *vp,
        !           885:                const char *name,
        !           886:                struct ucred *cred,
        !           887:                d_thread_t *p)
        !           888: {
        !           889:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !           890:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           891:     struct xfs_node *xn2 = VNODE_TO_XNODE(vp);
        !           892:     struct xfs_message_link msg;
        !           893:     int error = 0;
        !           894:
        !           895:     NNPFSDEB(XDEBVNOPS, ("xfs_link: %s\n", name));
        !           896:
        !           897:     msg.header.opcode = NNPFS_MSG_LINK;
        !           898:     msg.parent_handle = xn->handle;
        !           899:     msg.from_handle   = xn2->handle;
        !           900:     if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
        !           901:        return ENAMETOOLONG;
        !           902:     msg.cred.uid = cred->cr_uid;
        !           903:     msg.cred.pag = xfs_get_pag(cred);
        !           904:
        !           905:     error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !           906:     if (error == 0)
        !           907:        error = ((struct xfs_message_wakeup *) & msg)->error;
        !           908:
        !           909:     return error;
        !           910: }
        !           911:
        !           912: int
        !           913: xfs_symlink_common(struct vnode *dvp,
        !           914:                   struct vnode **vpp,
        !           915:                   xfs_componentname *cnp,
        !           916:                   struct vattr *vap,
        !           917:                   char *target)
        !           918: {
        !           919:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !           920:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !           921: #ifdef HAVE_FREEBSD_THREAD
        !           922:     d_thread_t *proc  = xfs_cnp_to_thread(cnp);
        !           923:     struct ucred *cred = xfs_thread_to_cred(proc);
        !           924: #else
        !           925:     d_thread_t *proc  = xfs_cnp_to_proc(cnp);
        !           926:     struct ucred *cred = xfs_proc_to_cred(proc);
        !           927: #endif
        !           928:     struct xfs_message_symlink *msg = NULL;
        !           929:     const char *name = cnp->cn_nameptr;
        !           930:     int error = 0;
        !           931:
        !           932:     NNPFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name));
        !           933:
        !           934:     msg = malloc(sizeof(struct xfs_message_symlink), M_TEMP, M_WAITOK);
        !           935:     if (msg == NULL) {
        !           936:         error = ENOMEM;
        !           937:        goto done;
        !           938:     }
        !           939:     memset(msg, 0, sizeof(*msg));
        !           940:
        !           941:     msg->header.opcode = NNPFS_MSG_SYMLINK;
        !           942:     msg->parent_handle = xn->handle;
        !           943:     vattr2xfs_attr(vap, &msg->attr);
        !           944:     msg->cred.uid = cred->cr_uid;
        !           945:     msg->cred.pag = xfs_get_pag(cred);
        !           946:     if (strlcpy (msg->contents, target, sizeof(msg->contents)) >= NNPFS_MAX_SYMLINK_CONTENT) {
        !           947:        error = ENAMETOOLONG;
        !           948:        goto done;
        !           949:     }
        !           950:     if (strlcpy(msg->name, name, sizeof(msg->name)) >= NNPFS_MAX_NAME) {
        !           951:        error = ENAMETOOLONG;
        !           952:        goto done;
        !           953:     }
        !           954:     error = xfs_message_rpc(xfsp->fd, &msg->header, sizeof(*msg), proc);
        !           955:     if (error == 0)
        !           956:        error = ((struct xfs_message_wakeup *) msg)->error;
        !           957:
        !           958:  done:
        !           959:     free(msg, M_TEMP);
        !           960:     return error;
        !           961: }
        !           962:
        !           963: int
        !           964: xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred)
        !           965: {
        !           966:     int error = 0;
        !           967:
        !           968:     NNPFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
        !           969:
        !           970: #ifdef HAVE_FREEBSD_THREAD
        !           971:     error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_R,
        !           972:                           xfs_uio_end_length(uiop));
        !           973: #else
        !           974:     error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_R,
        !           975:                           xfs_uio_end_length(uiop));
        !           976: #endif
        !           977:     if (error == 0) {
        !           978:        struct vnode *t = DATA_FROM_VNODE(vp);
        !           979:
        !           980: #ifdef HAVE_FREEBSD_THREAD
        !           981:        xfs_vfs_readlock(t, xfs_uio_to_thread(uiop));
        !           982:        xfs_vop_read(t, uiop, 0, cred, error);
        !           983:        xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
        !           984: #else
        !           985:        xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
        !           986:        xfs_vop_read(t, uiop, 0, cred, error);
        !           987:        xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
        !           988: #endif
        !           989:     }
        !           990:     return error;
        !           991: }
        !           992:
        !           993: int
        !           994: xfs_inactive_common(struct vnode *vp, d_thread_t *p)
        !           995: {
        !           996:     int error;
        !           997:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !           998:
        !           999:     NNPFSDEB(XDEBVNOPS, ("xfs_inactive, %lx\n",
        !          1000:                       (unsigned long)vp));
        !          1001:
        !          1002:     /*
        !          1003:      * This seems rather bogus, but sometimes we get an already
        !          1004:      * cleaned node to be made inactive.  Just ignoring it seems safe.
        !          1005:      */
        !          1006:
        !          1007:     if (xn == NULL) {
        !          1008:        NNPFSDEB(XDEBVNOPS, ("xfs_inactive: clean node\n"));
        !          1009:        return 0;
        !          1010:     }
        !          1011:
        !          1012:     /* xn->wr_cred not set -> NOCRED */
        !          1013:
        !          1014:     if (vp->v_type == VREG)
        !          1015:        xfs_pushdirty(vp, xn->wr_cred, p);
        !          1016:
        !          1017:     error = xfs_fsync_common(vp, xn->wr_cred, /* XXX */ 0, p);
        !          1018:     if (error) {
        !          1019:        printf ("xfs_inactive: failed writing back data: %d\n", error);
        !          1020:        xn->flags &= ~NNPFS_DATA_DIRTY;
        !          1021:     }
        !          1022:
        !          1023:     /* If this node is no longer valid, recycle immediately. */
        !          1024:     if (!NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_R | NNPFS_ATTR_W)
        !          1025:        || (xn->flags & NNPFS_STALE) == NNPFS_STALE)
        !          1026:     {
        !          1027: #ifndef __osf__
        !          1028:        xfs_vfs_unlock(vp, p);
        !          1029:         NNPFSDEB(XDEBVNOPS, ("xfs_inactive: vrecycle\n"));
        !          1030:         vrecycle(vp, p);
        !          1031: #else /* __osf__ */
        !          1032:        NNPFSDEB(XDEBVNOPS, ("xfs_inactive: vp = %lx vp->v_usecount= %d\n",
        !          1033:                             (unsigned long)vp, vp?vp->v_usecount:0));
        !          1034: #endif /* __osf__ */
        !          1035:     } else {
        !          1036: #ifndef __osf__
        !          1037:        xfs_vfs_unlock(vp, p);
        !          1038: #endif
        !          1039:        xn->flags &= ~NNPFS_STALE;
        !          1040:     }
        !          1041:
        !          1042:     NNPFSDEB(XDEBVNOPS, ("return: xfs_inactive\n"));
        !          1043:
        !          1044:     return 0;
        !          1045: }
        !          1046:
        !          1047: int
        !          1048: xfs_reclaim_common(struct vnode *vp)
        !          1049: {
        !          1050:     struct xfs_message_inactivenode msg;
        !          1051:     struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
        !          1052:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !          1053:
        !          1054:     NNPFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx\n",
        !          1055:                       (unsigned long)vp));
        !          1056:
        !          1057:     NNPFS_TOKEN_CLEAR(xn,
        !          1058:                    ~0,
        !          1059:                    NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
        !          1060:                    NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
        !          1061:     /* Release, data if we still have it. */
        !          1062:     if (DATA_FROM_XNODE(xn) != 0) {
        !          1063:         vrele(DATA_FROM_XNODE(xn));
        !          1064:        DATA_FROM_XNODE(xn) = 0;
        !          1065:     }
        !          1066:
        !          1067:     xfs_remove_node(&xfsp->nodehead, xn);
        !          1068:
        !          1069:     msg.header.opcode = NNPFS_MSG_INACTIVENODE;
        !          1070:     msg.handle = xn->handle;
        !          1071:     msg.flag   = NNPFS_NOREFS | NNPFS_DELETE;
        !          1072:     xfs_message_send(xfsp->fd, &msg.header, sizeof(msg));
        !          1073:
        !          1074:     xfs_dnlc_purge(vp);
        !          1075:     free_xfs_node(xn);
        !          1076:     return 0;
        !          1077: }
        !          1078:
        !          1079: /*
        !          1080:  *
        !          1081:  */
        !          1082:
        !          1083: #if 0
        !          1084:
        !          1085: int
        !          1086: xfs_advlock_common(struct vnode *dvp,
        !          1087:                   int locktype,
        !          1088:                   unsigned long lockid, /* XXX this good ? */
        !          1089:                   struct ucred *cred)
        !          1090: {
        !          1091:     struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
        !          1092:     struct xfs_node *xn = VNODE_TO_XNODE(dvp);
        !          1093:     int error = 0;
        !          1094:
        !          1095:     NNPFSDEB(XDEBVNOPS, ("xfs_advlock\n"));
        !          1096:     {
        !          1097:        struct xfs_message_advlock msg;
        !          1098:
        !          1099:        msg.header.opcode = NNPFS_MSG_ADVLOCK;
        !          1100:        msg.handle = xn->handle;
        !          1101:        msg.locktype = locktype;
        !          1102:        msg.lockid = lockid;
        !          1103:
        !          1104:        if (cred != NOCRED) {
        !          1105:            msg.cred.uid = cred->cr_uid;
        !          1106:            msg.cred.pag = xfs_get_pag(cred);
        !          1107:        } else {
        !          1108:            msg.cred.uid = 0;
        !          1109:            msg.cred.pag = NNPFS_ANONYMOUSID;
        !          1110:        }
        !          1111:        error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
        !          1112:        if (error == 0)
        !          1113:            error = ((struct xfs_message_wakeup *) & msg)->error;
        !          1114:     }
        !          1115:
        !          1116:     if (error == 0) {
        !          1117:
        !          1118:        /* sleep until woken */
        !          1119:
        !          1120:     } else {
        !          1121:
        !          1122:        /* die */
        !          1123:     }
        !          1124:
        !          1125:     return error;
        !          1126: }
        !          1127:
        !          1128: #endif
        !          1129:
        !          1130: /*
        !          1131:  *
        !          1132:  */
        !          1133:
        !          1134: void
        !          1135: xfs_printnode_common (struct vnode *vp)
        !          1136: {
        !          1137:     struct xfs_node *xn = VNODE_TO_XNODE(vp);
        !          1138:
        !          1139:     printf ("xnode: fid: %d.%d.%d.%d\n",
        !          1140:            xn->handle.a, xn->handle.b, xn->handle.c, xn->handle.d);
        !          1141:     printf ("\tattr: %svalid\n",
        !          1142:            NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_VALID) ? "": "in");
        !          1143:     printf ("\tdata: %svalid\n",
        !          1144:            NNPFS_TOKEN_GOT(xn, NNPFS_DATA_VALID) ? "": "in");
        !          1145:     printf ("\tflags: 0x%x\n", xn->flags);
        !          1146:     printf ("\toffset: %d\n", xn->offset);
        !          1147: }

CVSweb