Annotation of sys/xfs/xfs_message.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
! 3: * (Royal Institute of Technology, Stockholm, Sweden).
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: *
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: *
! 17: * 3. Neither the name of the Institute nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34: #include <xfs/xfs_locl.h>
! 35: #include <xfs/xfs_deb.h>
! 36: #include <xfs/xfs_fs.h>
! 37: #include <xfs/xfs_message.h>
! 38: #include <xfs/xfs_msg_locl.h>
! 39: #include <xfs/xfs_syscalls.h>
! 40: #include <xfs/xfs_vfsops.h>
! 41: #include <xfs/xfs_vnodeops.h>
! 42: #include <xfs/xfs_dev.h>
! 43:
! 44: RCSID("$arla: xfs_message.c,v 1.84 2003/06/02 18:25:20 lha Exp $");
! 45:
! 46: static void
! 47: send_inactive_node(int fd, xfs_handle *handle)
! 48: {
! 49: struct xfs_message_inactivenode msg;
! 50:
! 51: msg.header.opcode = NNPFS_MSG_INACTIVENODE;
! 52: msg.handle = *handle;
! 53: msg.flag = NNPFS_NOREFS | NNPFS_DELETE;
! 54: xfs_message_send(fd, &msg.header, sizeof(msg));
! 55: }
! 56:
! 57:
! 58: int
! 59: xfs_message_installroot(int fd,
! 60: struct xfs_message_installroot * message,
! 61: u_int size,
! 62: d_thread_t *p)
! 63: {
! 64: int error = 0;
! 65:
! 66: NNPFSDEB(XDEBMSG, ("xfs_message_installroot (%d,%d,%d,%d)\n",
! 67: message->node.handle.a,
! 68: message->node.handle.b,
! 69: message->node.handle.c,
! 70: message->node.handle.d));
! 71:
! 72: if (xfs[fd].root != NULL) {
! 73: printf("NNPFS PANIC WARNING! xfs_message_installroot: called again!\n");
! 74: error = EBUSY;
! 75: } else {
! 76: error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root, p);
! 77: if (error)
! 78: return error;
! 79: NNPFS_MAKE_VROOT(xfs[fd].root->vn);
! 80: }
! 81: return error;
! 82: }
! 83:
! 84: int
! 85: xfs_message_installnode(int fd,
! 86: struct xfs_message_installnode * message,
! 87: u_int size,
! 88: d_thread_t *p)
! 89: {
! 90: int error = 0;
! 91: struct xfs_node *n, *dp;
! 92:
! 93: NNPFSDEB(XDEBMSG, ("xfs_message_installnode (%d,%d,%d,%d)\n",
! 94: message->node.handle.a,
! 95: message->node.handle.b,
! 96: message->node.handle.c,
! 97: message->node.handle.d));
! 98:
! 99: retry:
! 100: dp = xfs_node_find(&xfs[fd].nodehead, &message->parent_handle);
! 101: if (dp) {
! 102: struct vnode *t_vnode = XNODE_TO_VNODE(dp);
! 103:
! 104: NNPFSDEB(XDEBMSG, ("xfs_message_installnode: t_vnode = %lx\n",
! 105: (unsigned long)t_vnode));
! 106:
! 107: if (xfs_do_vget(t_vnode, 0 /* LK_SHARED */, p))
! 108: goto retry;
! 109:
! 110: error = new_xfs_node(&xfs[fd], &message->node, &n, p);
! 111: if (error) {
! 112: vrele (t_vnode);
! 113: return error;
! 114: }
! 115:
! 116: xfs_dnlc_enter_name(t_vnode,
! 117: message->name,
! 118: XNODE_TO_VNODE(n));
! 119: vrele (XNODE_TO_VNODE(n));
! 120: vrele (t_vnode);
! 121: } else {
! 122: printf("NNPFS PANIC WARNING! xfs_message_installnode: no parent\n");
! 123: error = ENOENT;
! 124: }
! 125: NNPFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error));
! 126:
! 127: return error;
! 128: }
! 129:
! 130: int
! 131: xfs_message_installattr(int fd,
! 132: struct xfs_message_installattr * message,
! 133: u_int size,
! 134: d_thread_t *p)
! 135: {
! 136: int error = 0;
! 137: struct xfs_node *t;
! 138:
! 139: NNPFSDEB(XDEBMSG, ("xfs_message_installattr (%d,%d,%d,%d) \n",
! 140: message->node.handle.a,
! 141: message->node.handle.b,
! 142: message->node.handle.c,
! 143: message->node.handle.d));
! 144:
! 145: t = xfs_node_find(&xfs[fd].nodehead, &message->node.handle);
! 146: if (t != 0) {
! 147: t->tokens = message->node.tokens;
! 148: if ((t->tokens & NNPFS_DATA_MASK) && DATA_FROM_XNODE(t) == NULL) {
! 149: printf ("xfs_message_installattr: tokens and no data\n");
! 150: t->tokens &= ~NNPFS_DATA_MASK;
! 151: }
! 152: xfs_attr2vattr(&message->node.attr, &t->attr, 0);
! 153: if ((t->flags & NNPFS_VMOPEN) == 0)
! 154: xfs_set_vp_size(XNODE_TO_VNODE(t), t->attr.va_size);
! 155: bcopy(message->node.id, t->id, sizeof(t->id));
! 156: bcopy(message->node.rights, t->rights, sizeof(t->rights));
! 157: t->anonrights = message->node.anonrights;
! 158: } else {
! 159: NNPFSDEB(XDEBMSG, ("xfs_message_installattr: no such node\n"));
! 160: }
! 161:
! 162: return error;
! 163: }
! 164:
! 165: int
! 166: xfs_message_installdata(int fd,
! 167: struct xfs_message_installdata * message,
! 168: u_int size,
! 169: d_thread_t *p)
! 170: {
! 171: struct xfs_node *t;
! 172: int error = 0;
! 173:
! 174: NNPFSDEB(XDEBMSG, ("xfs_message_installdata (%d,%d,%d,%d)\n",
! 175: message->node.handle.a,
! 176: message->node.handle.b,
! 177: message->node.handle.c,
! 178: message->node.handle.d));
! 179:
! 180: retry:
! 181: t = xfs_node_find(&xfs[fd].nodehead, &message->node.handle);
! 182: if (t != NULL) {
! 183: struct xfs_fhandle_t *fh =
! 184: (struct xfs_fhandle_t *)&message->cache_handle;
! 185: struct vnode *t_vnode = XNODE_TO_VNODE(t);
! 186: struct vnode *vp;
! 187:
! 188: message->cache_name[sizeof(message->cache_name)-1] = '\0';
! 189: NNPFSDEB(XDEBMSG, ("cache_name = '%s'\n", message->cache_name));
! 190:
! 191: if (xfs_do_vget(t_vnode, 0 /* LK_SHARED */, p))
! 192: goto retry;
! 193:
! 194: if (message->flag & NNPFS_ID_HANDLE_VALID) {
! 195: error = xfs_fhlookup (p, fh, &vp);
! 196: } else {
! 197: error = EINVAL;
! 198: }
! 199: if (error != 0) {
! 200: #ifdef __osf__
! 201: struct nameidata *ndp = &u.u_nd;
! 202: #else
! 203: struct nameidata nd;
! 204: struct nameidata *ndp = &nd;
! 205: #endif
! 206:
! 207: NNPFSDEB(XDEBMSG,
! 208: ("xfs_message_installdata: fhlookup failed: %d, "
! 209: "opening by name\n", error));
! 210:
! 211: NDINIT(ndp, LOOKUP, FOLLOW | NNPFS_LOCKLEAF, UIO_SYSSPACE,
! 212: message->cache_name, p);
! 213: error = namei(ndp);
! 214: vp = ndp->ni_vp;
! 215: }
! 216:
! 217: if (error == 0) {
! 218: #ifndef __osf__
! 219: xfs_vfs_unlock(vp, p);
! 220: #endif
! 221: if (DATA_FROM_XNODE(t))
! 222: vrele(DATA_FROM_XNODE(t));
! 223: DATA_FROM_XNODE(t) = vp;
! 224:
! 225: NNPFSDEB(XDEBMSG, ("xfs_message_installdata: t = %lx;"
! 226: " tokens = %x\n",
! 227: (unsigned long)t, message->node.tokens));
! 228:
! 229: t->tokens = message->node.tokens;
! 230: xfs_attr2vattr(&message->node.attr, &t->attr, 1);
! 231: if ((t->flags & NNPFS_VMOPEN) == 0)
! 232: xfs_set_vp_size(XNODE_TO_VNODE(t), t->attr.va_size);
! 233: if (XNODE_TO_VNODE(t)->v_type == VDIR
! 234: && (message->flag & NNPFS_ID_INVALID_DNLC))
! 235: xfs_dnlc_purge (XNODE_TO_VNODE(t));
! 236: bcopy(message->node.id, t->id, sizeof(t->id));
! 237: bcopy(message->node.rights, t->rights, sizeof(t->rights));
! 238: t->anonrights = message->node.anonrights;
! 239: t->offset = message->offset;
! 240: #if 0
! 241: if (message->flag & NNPFS_ID_AFSDIR)
! 242: t->flags |= NNPFS_AFSDIR;
! 243: #endif
! 244: } else {
! 245: printf("NNPFS PANIC WARNING! xfs_message_installdata failed!\n");
! 246: printf("Reason: lookup failed on cache file '%s', error = %d\n",
! 247: message->cache_name, error);
! 248: }
! 249: vrele (t_vnode);
! 250: } else {
! 251: printf("NNPFS PANIC WARNING! xfs_message_installdata failed\n");
! 252: printf("Reason: No node to install the data into!\n");
! 253: error = ENOENT;
! 254: }
! 255:
! 256: return error;
! 257: }
! 258:
! 259: #ifdef __osf__
! 260: #define xfs_writecount v_wrcnt
! 261: #else
! 262: #define xfs_writecount v_writecount
! 263: #endif
! 264:
! 265: int
! 266: xfs_message_invalidnode(int fd,
! 267: struct xfs_message_invalidnode * message,
! 268: u_int size,
! 269: d_thread_t *p)
! 270: {
! 271: int error = 0;
! 272: struct xfs_node *t;
! 273:
! 274: NNPFSDEB(XDEBMSG, ("xfs_message_invalidnode (%d,%d,%d,%d)\n",
! 275: message->handle.a,
! 276: message->handle.b,
! 277: message->handle.c,
! 278: message->handle.d));
! 279:
! 280: #ifdef __APPLE__
! 281: retry:
! 282: #endif
! 283: t = xfs_node_find(&xfs[fd].nodehead, &message->handle);
! 284: if (t != 0) {
! 285: struct vnode *vp = XNODE_TO_VNODE(t);
! 286:
! 287: /* If open for writing, return immediately. Last close:er wins! */
! 288: if (vp->v_usecount >= 0 && vp->xfs_writecount >= 1)
! 289: return 0;
! 290:
! 291: #ifdef __FreeBSD__
! 292: {
! 293: vm_object_t obj = vp->v_object;
! 294:
! 295: if (obj != NULL
! 296: && (obj->ref_count != 0
! 297: #ifdef OBJ_MIGHTBEDIRTY
! 298: || (obj->flags & OBJ_MIGHTBEDIRTY) != 0
! 299: #endif
! 300: ))
! 301: return 0;
! 302:
! 303: }
! 304: #endif /* __FreeBSD__ */
! 305:
! 306: /* If node is in use, mark as stale */
! 307: if (vp->v_usecount > 0 && vp->v_type != VDIR) {
! 308: #ifdef __APPLE__
! 309: if (vget(vp, 0, p))
! 310: goto retry;
! 311:
! 312: if (UBCISVALID(vp) && !ubc_isinuse(vp, 1)) {
! 313: ubc_setsize(vp, 0);
! 314: vrele(vp);
! 315: } else {
! 316: vrele(vp);
! 317: t->flags |= NNPFS_STALE;
! 318: return 0;
! 319: }
! 320: #else
! 321: t->flags |= NNPFS_STALE;
! 322: return 0;
! 323: #endif
! 324: }
! 325:
! 326: if (DATA_FROM_XNODE(t)) {
! 327: vrele(DATA_FROM_XNODE(t));
! 328: DATA_FROM_XNODE(t) = (struct vnode *) 0;
! 329: }
! 330: NNPFS_TOKEN_CLEAR(t, ~0,
! 331: NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
! 332: NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
! 333: /* Dir changed, must invalidate DNLC. */
! 334: if (vp->v_type == VDIR)
! 335: xfs_dnlc_purge(vp);
! 336: if (vp->v_usecount == 0) {
! 337: #ifndef __osf__
! 338: NNPFSDEB(XDEBVNOPS, ("xfs_message_invalidnode: vrecycle\n"));
! 339: vrecycle(vp, p);
! 340: #else
! 341: /* XXX */
! 342: #endif /* __osf__ */
! 343: }
! 344: } else {
! 345: NNPFSDEB(XDEBMSG, ("xfs_message_invalidnode: no such node\n"));
! 346: send_inactive_node(fd, &message->handle);
! 347: error = ENOENT;
! 348: }
! 349:
! 350: return error;
! 351: }
! 352:
! 353: int
! 354: xfs_message_updatefid(int fd,
! 355: struct xfs_message_updatefid * message,
! 356: u_int size,
! 357: d_thread_t *p)
! 358: {
! 359: int error = 0;
! 360:
! 361: NNPFSDEB(XDEBMSG, ("xfs_message_updatefid (%d,%d,%d,%d) (%d,%d,%d,%d)\n",
! 362: message->old_handle.a,
! 363: message->old_handle.b,
! 364: message->old_handle.c,
! 365: message->old_handle.d,
! 366: message->new_handle.a,
! 367: message->new_handle.b,
! 368: message->new_handle.c,
! 369: message->new_handle.d));
! 370:
! 371: error = xfs_update_handle(&xfs[fd].nodehead,
! 372: &message->old_handle,
! 373: &message->new_handle);
! 374: if (error)
! 375: printf ("NNPFS PANIC WARNING! xfs_message_updatefid: %d\n", error);
! 376: return error;
! 377: }
! 378:
! 379: #if __osf__
! 380:
! 381: /*
! 382: * Try to clean out nodes for the userland daemon
! 383: */
! 384:
! 385: static void
! 386: gc_vnode (struct vnode *vp,
! 387: d_thread_t *p)
! 388: {
! 389: /* This node is on the freelist */
! 390: if (vp->v_usecount <= 0) {
! 391:
! 392: /* DIAGNOSTIC */
! 393: if (vp->v_usecount < 0) {
! 394: vprint("vrele: bad ref count", vp);
! 395: panic("vrele: ref cnt");
! 396: }
! 397:
! 398: NNPFSDEB(XDEBMSG, ("xfs_message_gc: success\n"));
! 399:
! 400: vgone(vp, VX_NOSLEEP, NULL);
! 401: } else {
! 402: NNPFSDEB(XDEBMSG, ("xfs_message_gc: used\n"));
! 403: }
! 404:
! 405: }
! 406:
! 407:
! 408: #else /* !__osf__ */
! 409:
! 410: /*
! 411: * Try to clean out nodes for the userland daemon
! 412: */
! 413:
! 414: static void
! 415: gc_vnode (struct vnode *vp,
! 416: d_thread_t *p)
! 417: {
! 418: #ifdef HAVE_SYS_MUTEX_H
! 419: mtx_lock(&vp->v_interlock);
! 420: #else
! 421: simple_lock(&vp->v_interlock);
! 422: #endif
! 423:
! 424: /* This node is on the freelist */
! 425: if (vp->v_usecount <= 0) {
! 426: #if __FreeBSD__
! 427: vm_object_t obj;
! 428:
! 429: obj = vp->v_object;
! 430:
! 431: if (obj != NULL
! 432: && (obj->ref_count != 0
! 433: #ifdef OBJ_MIGHTBEDIRTY
! 434: || (obj->flags & OBJ_MIGHTBEDIRTY) != 0
! 435: #endif
! 436: )) {
! 437: #ifdef HAVE_SYS_MUTEX_H
! 438: mtx_unlock(&vp->v_interlock);
! 439: #else
! 440: simple_unlock (&vp->v_interlock);
! 441: #endif
! 442: return;
! 443: }
! 444: #endif /* __FreeBSD__ */
! 445:
! 446: #ifdef DIAGNOSTIC
! 447: if (vp->v_usecount < 0 || vp->v_writecount != 0) {
! 448: vprint("vrele: bad ref count", vp);
! 449: panic("vrele: ref cnt");
! 450: }
! 451: #endif /* DIAGNOSTIC */
! 452:
! 453: NNPFSDEB(XDEBMSG, ("xfs_message_gc: success\n"));
! 454:
! 455: #ifdef HAVE_KERNEL_VGONEL
! 456: vgonel (vp, p);
! 457: #else
! 458: #ifdef HAVE_SYS_MUTEX_H
! 459: mtx_unlock(&vp->v_interlock);
! 460: #else
! 461: simple_unlock(&vp->v_interlock);
! 462: #endif
! 463: vgone (vp);
! 464: #endif
! 465:
! 466: } else {
! 467: #ifdef HAVE_SYS_MUTEX_H
! 468: mtx_unlock(&vp->v_interlock);
! 469: #else
! 470: simple_unlock(&vp->v_interlock);
! 471: #endif
! 472: NNPFSDEB(XDEBMSG, ("xfs_message_gc: used\n"));
! 473: }
! 474:
! 475: }
! 476:
! 477: #endif
! 478:
! 479: int
! 480: xfs_message_gc_nodes(int fd,
! 481: struct xfs_message_gc_nodes *message,
! 482: u_int size,
! 483: d_thread_t *p)
! 484: {
! 485: struct xfs_node *node;
! 486: int i;
! 487:
! 488: NNPFSDEB(XDEBMSG, ("xfs_message_gc\n"));
! 489:
! 490: for (i = 0; i < message->len; i++) {
! 491: node = xfs_node_find (&xfs[fd].nodehead, &message->handle[i]);
! 492: if (node)
! 493: gc_vnode(XNODE_TO_VNODE(node), p);
! 494: else {
! 495: NNPFSDEB(XDEBMSG, ("xfs_message_gc_nodes: no such node\n"));
! 496: send_inactive_node(fd, &message->handle[i]);
! 497: }
! 498: }
! 499:
! 500: return 0;
! 501: }
! 502:
! 503:
! 504: /*
! 505: * Probe what version of xfs this support
! 506: */
! 507:
! 508: int
! 509: xfs_message_version(int fd,
! 510: struct xfs_message_version *message,
! 511: u_int size,
! 512: d_thread_t *p)
! 513: {
! 514: struct xfs_message_wakeup msg;
! 515: int ret;
! 516:
! 517: ret = NNPFS_VERSION;
! 518:
! 519: msg.header.opcode = NNPFS_MSG_WAKEUP;
! 520: msg.sleepers_sequence_num = message->header.sequence_num;
! 521: msg.error = ret;
! 522:
! 523: return xfs_message_send(fd,
! 524: (struct xfs_message_header *) &msg, sizeof(msg));
! 525: }
CVSweb