Annotation of sys/xfs/xfs_node-bsd.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 <sys/queue.h>
35: #include <xfs/xfs_locl.h>
36: #include <xfs/xfs_common.h>
37: #include <xfs/xfs_fs.h>
38: #include <xfs/xfs_deb.h>
39: #include <xfs/xfs_vnodeops.h>
40:
41: RCSID("$arla: xfs_node-bsd.c,v 1.70 2003/02/28 02:01:06 lha Exp $");
42:
43: extern vop_t **xfs_vnodeop_p;
44:
45: #ifndef LK_NOPAUSE
46: #define LK_NOPAUSE 0
47: #endif
48:
49: /*
50: * Allocate a new vnode with handle `handle' in `mp' and return it in
51: * `vpp'. Return 0 or error.
52: */
53:
54: int
55: xfs_getnewvnode(struct xfs *xfsp, struct vnode **vpp,
56: struct xfs_handle *handle)
57: {
58: struct xfs_node *result, *check;
59: int error;
60:
61: error = getnewvnode(VT_XFS, NNPFS_TO_VFS(xfsp), xfs_vnodeop_p, vpp);
62: if (error)
63: return error;
64:
65: result = xfs_alloc(sizeof(*result), M_NNPFS_NODE);
66: bzero(result, sizeof(*result));
67:
68: (*vpp)->v_data = result;
69: result->vn = *vpp;
70:
71: result->handle = *handle;
72: result->flags = 0;
73: result->tokens = 0;
74: result->offset = 0;
75: #if defined(HAVE_KERNEL_LOCKMGR) || defined(HAVE_KERNEL_DEBUGLOCKMGR)
76: lockinit (&result->lock, PVFS, "xfs_lock", 0, LK_NOPAUSE);
77: #else
78: result->vnlocks = 0;
79: #endif
80: result->anonrights = 0;
81: result->rd_cred = NULL;
82: result->wr_cred = NULL;
83:
84: #if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105280000
85: genfs_node_init(*vpp, &xfs_genfsops);
86: #endif
87:
88: check = xfs_node_find(&xfsp->nodehead, handle);
89: if (check) {
90: vput(*vpp);
91: *vpp = result->vn;
92: return 0;
93: }
94:
95: xfs_insert(&xfs->nodehead, result);
96:
97: return 0;
98: }
99:
100: /*
101: * Create a new xfs_node and make a vget
102: *
103: * Also prevents creation of duplicates. This happens
104: * whenever there are more than one name to a file,
105: * "." and ".." are common cases. */
106:
107: int
108: new_xfs_node(struct xfs *xfsp,
109: struct xfs_msg_node *node,
110: struct xfs_node **xpp,
111: d_thread_t *p)
112: {
113: struct xfs_node *result;
114:
115: NNPFSDEB(XDEBNODE, ("new_xfs_node (%d,%d,%d,%d)\n",
116: node->handle.a,
117: node->handle.b,
118: node->handle.c,
119: node->handle.d));
120:
121: retry:
122: /* Does not allow duplicates */
123: result = xfs_node_find(&xfsp->nodehead, &node->handle);
124: if (result == 0) {
125: int error;
126: struct vnode *v;
127:
128: error = xfs_getnewvnode(xfsp, &v, &node->handle);
129: if (error)
130: return error;
131:
132: result = VNODE_TO_XNODE(v);
133: result->anonrights = node->anonrights;
134:
135: xfsp->nnodes++;
136: } else {
137: /* Node is already cached */
138: if(xfs_do_vget(XNODE_TO_VNODE(result), 0, p))
139: goto retry;
140: }
141:
142: /* Init other fields */
143: xfs_attr2vattr(&node->attr, &result->attr, 1);
144: result->vn->v_type = result->attr.va_type;
145: result->tokens = node->tokens;
146: bcopy(node->id, result->id, sizeof(result->id));
147: bcopy(node->rights, result->rights, sizeof(result->rights));
148:
149: #ifdef __APPLE__
150: if (result->vn->v_type == VREG && (!UBCINFOEXISTS(result->vn)))
151: ubc_info_init(result->vn);
152: #endif
153:
154: *xpp = result;
155: NNPFSDEB(XDEBNODE, ("return: new_xfs_node\n"));
156: return 0;
157: }
158:
159: void
160: free_xfs_node(struct xfs_node *node)
161: {
162: struct xfs *xfsp = NNPFS_FROM_XNODE(node);
163:
164: NNPFSDEB(XDEBNODE, ("free_xfs_node(%lx) (%d,%d,%d,%d)\n",
165: (unsigned long)node,
166: node->handle.a,
167: node->handle.b,
168: node->handle.c,
169: node->handle.d));
170:
171: /* XXX Really need to put back dirty data first. */
172:
173: if (DATA_FROM_XNODE(node)) {
174: vrele(DATA_FROM_XNODE(node));
175: DATA_FROM_XNODE(node) = NULL;
176: }
177: xfsp->nnodes--;
178: XNODE_TO_VNODE(node)->v_data = NULL;
179: if (node->rd_cred) {
180: crfree (node->rd_cred);
181: node->rd_cred = NULL;
182: }
183: if (node->wr_cred) {
184: crfree (node->wr_cred);
185: node->wr_cred = NULL;
186: }
187:
188: xfs_free(node, sizeof(*node), M_NNPFS_NODE);
189:
190: NNPFSDEB(XDEBNODE, ("free_xfs_node done\n"));
191: }
192:
193: /*
194: * FreeBSD 4.4 and newer changed to API to vflush around June 2001
195: */
196:
197: static int
198: xfs_vflush(struct mount *mp, int flags)
199: {
200: #if __FreeBSD__ && __FreeBSD_version > 430000
201: return vflush(mp, 0, flags);
202: #else
203: return vflush(mp, NULL, flags);
204: #endif
205: }
206:
207: int
208: free_all_xfs_nodes(struct xfs *xfsp, int flags, int unmountp)
209: {
210: int error = 0;
211: struct mount *mp = NNPFS_TO_VFS(xfsp);
212:
213: if (mp == NULL) {
214: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n"));
215: return 0;
216: }
217:
218: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n"));
219:
220: xfs_dnlc_purge_mp(mp);
221:
222: if (xfsp->root) {
223: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n"));
224:
225: vgone(XNODE_TO_VNODE(xfsp->root));
226: xfsp->root = NULL;
227: }
228:
229: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n"));
230: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes now killing all remaining nodes\n"));
231:
232: /*
233: * If we have a syncer vnode, release it (to emulate dounmount)
234: * and the create it again when if we are going to need it.
235: */
236:
237: #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER
238: if (!unmountp) {
239: if (mp->mnt_syncer != NULL) {
240: #ifdef HAVE_KERNEL_VFS_DEALLOCATE_SYNCVNODE
241: vfs_deallocate_syncvnode(mp);
242: #else
243: /*
244: * FreeBSD and OpenBSD uses different semantics,
245: * FreeBSD does vrele, and OpenBSD does vgone.
246: */
247: #if defined(__OpenBSD__)
248: vgone(mp->mnt_syncer);
249: #elif defined(__FreeBSD__)
250: vrele(mp->mnt_syncer);
251: #else
252: #error what os do you use ?
253: #endif
254: mp->mnt_syncer = NULL;
255: #endif
256: }
257: }
258: #endif
259: error = xfs_vflush(mp, flags);
260: #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER
261: if (!unmountp) {
262: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes not flushing syncer vnode\n"));
263: if (mp->mnt_syncer == NULL)
264: if (vfs_allocate_syncvnode(mp))
265: panic("failed to allocate syncer node when xfs daemon died");
266: }
267: #endif
268:
269: if (error) {
270: NNPFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush() error == %d\n",
271: error));
272: return error;
273: }
274:
275: NNPFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n"));
276: return error;
277: }
278:
279: void
280: vattr2xfs_attr(const struct vattr *va, struct xfs_attr *xa)
281: {
282: bzero(xa, sizeof(*xa));
283: if (va->va_mode != (mode_t)VNOVAL)
284: XA_SET_MODE(xa, va->va_mode);
285: if (va->va_nlink != VNOVAL)
286: XA_SET_NLINK(xa, va->va_nlink);
287: if (va->va_size != VNOVAL)
288: XA_SET_SIZE(xa, va->va_size);
289: if (va->va_uid != VNOVAL)
290: XA_SET_UID(xa, va->va_uid);
291: if (va->va_gid != VNOVAL)
292: XA_SET_GID(xa, va->va_gid);
293: if (va->va_atime.tv_sec != VNOVAL)
294: XA_SET_ATIME(xa, va->va_atime.tv_sec);
295: if (va->va_mtime.tv_sec != VNOVAL)
296: XA_SET_MTIME(xa, va->va_mtime.tv_sec);
297: if (va->va_ctime.tv_sec != VNOVAL)
298: XA_SET_CTIME(xa, va->va_ctime.tv_sec);
299: if (va->va_fileid != VNOVAL)
300: XA_SET_FILEID(xa, va->va_fileid);
301: switch (va->va_type) {
302: case VNON:
303: xa->xa_type = NNPFS_FILE_NON;
304: break;
305: case VREG:
306: xa->xa_type = NNPFS_FILE_REG;
307: break;
308: case VDIR:
309: xa->xa_type = NNPFS_FILE_DIR;
310: break;
311: case VBLK:
312: xa->xa_type = NNPFS_FILE_BLK;
313: break;
314: case VCHR:
315: xa->xa_type = NNPFS_FILE_CHR;
316: break;
317: case VLNK:
318: xa->xa_type = NNPFS_FILE_LNK;
319: break;
320: case VSOCK:
321: xa->xa_type = NNPFS_FILE_SOCK;
322: break;
323: case VFIFO:
324: xa->xa_type = NNPFS_FILE_FIFO;
325: break;
326: case VBAD:
327: xa->xa_type = NNPFS_FILE_BAD;
328: break;
329: default:
330: panic("xfs_attr2attr: bad value");
331: }
332: }
333:
334: #define SET_TIMEVAL(X, S, N) do { (X)->tv_sec = (S); (X)->tv_nsec = (N); } while(0)
335:
336: void
337: xfs_attr2vattr(const struct xfs_attr *xa, struct vattr *va, int clear_node)
338: {
339: if (clear_node)
340: VATTR_NULL(va);
341: if (XA_VALID_MODE(xa))
342: va->va_mode = xa->xa_mode;
343: if (XA_VALID_NLINK(xa))
344: va->va_nlink = xa->xa_nlink;
345: if (XA_VALID_SIZE(xa)) {
346: va->va_size = xa->xa_size;
347: va->va_bytes = va->va_size;
348: }
349: if (XA_VALID_UID(xa))
350: va->va_uid = xa->xa_uid;
351: if (XA_VALID_GID(xa))
352: va->va_gid = xa->xa_gid;
353: if (XA_VALID_ATIME(xa)) {
354: SET_TIMEVAL(&va->va_atime, xa->xa_atime, 0);
355: }
356: if (XA_VALID_MTIME(xa)) {
357: SET_TIMEVAL(&va->va_mtime, xa->xa_mtime, 0);
358: }
359: if (XA_VALID_CTIME(xa)) {
360: SET_TIMEVAL(&va->va_ctime, xa->xa_ctime, 0);
361: }
362: if (XA_VALID_FILEID(xa)) {
363: va->va_fileid = xa->xa_fileid;
364: }
365: if (XA_VALID_TYPE(xa)) {
366: switch (xa->xa_type) {
367: case NNPFS_FILE_NON:
368: va->va_type = VNON;
369: break;
370: case NNPFS_FILE_REG:
371: va->va_type = VREG;
372: break;
373: case NNPFS_FILE_DIR:
374: va->va_type = VDIR;
375: break;
376: case NNPFS_FILE_BLK:
377: va->va_type = VBLK;
378: break;
379: case NNPFS_FILE_CHR:
380: va->va_type = VCHR;
381: break;
382: case NNPFS_FILE_LNK:
383: va->va_type = VLNK;
384: break;
385: case NNPFS_FILE_SOCK:
386: va->va_type = VSOCK;
387: break;
388: case NNPFS_FILE_FIFO:
389: va->va_type = VFIFO;
390: break;
391: case NNPFS_FILE_BAD:
392: va->va_type = VBAD;
393: break;
394: default:
395: panic("xfs_attr2vattr: bad value");
396: }
397: }
398: va->va_flags = 0;
399: va->va_blocksize = 8192;
400: }
401:
402: /*
403: * A single entry DNLC for systems for handling long names that don't
404: * get put into the system DNLC.
405: */
406:
407: struct long_entry {
408: struct vnode *dvp, *vp;
409: char name[MAXNAMLEN + 1];
410: size_t len;
411: u_long dvpid, vpid;
412: };
413:
414: static struct long_entry tbl;
415:
416: /*
417: * Nuke the `tbl'
418: */
419:
420: static void
421: tbl_clear (void)
422: {
423: tbl.dvp = tbl.vp = NULL;
424: tbl.name[0] = '\0';
425: tbl.len = 0;
426: tbl.dvpid = tbl.vpid = 0;
427: }
428:
429: /*
430: * Set the entry in the `tbl'
431: */
432:
433: static void
434: tbl_enter (size_t len, const char *name, struct vnode *dvp, struct vnode *vp)
435: {
436: tbl.len = len;
437: bcopy(name, tbl.name, len);
438: tbl.dvp = dvp;
439: tbl.vp = vp;
440: tbl.dvpid = dvp->v_id;
441: tbl.vpid = vp->v_id;
442: }
443:
444: /*
445: * Lookup in tbl (`dvp', `name', `len') and return result in `res'.
446: * Return -1 if successful, otherwise 0.
447: */
448:
449: static int
450: tbl_lookup (struct componentname *cnp,
451: struct vnode *dvp,
452: struct vnode **res)
453: {
454: if (tbl.dvp == dvp
455: && tbl.len == cnp->cn_namelen
456: && strncmp(tbl.name, cnp->cn_nameptr, tbl.len) == 0
457: && tbl.dvpid == tbl.dvp->v_id
458: && tbl.vpid == tbl.vp->v_id) {
459:
460: *res = tbl.vp;
461: return -1;
462: } else
463: return 0;
464: }
465:
466: /*
467: * Store a componentname in the DNLC
468: */
469:
470: int
471: xfs_dnlc_enter(struct vnode *dvp,
472: xfs_componentname *cnp,
473: struct vnode *vp)
474: {
475: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter_cnp(%lx, %lx, %lx)\n",
476: (unsigned long)dvp,
477: (unsigned long)cnp,
478: (unsigned long)vp));
479: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %lu\n", (u_long)dvp->v_id));
480:
481: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:"
482: "dvp = %lx, vp = %lx, cnp = (%s, %ld), "
483: "nameiop = %lu, flags = %lx\n",
484: (unsigned long)dvp,
485: (unsigned long)vp,
486: cnp->cn_nameptr, cnp->cn_namelen,
487: cnp->cn_nameiop, cnp->cn_flags));
488:
489: #ifdef NCHNAMLEN
490: if (cnp->cn_namelen <= NCHNAMLEN)
491: #endif
492: {
493: /*
494: * This is to make sure there's no negative entry already in the dnlc
495: */
496: u_long save_nameiop;
497: u_long save_flags;
498: struct vnode *dummy;
499:
500: save_nameiop = cnp->cn_nameiop;
501: save_flags = cnp->cn_flags;
502: cnp->cn_nameiop = CREATE;
503: cnp->cn_flags &= ~MAKEENTRY;
504:
505: /*
506: * The version number here is not entirely correct, but it's conservative.
507: * The real change is sys/kern/vfs_cache:1.20
508: */
509:
510: #if __NetBSD_Version__ >= 104120000 || OpenBSD > 200211
511: if (cache_lookup(dvp, &dummy, cnp) != -1) {
512: xfs_vfs_unlock(dummy, xfs_cnp_to_proc(cnp));
513: printf ("NNPFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n",
514: cnp->cn_nameptr);
515: }
516: #else
517: if (cache_lookup(dvp, &dummy, cnp) != 0) {
518: printf ("NNPFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n",
519: cnp->cn_nameptr);
520: }
521: #endif
522:
523:
524: cnp->cn_nameiop = save_nameiop;
525: cnp->cn_flags = save_flags;
526: cache_enter(dvp, vp, cnp);
527: }
528:
529: if (vp != NULL)
530: tbl_enter (cnp->cn_namelen, cnp->cn_nameptr, dvp, vp);
531:
532: return 0;
533: }
534:
535:
536: static void
537: xfs_cnp_init (struct componentname *cn,
538: const char *name,
539: d_thread_t *proc, struct ucred *cred,
540: int nameiop)
541: {
542: bzero(cn, sizeof(*cn));
543: cn->cn_nameptr = (char *)name;
544: cn->cn_namelen = strlen(name);
545: cn->cn_flags = 0;
546: #if __APPLE__
547: {
548: const unsigned char *p;
549: int i;
550:
551: cn->cn_hash = 0;
552: for (p = cn->cn_nameptr, i = 1; *p; ++p, ++i)
553: cn->cn_hash += *p * i;
554: }
555: #elif defined(HAVE_KERNEL_NAMEI_HASH)
556: {
557: const char *cp = name + cn->cn_namelen;
558: cn->cn_hash = namei_hash(name, &cp);
559: }
560: #elif defined(HAVE_STRUCT_COMPONENTNAME_CN_HASH)
561: {
562: const unsigned char *p;
563:
564: cn->cn_hash = 0;
565: for (p = cn->cn_nameptr; *p; ++p)
566: cn->cn_hash += *p;
567: }
568: #endif
569: cn->cn_nameiop = nameiop;
570: #ifdef HAVE_FREEBSD_THREAD
571: cn->cn_thread = proc;
572: #else
573: cn->cn_proc = proc;
574: #endif
575: cn->cn_cred = cred;
576: }
577:
578:
579: /*
580: * Store (dvp, name, vp) in the DNLC
581: */
582:
583: int
584: xfs_dnlc_enter_name(struct vnode *dvp,
585: const char *name,
586: struct vnode *vp)
587: {
588: struct componentname cn;
589:
590: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_enter_name(%lx, \"%s\", %lx)\n",
591: (unsigned long)dvp,
592: name,
593: (unsigned long)vp));
594:
595: xfs_cnp_init (&cn, name, NULL, NULL, LOOKUP);
596: return xfs_dnlc_enter (dvp, &cn, vp);
597: }
598:
599: /*
600: * Lookup (dvp, cnp) in the DNLC and return the result in `res'.
601: * Return the result from cache_lookup.
602: */
603:
604: static int
605: xfs_dnlc_lookup_int(struct vnode *dvp,
606: xfs_componentname *cnp,
607: struct vnode **res)
608: {
609: int error;
610: u_long saved_flags;
611:
612: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(%lx, \"%s\")\n",
613: (unsigned long)dvp, cnp->cn_nameptr));
614:
615: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %lu\n", (u_long)dvp->v_id));
616:
617: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:"
618: "dvp = %lx, cnp = (%s, %ld), flags = %lx\n",
619: (unsigned long)dvp,
620: cnp->cn_nameptr, cnp->cn_namelen,
621: cnp->cn_flags));
622:
623: saved_flags = cnp->cn_flags;
624: cnp->cn_flags |= MAKEENTRY | LOCKPARENT | ISLASTCN;
625:
626: error = cache_lookup(dvp, res, cnp);
627:
628: cnp->cn_flags = saved_flags;
629:
630: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. "
631: "error = %d, *res = %lx\n", error,
632: (unsigned long)*res));
633: return error;
634: }
635:
636: /*
637: * do the last (and locking protocol) portion of xnlc_lookup
638: *
639: * return:
640: * -1 for successful
641: * 0 for failed
642: */
643:
644: static int
645: xfs_dnlc_lock(struct vnode *dvp,
646: xfs_componentname *cnp,
647: struct vnode **res)
648: {
649: int error = 0;
650:
651: /*
652: * Try to handle the (complex) BSD locking protocol.
653: */
654:
655: if (*res == dvp) { /* "." */
656: VREF(dvp);
657: } else if (cnp->cn_flags & ISDOTDOT) { /* ".." */
658: u_long vpid = dvp->v_id;
659:
660: #ifdef HAVE_FREEBSD_THREAD
661: xfs_vfs_unlock(dvp, xfs_cnp_to_thread(cnp));
662: error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp));
663: xfs_vfs_writelock(dvp, xfs_cnp_to_thread(cnp));
664: #else
665: xfs_vfs_unlock(dvp, xfs_cnp_to_proc(cnp));
666: error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp));
667: xfs_vfs_writelock(dvp, xfs_cnp_to_proc(cnp));
668: #endif
669:
670: if (error == 0 && dvp->v_id != vpid) {
671: vput(*res);
672: return 0;
673: }
674: } else {
675: #ifdef HAVE_FREEBSD_THREAD
676: error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp));
677: #else
678: error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp));
679: #endif
680: }
681:
682: if (error == 0)
683: return -1;
684: else
685: return 0;
686: }
687:
688: /*
689: * Lookup (`dvp', `cnp') in the DNLC (and the local cache).
690: *
691: * Return -1 if successful, 0 if not and ENOENT if the entry is known
692: * not to exist.
693: *
694: * On modern NetBSD, cache_lookup has been changed to return 0 for
695: * successful and -1 for not.
696: * (see the comment above for version information).
697: */
698:
699: #if __NetBSD_Version__ >= 104120000 || defined(__OpenBSD__)
700:
701: int
702: xfs_dnlc_lookup(struct vnode *dvp,
703: xfs_componentname *cnp,
704: struct vnode **res)
705: {
706: int error = xfs_dnlc_lookup_int (dvp, cnp, res);
707:
708: if (error == 0)
709: return -1;
710: else if (error == ENOENT)
711: return error;
712:
713: error = tbl_lookup (cnp, dvp, res);
714:
715: if (error != -1)
716: return error;
717:
718: return xfs_dnlc_lock (dvp, cnp, res);
719: }
720:
721: #else /* ! __NetBSD_Version__ >= 104120000 && ! OpenBSD > 200211 */
722:
723: int
724: xfs_dnlc_lookup(struct vnode *dvp,
725: xfs_componentname *cnp,
726: struct vnode **res)
727: {
728: int error = xfs_dnlc_lookup_int (dvp, cnp, res);
729:
730: if (error == 0)
731: error = tbl_lookup (cnp, dvp, res);
732:
733: if (error != -1)
734: return error;
735:
736: return xfs_dnlc_lock (dvp, cnp, res);
737: }
738:
739: #endif /* __NetBSD_Version__ >= 104120000 || OpenBSD > 200211 */
740:
741: /*
742: * Remove one entry from the DNLC
743: */
744:
745: void
746: xfs_dnlc_purge (struct vnode *vp)
747: {
748: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_purge\n"));
749:
750: if (tbl.dvp == vp || tbl.vp == vp)
751: tbl_clear ();
752:
753: cache_purge(vp);
754: }
755:
756: /*
757: * Remove all entries belong to `mp' from the DNLC
758: */
759:
760: void
761: xfs_dnlc_purge_mp(struct mount *mp)
762: {
763: NNPFSDEB(XDEBDNLC, ("xfs_dnlc_purge_mp()\n"));
764:
765: tbl_clear ();
766: cache_purgevfs(mp);
767: }
768:
769: /*
770: * Returns 1 if pag has any rights set in the node
771: */
772:
773: int
774: xfs_has_pag(const struct xfs_node *xn, xfs_pag_t pag)
775: {
776: int i;
777:
778: for (i = 0; i < MAXRIGHTS; i++)
779: if (xn->id[i] == pag)
780: return 1;
781:
782: return 0;
783: }
784:
785: void
786: xfs_update_write_cred(struct xfs_node *xn, struct ucred *cred)
787: {
788: if (xn->wr_cred)
789: crfree (xn->wr_cred);
790: crhold (cred);
791: xn->wr_cred = cred;
792: }
793:
794: void
795: xfs_update_read_cred(struct xfs_node *xn, struct ucred *cred)
796: {
797: if (xn->rd_cred)
798: crfree (xn->rd_cred);
799: crhold (cred);
800: xn->rd_cred = cred;
801: }
CVSweb