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