Annotation of sys/xfs/xfs_message.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
3: * (Royal Institute of Technology, Stockholm, Sweden).
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: *
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * 3. Neither the name of the Institute nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include <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