kernel - TMPFS - Bug fixing pass - vinitvmio(), umount, readdir
[dragonfly.git] / sys / vfs / tmpfs / tmpfs_vnops.c
1 /*      $NetBSD: tmpfs_vnops.c,v 1.39 2007/07/23 15:41:01 jmmv Exp $    */
2
3 /*-
4  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9  * 2005 program.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * tmpfs vnode interface.
35  */
36 #include <sys/cdefs.h>
37
38 #include <sys/kernel.h>
39 #include <sys/kern_syscall.h>
40 #include <sys/param.h>
41 #include <sys/fcntl.h>
42 #include <sys/lockf.h>
43 #include <sys/priv.h>
44 #include <sys/proc.h>
45 #include <sys/resourcevar.h>
46 #include <sys/sched.h>
47 #include <sys/sfbuf.h>
48 #include <sys/stat.h>
49 #include <sys/systm.h>
50 #include <sys/unistd.h>
51 #include <sys/vfsops.h>
52 #include <sys/vnode.h>
53
54 #include <sys/mplock2.h>
55
56 #include <vm/vm.h>
57 #include <vm/vm_object.h>
58 #include <vm/vm_page.h>
59 #include <vm/vm_pager.h>
60
61 #include <vfs/fifofs/fifo.h>
62 #include <vfs/tmpfs/tmpfs_vnops.h>
63 #include <vfs/tmpfs/tmpfs.h>
64
65 MALLOC_DECLARE(M_TMPFS);
66
67 /* --------------------------------------------------------------------- */
68
69 static int
70 tmpfs_nresolve(struct vop_nresolve_args *v)
71 {
72         struct vnode *dvp = v->a_dvp;
73         struct vnode *vp = NULL;
74         struct namecache *ncp = v->a_nch->ncp;
75         struct ucred *cred = v->a_cred;
76
77         int error;
78         struct tmpfs_dirent *de;
79         struct tmpfs_node *dnode;
80
81         dnode = VP_TO_TMPFS_DIR(dvp);
82
83         /* Check accessibility of requested node as a first step. */
84         error = VOP_ACCESS(dvp, VEXEC, cred);
85         if (error != 0)
86                 goto out;
87
88         if (dnode->tn_dir.tn_parent == NULL) {
89                 error = ENOENT;
90                 goto out;
91         }
92
93         de = tmpfs_dir_lookup(dnode, NULL, ncp);
94         if (de == NULL) {
95                 /* The entry was not found in the directory.
96                  * This is OK if we are creating or renaming an
97                  * entry and are working on the last component of
98                  * the path name. */
99                 error = VOP_ACCESS(dvp, VWRITE, cred);
100                 if (error != 0) {
101                         goto out;
102                 } else {
103                         error = ENOENT;
104                         goto out;
105                 }
106         } else {
107                 struct tmpfs_node *tnode;
108
109                 /* The entry was found, so get its associated
110                  * tmpfs_node. */
111                 tnode = de->td_node;
112
113                 /* If we are not at the last path component and
114                  * found a non-directory or non-link entry (which
115                  * may itself be pointing to a directory), raise
116                  * an error. */
117                 if (tnode->tn_links > 1 &&
118                     tnode->tn_type != VDIR && tnode->tn_type != VLNK) {
119                         error = ENOTDIR;
120                         goto out;
121                 }
122
123                 error = VOP_ACCESS(dvp, VWRITE, cred);
124                 if (error != 0)
125                         goto out;
126
127                 /* Allocate a new vnode on the matching entry. */
128                 error = tmpfs_alloc_vp(dvp->v_mount, tnode,
129                                 LK_EXCLUSIVE | LK_RETRY, &vp);
130                 if (error != 0)
131                         goto out;
132
133                 if ((dnode->tn_mode & S_ISTXT) &&
134                     VOP_ACCESS(vp, VWRITE, cred)) {
135                         error = EPERM;
136                         vp = NULL;
137                         goto out;
138                 }
139         }
140
141         KKASSERT(vp);
142
143 out:
144         /* Store the result of this lookup in the cache.  Avoid this if the
145          * request was for creation, as it does not improve timings on
146          * emprical tests. */
147         if (vp) {
148                 vn_unlock(vp);
149                 cache_setvp(v->a_nch, vp);
150                 vrele(vp);
151         }
152         if (error == ENOENT) {
153                 cache_setvp(v->a_nch, NULL);
154         }
155         return error;
156 }
157
158 static int
159 tmpfs_nlookupdotdot(struct vop_nlookupdotdot_args *v)
160 {
161         struct vnode *dvp = v->a_dvp;
162         struct vnode **vpp = v->a_vpp;
163         struct tmpfs_node *dnode = VP_TO_TMPFS_NODE(dvp);
164         struct ucred *cred = v->a_cred;
165         int error;
166
167         *vpp = NULL;
168         /* Check accessibility of requested node as a first step. */
169         error = VOP_ACCESS(dvp, VEXEC, cred);
170         if (error != 0)
171                 return error;
172
173         if (dnode->tn_dir.tn_parent != NULL) {
174                 /* Allocate a new vnode on the matching entry. */
175                 error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent,
176                     LK_EXCLUSIVE | LK_RETRY, vpp);
177
178                 if (*vpp)
179                         vn_unlock(*vpp);
180         }
181
182         return (*vpp == NULL) ? ENOENT : 0;
183 }
184
185 /* --------------------------------------------------------------------- */
186
187 static int
188 tmpfs_ncreate(struct vop_ncreate_args *v)
189 {
190         struct vnode *dvp = v->a_dvp;
191         struct vnode **vpp = v->a_vpp;
192         struct namecache *ncp = v->a_nch->ncp;
193         struct vattr *vap = v->a_vap;
194         struct ucred *cred = v->a_cred;
195         int error;
196
197         KKASSERT(vap->va_type == VREG || vap->va_type == VSOCK);
198
199         error = tmpfs_alloc_file(dvp, vpp, vap, ncp, cred, NULL);
200         if (error == 0) {
201                 cache_setunresolved(v->a_nch);
202                 cache_setvp(v->a_nch, *vpp);
203         }
204
205         return error;
206 }
207 /* --------------------------------------------------------------------- */
208
209 static int
210 tmpfs_nmknod(struct vop_nmknod_args *v)
211 {
212         struct vnode *dvp = v->a_dvp;
213         struct vnode **vpp = v->a_vpp;
214         struct namecache *ncp = v->a_nch->ncp;
215         struct vattr *vap = v->a_vap;
216         struct ucred *cred = v->a_cred;
217         int error;
218
219         if (vap->va_type != VBLK && vap->va_type != VCHR &&
220             vap->va_type != VFIFO)
221                 return EINVAL;
222
223         error = tmpfs_alloc_file(dvp, vpp, vap, ncp, cred, NULL);
224         if (error == 0) {
225                 cache_setunresolved(v->a_nch);
226                 cache_setvp(v->a_nch, *vpp);
227         }
228
229         return error;
230 }
231
232 /* --------------------------------------------------------------------- */
233
234 static int
235 tmpfs_open(struct vop_open_args *v)
236 {
237         struct vnode *vp = v->a_vp;
238         int mode = v->a_mode;
239
240         int error;
241         struct tmpfs_node *node;
242
243         node = VP_TO_TMPFS_NODE(vp);
244
245         /* The file is still active but all its names have been removed
246          * (e.g. by a "rmdir $(pwd)").  It cannot be opened any more as
247          * it is about to die. */
248         if (node->tn_links < 1)
249                 return (ENOENT);
250
251         /* If the file is marked append-only, deny write requests. */
252         if ((node->tn_flags & APPEND) &&
253             (mode & (FWRITE | O_APPEND)) == FWRITE) {
254                 error = EPERM;
255         } else {
256                 return (vop_stdopen(v));
257         }
258         return error;
259 }
260
261 /* --------------------------------------------------------------------- */
262
263 static int
264 tmpfs_close(struct vop_close_args *v)
265 {
266         struct vnode *vp = v->a_vp;
267         struct tmpfs_node *node;
268
269         node = VP_TO_TMPFS_NODE(vp);
270
271         if (node->tn_links > 0) {
272                 /* Update node times.  No need to do it if the node has
273                  * been deleted, because it will vanish after we return. */
274                 tmpfs_update(vp);
275         }
276
277         return vop_stdclose(v);
278 }
279
280 /* --------------------------------------------------------------------- */
281
282 int
283 tmpfs_access(struct vop_access_args *v)
284 {
285         struct vnode *vp = v->a_vp;
286         int error;
287         struct tmpfs_node *node;
288
289         node = VP_TO_TMPFS_NODE(vp);
290
291         switch (vp->v_type) {
292         case VDIR:
293                 /* FALLTHROUGH */
294         case VLNK:
295                 /* FALLTHROUGH */
296         case VREG:
297                 if (VWRITE && vp->v_mount->mnt_flag & MNT_RDONLY) {
298                         error = EROFS;
299                         goto out;
300                 }
301                 break;
302
303         case VBLK:
304                 /* FALLTHROUGH */
305         case VCHR:
306                 /* FALLTHROUGH */
307         case VSOCK:
308                 /* FALLTHROUGH */
309         case VFIFO:
310                 break;
311
312         default:
313                 error = EINVAL;
314                 goto out;
315         }
316
317         if (VWRITE && node->tn_flags & IMMUTABLE) {
318                 error = EPERM;
319                 goto out;
320         }
321
322         error = vop_helper_access(v, node->tn_uid, node->tn_gid, node->tn_mode, 0);
323
324 out:
325
326         return error;
327 }
328
329 /* --------------------------------------------------------------------- */
330
331 int
332 tmpfs_getattr(struct vop_getattr_args *v)
333 {
334         struct vnode *vp = v->a_vp;
335         struct vattr *vap = v->a_vap;
336         struct tmpfs_node *node;
337
338         node = VP_TO_TMPFS_NODE(vp);
339
340         tmpfs_update(vp);
341
342         vap->va_type = vp->v_type;
343         vap->va_mode = node->tn_mode;
344         vap->va_nlink = node->tn_links;
345         vap->va_uid = node->tn_uid;
346         vap->va_gid = node->tn_gid;
347         vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
348         vap->va_fileid = node->tn_id;
349         vap->va_size = node->tn_size;
350         vap->va_blocksize = PAGE_SIZE;
351         vap->va_atime.tv_sec = node->tn_atime;
352         vap->va_atime.tv_nsec = node->tn_atimensec;
353         vap->va_mtime.tv_sec = node->tn_mtime;
354         vap->va_mtime.tv_nsec = node->tn_mtimensec;
355         vap->va_ctime.tv_sec = node->tn_ctime;
356         vap->va_ctime.tv_nsec = node->tn_ctimensec;
357         vap->va_gen = node->tn_gen;
358         vap->va_flags = node->tn_flags;
359         if (vp->v_type == VBLK || vp->v_type == VCHR)
360         {
361                 vap->va_rmajor = umajor(node->tn_rdev);
362                 vap->va_rminor = uminor(node->tn_rdev);
363         }
364         vap->va_bytes = round_page(node->tn_size);
365         vap->va_filerev = 0;
366
367         return 0;
368 }
369
370 /* --------------------------------------------------------------------- */
371
372 int
373 tmpfs_setattr(struct vop_setattr_args *v)
374 {
375         struct vnode *vp = v->a_vp;
376         struct vattr *vap = v->a_vap;
377         struct ucred *cred = v->a_cred;
378         int error = 0;
379
380         /* Abort if any unsettable attribute is given. */
381         if (vap->va_type != VNON ||
382             vap->va_nlink != VNOVAL ||
383             vap->va_fsid != VNOVAL ||
384             vap->va_fileid != VNOVAL ||
385             vap->va_blocksize != VNOVAL ||
386             vap->va_gen != VNOVAL ||
387             vap->va_rmajor != VNOVAL ||
388             vap->va_bytes != VNOVAL)
389                 error = EINVAL;
390
391         if (error == 0 && (vap->va_flags != VNOVAL))
392                 error = tmpfs_chflags(vp, vap->va_flags, cred);
393
394         if (error == 0 && (vap->va_size != VNOVAL))
395                 error = tmpfs_chsize(vp, vap->va_size, cred);
396
397         if (error == 0 && (vap->va_uid != VNOVAL || vap->va_gid != VNOVAL))
398                 error = tmpfs_chown(vp, vap->va_uid, vap->va_gid, cred);
399
400         if (error == 0 && (vap->va_mode != (mode_t)VNOVAL))
401                 error = tmpfs_chmod(vp, vap->va_mode, cred);
402
403         if (error == 0 && ((vap->va_atime.tv_sec != VNOVAL &&
404             vap->va_atime.tv_nsec != VNOVAL) ||
405             (vap->va_mtime.tv_sec != VNOVAL &&
406             vap->va_mtime.tv_nsec != VNOVAL) ))
407                 error = tmpfs_chtimes(vp, &vap->va_atime, &vap->va_mtime,
408                         vap->va_vaflags, cred);
409
410         /* Update the node times.  We give preference to the error codes
411          * generated by this function rather than the ones that may arise
412          * from tmpfs_update. */
413         tmpfs_update(vp);
414
415         return error;
416 }
417
418 /* --------------------------------------------------------------------- */
419
420 /*
421  * fsync is usually a NOP, but we must take action when unmounting or
422  * when recycling.
423  */
424 static int
425 tmpfs_fsync(struct vop_fsync_args *v)
426 {
427         struct tmpfs_mount *tmp;
428         struct tmpfs_node *node;
429         struct vnode *vp = v->a_vp;
430
431         tmp = VFS_TO_TMPFS(vp->v_mount);
432         node = VP_TO_TMPFS_NODE(vp);
433
434         tmpfs_update(vp);
435         if (vp->v_type == VREG) {
436                 if (tmp->tm_flags & TMPFS_FLAG_UNMOUNTING) {
437                         tmpfs_truncate(vp, 0);
438                 } else if (vp->v_flag & VRECLAIMED) {
439                         if (node->tn_links == 0)
440                                 tmpfs_truncate(vp, 0);
441                         else
442                                 vfsync(v->a_vp, v->a_waitfor, 1, NULL, NULL);
443                 }
444         }
445         return 0;
446 }
447
448 /* --------------------------------------------------------------------- */
449
450 static int
451 tmpfs_read (struct vop_read_args *ap)
452 {
453         struct buf *bp;
454         struct vnode *vp = ap->a_vp;
455         struct uio *uio = ap->a_uio;
456         struct tmpfs_node *node;
457         off_t base_offset;
458         size_t offset;
459         size_t len;
460         int got_mplock;
461         int error;
462
463         error = 0;
464         if (uio->uio_resid == 0) {
465                 return error;
466         }
467
468         node = VP_TO_TMPFS_NODE(vp);
469
470         if (uio->uio_offset < 0)
471                 return (EINVAL);
472         if (vp->v_type != VREG)
473                 return (EINVAL);
474
475 #ifdef SMP
476         if(curthread->td_mpcount)
477                 got_mplock = -1;
478         else
479                 got_mplock = 0;
480 #else
481                 got_mplock = -1;
482 #endif
483
484         while (uio->uio_resid > 0 && uio->uio_offset < node->tn_size) {
485                 /*
486                  * Use buffer cache I/O (via tmpfs_strategy)
487                  */
488                 offset = (size_t)uio->uio_offset & BMASK;
489                 base_offset = (off_t)uio->uio_offset - offset;
490                 bp = getcacheblk(vp, base_offset);
491                 if (bp == NULL)
492                 {
493                         if (got_mplock == 0) {
494                                 got_mplock = 1;
495                                 get_mplock();
496                         }
497
498                         error = bread(vp, base_offset, BSIZE, &bp);
499                         if (error) {
500                                 brelse(bp);
501                                 kprintf("tmpfs_read bread error %d\n", error);
502                                 break;
503                         }
504                 }
505
506                 if (got_mplock == 0) {
507                         got_mplock = 1;
508                         get_mplock();
509                 }
510
511                 /*
512                  * Figure out how many bytes we can actually copy this loop.
513                  */
514                 len = BSIZE - offset;
515                 if (len > uio->uio_resid)
516                         len = uio->uio_resid;
517                 if (len > node->tn_size - uio->uio_offset)
518                         len = (size_t)(node->tn_size - uio->uio_offset);
519
520                 error = uiomove((char *)bp->b_data + offset, len, uio);
521                 bqrelse(bp);
522                 if (error) {
523                         kprintf("tmpfs_read uiomove error %d\n", error);
524                         break;
525                 }
526         }
527
528         if (got_mplock > 0)
529                 rel_mplock();
530
531         TMPFS_NODE_LOCK(node);
532         node->tn_status |= TMPFS_NODE_ACCESSED;
533         TMPFS_NODE_UNLOCK(node);
534
535         return(error);
536 }
537
538 static int
539 tmpfs_write (struct vop_write_args *ap)
540 {
541         struct buf *bp;
542         struct vnode *vp = ap->a_vp;
543         struct uio *uio = ap->a_uio;
544         struct thread *td = uio->uio_td;
545         struct tmpfs_node *node;
546         boolean_t extended;
547         off_t oldsize;
548         int error;
549         off_t base_offset;
550         size_t offset;
551         size_t len;
552         struct rlimit limit;
553         int got_mplock;
554         int trivial = 0;
555
556         error = 0;
557         if (uio->uio_resid == 0) {
558                 return error;
559         }
560
561         node = VP_TO_TMPFS_NODE(vp);
562
563         if (vp->v_type != VREG)
564                 return (EINVAL);
565
566         oldsize = node->tn_size;
567         if (ap->a_ioflag & IO_APPEND)
568                 uio->uio_offset = node->tn_size;
569
570         /*
571          * Check for illegal write offsets.
572          */
573         if (uio->uio_offset + uio->uio_resid >
574           VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
575                 return (EFBIG);
576
577         if (vp->v_type == VREG && td != NULL) {
578                 error = kern_getrlimit(RLIMIT_FSIZE, &limit);
579                 if (error != 0)
580                         return error;
581                 if (uio->uio_offset + uio->uio_resid > limit.rlim_cur) {
582                         ksignal(td->td_proc, SIGXFSZ);
583                         return (EFBIG);
584                 }
585         }
586
587
588         /*
589          * Extend the file's size if necessary
590          */
591         extended = ((uio->uio_offset + uio->uio_resid) > node->tn_size);
592
593 #ifdef SMP
594         if (curthread->td_mpcount) {
595                 got_mplock = -1;
596         } else {
597                 got_mplock = 1;
598                 get_mplock();
599         }
600 #else
601         got_mplock = -1;
602 #endif
603         while (uio->uio_resid > 0) {
604                 /*
605                  * Use buffer cache I/O (via tmpfs_strategy)
606                  */
607                 offset = (size_t)uio->uio_offset & BMASK;
608                 base_offset = (off_t)uio->uio_offset - offset;
609                 len = BSIZE - offset;
610                 if (len > uio->uio_resid)
611                         len = uio->uio_resid;
612
613                 if ((uio->uio_offset + len) > node->tn_size) {
614                         trivial = (uio->uio_offset <= node->tn_size);
615                         error = tmpfs_reg_resize(vp, uio->uio_offset + len,  trivial);
616                         if (error)
617                                 break;
618                 }
619
620                 /*
621                  * Read to fill in any gaps.  Theoretically we could
622                  * optimize this if the write covers the entire buffer
623                  * and is not a UIO_NOCOPY write, however this can lead
624                  * to a security violation exposing random kernel memory
625                  * (whatever junk was in the backing VM pages before).
626                  *
627                  * So just use bread() to do the right thing.
628                  */
629                 error = bread(vp, base_offset, BSIZE, &bp);
630                 error = uiomove((char *)bp->b_data + offset, len, uio);
631                 if (error) {
632                         kprintf("tmpfs_write uiomove error %d\n", error);
633                         brelse(bp);
634                         break;
635                 }
636
637                 if (uio->uio_offset > node->tn_size)
638                         node->tn_size = uio->uio_offset;
639
640                 /*
641                  * The data has been loaded into the buffer, write it out.
642                  *
643                  * We want tmpfs to be able to use all available ram, not
644                  * just the buffer cache, so if not explicitly paging we
645                  * use buwrite() to leave the buffer clean but mark all the
646                  * VM pages valid+dirty.
647                  *
648                  * Be careful, the kernel uses IO_SYNC/IO_ASYNC when it
649                  * really really wants to flush the buffer, typically as
650                  * part of the paging system, and we'll loop forever if
651                  * we fake those.
652                  */
653                 if (ap->a_ioflag & IO_SYNC)
654                         bwrite(bp);
655                 else if (ap->a_ioflag & IO_ASYNC)
656                         bawrite(bp);
657                 else
658                         buwrite(bp);
659
660                 if (bp->b_error) {
661                         kprintf("tmpfs_write bwrite error %d\n", error);
662                         break;
663                 }
664         }
665
666         if (got_mplock > 0)
667                 rel_mplock();
668
669         if (error) {
670                 if (extended)
671                         (void)tmpfs_reg_resize(vp, oldsize, trivial);
672                 return error;
673         }
674
675         TMPFS_NODE_LOCK(node);
676         node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
677             (extended? TMPFS_NODE_CHANGED : 0);
678
679         if (node->tn_mode & (S_ISUID | S_ISGID)) {
680                 if (priv_check_cred(ap->a_cred, PRIV_VFS_RETAINSUGID, 0))
681                         node->tn_mode &= ~(S_ISUID | S_ISGID);
682         }
683         TMPFS_NODE_UNLOCK(node);
684
685         return(error);
686 }
687
688 static int
689 tmpfs_advlock (struct vop_advlock_args *ap)
690 {
691         struct tmpfs_node *node;
692         struct vnode *vp = ap->a_vp;
693
694         node = VP_TO_TMPFS_NODE(vp);
695
696         return (lf_advlock(ap, &node->tn_advlock, node->tn_size));
697 }
698
699
700 static int
701 tmpfs_strategy(struct vop_strategy_args *ap)
702 {
703         struct bio *bio = ap->a_bio;
704         struct buf *bp = bio->bio_buf;
705         struct vnode *vp = ap->a_vp;
706         struct tmpfs_node *node;
707         vm_object_t uobj;
708
709         if (vp->v_type != VREG) {
710                 bp->b_resid = bp->b_bcount;
711                 bp->b_flags |= B_ERROR | B_INVAL;
712                 bp->b_error = EINVAL;
713                 biodone(bio);
714                 return(0);
715         }
716
717         node = VP_TO_TMPFS_NODE(vp);
718
719         uobj = node->tn_reg.tn_aobj;
720
721         /*
722          * Call swap_pager_strategy to read or write between the VM
723          * object and the buffer cache.
724          */
725         swap_pager_strategy(uobj, bio);
726
727         return 0;
728 }
729
730 static int
731 tmpfs_bmap(struct vop_bmap_args *ap)
732 {
733         if (ap->a_doffsetp != NULL)
734                 *ap->a_doffsetp = ap->a_loffset;
735         if (ap->a_runp != NULL)
736                 *ap->a_runp = 0;
737         if (ap->a_runb != NULL)
738                 *ap->a_runb = 0;
739
740         return 0;
741 }
742
743 /* --------------------------------------------------------------------- */
744
745 static int
746 tmpfs_nremove(struct vop_nremove_args *v)
747 {
748         struct vnode *dvp = v->a_dvp;
749         struct namecache *ncp = v->a_nch->ncp;
750         struct vnode *vp;
751         int error;
752         struct tmpfs_dirent *de;
753         struct tmpfs_mount *tmp;
754         struct tmpfs_node *dnode;
755         struct tmpfs_node *node;
756
757         /*
758          * We have to acquire the vp from v->a_nch because
759          * we will likely unresolve the namecache entry, and
760          * a vrele is needed to trigger the tmpfs_inactive/tmpfs_reclaim
761          * sequence to recover space from the file.
762          */
763         error = cache_vref(v->a_nch, v->a_cred, &vp);
764         KKASSERT(error == 0);
765
766         if (vp->v_type == VDIR) {
767                 error = EISDIR;
768                 goto out;
769         }
770
771         dnode = VP_TO_TMPFS_DIR(dvp);
772         node = VP_TO_TMPFS_NODE(vp);
773         tmp = VFS_TO_TMPFS(vp->v_mount);
774         de = tmpfs_dir_lookup(dnode, node, ncp);
775         if (de == NULL) {
776                 error = ENOENT;
777                 goto out;
778         }
779
780         /* Files marked as immutable or append-only cannot be deleted. */
781         if ((node->tn_flags & (IMMUTABLE | APPEND | NOUNLINK)) ||
782             (dnode->tn_flags & APPEND)) {
783                 error = EPERM;
784                 goto out;
785         }
786
787         /* Remove the entry from the directory; as it is a file, we do not
788          * have to change the number of hard links of the directory. */
789         tmpfs_dir_detach(dnode, de);
790
791         /* Free the directory entry we just deleted.  Note that the node
792          * referred by it will not be removed until the vnode is really
793          * reclaimed. */
794         tmpfs_free_dirent(tmp, de);
795
796         if (node->tn_links > 0) {
797                 TMPFS_NODE_LOCK(node);
798                 node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
799                         TMPFS_NODE_MODIFIED;
800                 TMPFS_NODE_UNLOCK(node);
801         }
802
803         cache_setunresolved(v->a_nch);
804         cache_setvp(v->a_nch, NULL);
805         /*cache_inval_vp(vp, CINV_DESTROY);*/
806         error = 0;
807
808 out:
809         vrele(vp);
810
811         return error;
812 }
813
814 /* --------------------------------------------------------------------- */
815
816 static int
817 tmpfs_nlink(struct vop_nlink_args *v)
818 {
819         struct vnode *dvp = v->a_dvp;
820         struct vnode *vp = v->a_vp;
821         struct namecache *ncp = v->a_nch->ncp;
822         struct tmpfs_dirent *de;
823         struct tmpfs_node *node;
824         struct tmpfs_node *dnode;
825         int error;
826
827         KKASSERT(dvp != vp); /* XXX When can this be false? */
828
829         node = VP_TO_TMPFS_NODE(vp);
830         dnode = VP_TO_TMPFS_NODE(dvp);
831
832         /* XXX: Why aren't the following two tests done by the caller? */
833
834         /* Hard links of directories are forbidden. */
835         if (vp->v_type == VDIR) {
836                 error = EPERM;
837                 goto out;
838         }
839
840         /* Cannot create cross-device links. */
841         if (dvp->v_mount != vp->v_mount) {
842                 error = EXDEV;
843                 goto out;
844         }
845
846         /* Ensure that we do not overflow the maximum number of links imposed
847          * by the system. */
848         KKASSERT(node->tn_links <= LINK_MAX);
849         if (node->tn_links == LINK_MAX) {
850                 error = EMLINK;
851                 goto out;
852         }
853
854         /* We cannot create links of files marked immutable or append-only. */
855         if (node->tn_flags & (IMMUTABLE | APPEND)) {
856                 error = EPERM;
857                 goto out;
858         }
859
860         /* Allocate a new directory entry to represent the node. */
861         error = tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), node,
862             ncp->nc_name, ncp->nc_nlen, &de);
863         if (error != 0)
864                 goto out;
865
866         /* Insert the new directory entry into the appropriate directory. */
867         tmpfs_dir_attach(dnode, de);
868
869         /* vp link count has changed, so update node times. */
870
871         TMPFS_NODE_LOCK(node);
872         node->tn_status |= TMPFS_NODE_CHANGED;
873         TMPFS_NODE_UNLOCK(node);
874         tmpfs_update(vp);
875
876         cache_setunresolved(v->a_nch);
877         cache_setvp(v->a_nch, vp);
878         error = 0;
879
880 out:
881         return error;
882 }
883
884 /* --------------------------------------------------------------------- */
885
886 static int
887 tmpfs_nrename(struct vop_nrename_args *v)
888 {
889         struct vnode *fdvp = v->a_fdvp;
890         struct namecache *fncp = v->a_fnch->ncp;
891         struct vnode *fvp = fncp->nc_vp;
892         struct vnode *tdvp = v->a_tdvp;
893         struct namecache *tncp = v->a_tnch->ncp;
894         struct vnode *tvp = tncp->nc_vp;
895         struct tmpfs_dirent *de;
896         struct tmpfs_mount *tmp;
897         struct tmpfs_node *fdnode;
898         struct tmpfs_node *fnode;
899         struct tmpfs_node *tnode;
900         struct tmpfs_node *tdnode;
901         char *newname;
902         int error;
903
904         tnode = (tvp == NULL) ? NULL : VP_TO_TMPFS_NODE(tvp);
905
906         /* Disallow cross-device renames.
907          * XXX Why isn't this done by the caller? */
908         if (fvp->v_mount != tdvp->v_mount ||
909             (tvp != NULL && fvp->v_mount != tvp->v_mount)) {
910                 error = EXDEV;
911                 goto out;
912         }
913
914         tmp = VFS_TO_TMPFS(tdvp->v_mount);
915         tdnode = VP_TO_TMPFS_DIR(tdvp);
916
917         /* If source and target are the same file, there is nothing to do. */
918         if (fvp == tvp) {
919                 error = 0;
920                 goto out;
921         }
922
923         fdnode = VP_TO_TMPFS_DIR(fdvp);
924         fnode = VP_TO_TMPFS_NODE(fvp);
925         de = tmpfs_dir_lookup(fdnode, fnode, fncp);
926
927         /* Avoid manipulating '.' and '..' entries. */
928         if (de == NULL) {
929                 error = ENOENT;
930                 goto out_locked;
931         }
932         KKASSERT(de->td_node == fnode);
933
934         /* If re-naming a directory to another preexisting directory
935          * ensure that the target directory is empty so that its
936          * removal causes no side effects.
937          * Kern_rename gurantees the destination to be a directory
938          * if the source is one. */
939         if (tvp != NULL) {
940                 KKASSERT(tnode != NULL);
941
942                 if ((tnode->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
943                     (tdnode->tn_flags & (APPEND | IMMUTABLE))) {
944                         error = EPERM;
945                         goto out_locked;
946                 }
947
948                 if (fnode->tn_type == VDIR && tnode->tn_type == VDIR) {
949                         if (tnode->tn_size > 0) {
950                                 error = ENOTEMPTY;
951                                 goto out_locked;
952                         }
953                 } else if (fnode->tn_type == VDIR && tnode->tn_type != VDIR) {
954                         error = ENOTDIR;
955                         goto out_locked;
956                 } else if (fnode->tn_type != VDIR && tnode->tn_type == VDIR) {
957                         error = EISDIR;
958                         goto out_locked;
959                 } else {
960                         KKASSERT(fnode->tn_type != VDIR &&
961                                 tnode->tn_type != VDIR);
962                 }
963         }
964
965         if ((fnode->tn_flags & (NOUNLINK | IMMUTABLE | APPEND))
966             || (fdnode->tn_flags & (APPEND | IMMUTABLE))) {
967                 error = EPERM;
968                 goto out_locked;
969         }
970
971         /* Ensure that we have enough memory to hold the new name, if it
972          * has to be changed. */
973         if (fncp->nc_nlen != tncp->nc_nlen ||
974             bcmp(fncp->nc_name, tncp->nc_name, fncp->nc_nlen) != 0) {
975                 newname = kmalloc(tncp->nc_nlen + 1, M_TMPFSNAME, M_WAITOK);
976         } else
977                 newname = NULL;
978
979         /* If the node is being moved to another directory, we have to do
980          * the move. */
981         if (fdnode != tdnode) {
982                 /* In case we are moving a directory, we have to adjust its
983                  * parent to point to the new parent. */
984                 if (de->td_node->tn_type == VDIR) {
985                         struct tmpfs_node *n;
986
987                         /* Ensure the target directory is not a child of the
988                          * directory being moved.  Otherwise, we'd end up
989                          * with stale nodes. */
990                         n = tdnode;
991                         /* TMPFS_LOCK garanties that no nodes are freed while
992                          * traversing the list. Nodes can only be marked as
993                          * removed: tn_parent == NULL. */
994                         TMPFS_LOCK(tmp);
995                         TMPFS_NODE_LOCK(n);
996                         while (n != n->tn_dir.tn_parent) {
997                                 struct tmpfs_node *parent;
998
999                                 if (n == fnode) {
1000                                         TMPFS_NODE_UNLOCK(n);
1001                                         TMPFS_UNLOCK(tmp);
1002                                         error = EINVAL;
1003                                         if (newname != NULL)
1004                                                     kfree(newname, M_TMPFSNAME);
1005                                         goto out_locked;
1006                                 }
1007                                 parent = n->tn_dir.tn_parent;
1008                                 if (parent == NULL) {
1009                                         n = NULL;
1010                                         break;
1011                                 }
1012                                 TMPFS_NODE_LOCK(parent);
1013                                 if (parent->tn_dir.tn_parent == NULL) {
1014                                         TMPFS_NODE_UNLOCK(parent);
1015                                         n = NULL;
1016                                         break;
1017                                 }
1018                                 n = parent;
1019                         }
1020                         TMPFS_NODE_UNLOCK(n);
1021                         TMPFS_UNLOCK(tmp);
1022                         if (n == NULL) {
1023                                 error = EINVAL;
1024                                 if (newname != NULL)
1025                                             kfree(newname, M_TMPFSNAME);
1026                                 goto out_locked;
1027                         }
1028
1029                         /* Adjust the parent pointer. */
1030                         TMPFS_VALIDATE_DIR(fnode);
1031                         TMPFS_NODE_LOCK(de->td_node);
1032                         de->td_node->tn_dir.tn_parent = tdnode;
1033
1034                         /* As a result of changing the target of the '..'
1035                          * entry, the link count of the source and target
1036                          * directories has to be adjusted. */
1037                         TMPFS_NODE_LOCK(tdnode);
1038                         TMPFS_ASSERT_LOCKED(tdnode);
1039                         TMPFS_NODE_LOCK(fdnode);
1040                         TMPFS_ASSERT_LOCKED(fdnode);
1041
1042                         tdnode->tn_links++;
1043                         fdnode->tn_links--;
1044
1045                         TMPFS_NODE_UNLOCK(fdnode);
1046                         TMPFS_NODE_UNLOCK(tdnode);
1047                         TMPFS_NODE_UNLOCK(de->td_node);
1048                 }
1049
1050                 /* Do the move: just remove the entry from the source directory
1051                  * and insert it into the target one. */
1052                 tmpfs_dir_detach(fdnode, de);
1053                 tmpfs_dir_attach(tdnode, de);
1054         }
1055
1056         /* If the name has changed, we need to make it effective by changing
1057          * it in the directory entry. */
1058         if (newname != NULL) {
1059
1060                 kfree(de->td_name, M_TMPFSNAME);
1061                 de->td_namelen = (uint16_t)tncp->nc_nlen;
1062                 bcopy(tncp->nc_name, newname, tncp->nc_nlen);
1063                 newname[tncp->nc_nlen] = '\0';
1064                 de->td_name = newname;
1065
1066                 TMPFS_NODE_LOCK(tdnode);
1067                 TMPFS_NODE_LOCK(fdnode);
1068
1069                 fnode->tn_status |= TMPFS_NODE_CHANGED;
1070                 tdnode->tn_status |= TMPFS_NODE_MODIFIED;
1071
1072                 TMPFS_NODE_UNLOCK(fdnode);
1073                 TMPFS_NODE_UNLOCK(tdnode);
1074         }
1075
1076         /* If we are overwriting an entry, we have to remove the old one
1077          * from the target directory. */
1078         if (tvp != NULL) {
1079                 /* Remove the old entry from the target directory. */
1080                 de = tmpfs_dir_lookup(tdnode, tnode, tncp);
1081                 tmpfs_dir_detach(tdnode, de);
1082
1083                 /* Free the directory entry we just deleted.  Note that the
1084                  * node referred by it will not be removed until the vnode is
1085                  * really reclaimed. */
1086                 tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), de);
1087                 /*cache_inval_vp(tvp, CINV_DESTROY);*/
1088         }
1089
1090         cache_rename(v->a_fnch, v->a_tnch);
1091         error = 0;
1092
1093 out_locked:
1094         ;
1095
1096 out:
1097         /* Release target nodes. */
1098         /* XXX: I don't understand when tdvp can be the same as tvp, but
1099          * other code takes care of this... */
1100         if (tdvp == tvp)
1101                 vrele(tdvp);
1102
1103         return error;
1104 }
1105
1106 /* --------------------------------------------------------------------- */
1107
1108 static int
1109 tmpfs_nmkdir(struct vop_nmkdir_args *v)
1110 {
1111         struct vnode *dvp = v->a_dvp;
1112         struct vnode **vpp = v->a_vpp;
1113         struct namecache *ncp = v->a_nch->ncp;
1114         struct vattr *vap = v->a_vap;
1115         struct ucred *cred = v->a_cred;
1116         int error;
1117
1118         KKASSERT(vap->va_type == VDIR);
1119
1120         error = tmpfs_alloc_file(dvp, vpp, vap, ncp, cred, NULL);
1121         if (error == 0) {
1122                 cache_setunresolved(v->a_nch);
1123                 cache_setvp(v->a_nch, *vpp);
1124         }
1125
1126         return error;
1127 }
1128
1129 /* --------------------------------------------------------------------- */
1130
1131 static int
1132 tmpfs_nrmdir(struct vop_nrmdir_args *v)
1133 {
1134         struct vnode *dvp = v->a_dvp;
1135         struct namecache *ncp = v->a_nch->ncp;
1136         struct vnode *vp;
1137
1138         int error;
1139         struct tmpfs_dirent *de;
1140         struct tmpfs_mount *tmp;
1141         struct tmpfs_node *dnode;
1142         struct tmpfs_node *node;
1143
1144         /*
1145          * We have to acquire the vp from v->a_nch because
1146          * we will likely unresolve the namecache entry, and
1147          * a vrele is needed to trigger the tmpfs_inactive/tmpfs_reclaim
1148          * sequence.
1149          */
1150         error = cache_vref(v->a_nch, v->a_cred, &vp);
1151         KKASSERT(error == 0);
1152
1153         tmp = VFS_TO_TMPFS(dvp->v_mount);
1154         dnode = VP_TO_TMPFS_DIR(dvp);
1155         node = VP_TO_TMPFS_DIR(vp);
1156
1157         /* Directories with more than two entries ('.' and '..') cannot be
1158          * removed. */
1159          if (node->tn_size > 0) {
1160                  error = ENOTEMPTY;
1161                  goto out;
1162          }
1163
1164         if ((dnode->tn_flags & APPEND)
1165             || (node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
1166                 error = EPERM;
1167                 goto out;
1168         }
1169
1170         /* This invariant holds only if we are not trying to remove "..".
1171           * We checked for that above so this is safe now. */
1172         KKASSERT(node->tn_dir.tn_parent == dnode);
1173
1174         /* Get the directory entry associated with node (vp).  This was
1175          * filled by tmpfs_lookup while looking up the entry. */
1176         de = tmpfs_dir_lookup(dnode, node, ncp);
1177         KKASSERT(TMPFS_DIRENT_MATCHES(de,
1178             ncp->nc_name,
1179             ncp->nc_nlen));
1180
1181         /* Check flags to see if we are allowed to remove the directory. */
1182         if (dnode->tn_flags & APPEND
1183                 || node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) {
1184                 error = EPERM;
1185                 goto out;
1186         }
1187
1188
1189         /* Detach the directory entry from the directory (dnode). */
1190         tmpfs_dir_detach(dnode, de);
1191
1192         /* No vnode should be allocated for this entry from this point */
1193         TMPFS_NODE_LOCK(node);
1194         TMPFS_ASSERT_ELOCKED(node);
1195         TMPFS_NODE_LOCK(dnode);
1196         TMPFS_ASSERT_ELOCKED(dnode);
1197
1198 #if 0
1199         /* handled by tmpfs_free_node */
1200         KKASSERT(node->tn_links > 0);
1201         node->tn_links--;
1202         node->tn_dir.tn_parent = NULL;
1203 #endif
1204         node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
1205             TMPFS_NODE_MODIFIED;
1206
1207 #if 0
1208         /* handled by tmpfs_free_node */
1209         KKASSERT(dnode->tn_links > 0);
1210         dnode->tn_links--;
1211 #endif
1212         dnode->tn_status |= TMPFS_NODE_ACCESSED | \
1213             TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
1214
1215         TMPFS_NODE_UNLOCK(dnode);
1216         TMPFS_NODE_UNLOCK(node);
1217
1218         /* Free the directory entry we just deleted.  Note that the node
1219          * referred by it will not be removed until the vnode is really
1220          * reclaimed. */
1221         tmpfs_free_dirent(tmp, de);
1222
1223         /* Release the deleted vnode (will destroy the node, notify
1224          * interested parties and clean it from the cache). */
1225
1226         TMPFS_NODE_LOCK(dnode);
1227         dnode->tn_status |= TMPFS_NODE_CHANGED;
1228         TMPFS_NODE_UNLOCK(dnode);
1229         tmpfs_update(dvp);
1230
1231         cache_setunresolved(v->a_nch);
1232         cache_setvp(v->a_nch, NULL);
1233         /*cache_inval_vp(vp, CINV_DESTROY);*/
1234         error = 0;
1235
1236 out:
1237         vrele(vp);
1238
1239         return error;
1240 }
1241
1242 /* --------------------------------------------------------------------- */
1243
1244 static int
1245 tmpfs_nsymlink(struct vop_nsymlink_args *v)
1246 {
1247         struct vnode *dvp = v->a_dvp;
1248         struct vnode **vpp = v->a_vpp;
1249         struct namecache *ncp = v->a_nch->ncp;
1250         struct vattr *vap = v->a_vap;
1251         struct ucred *cred = v->a_cred;
1252         char *target = v->a_target;
1253         int error;
1254
1255         vap->va_type = VLNK;
1256         error = tmpfs_alloc_file(dvp, vpp, vap, ncp, cred, target);
1257         if (error == 0) {
1258                 cache_setunresolved(v->a_nch);
1259                 cache_setvp(v->a_nch, *vpp);
1260         }
1261
1262         return error;
1263 }
1264
1265 /* --------------------------------------------------------------------- */
1266
1267 static int
1268 tmpfs_readdir(struct vop_readdir_args *v)
1269 {
1270         struct vnode *vp = v->a_vp;
1271         struct uio *uio = v->a_uio;
1272         int *eofflag = v->a_eofflag;
1273         off_t **cookies = v->a_cookies;
1274         int *ncookies = v->a_ncookies;
1275         struct tmpfs_mount *tmp;
1276         int error;
1277         off_t startoff;
1278         off_t cnt = 0;
1279         struct tmpfs_node *node;
1280
1281         /* This operation only makes sense on directory nodes. */
1282         if (vp->v_type != VDIR)
1283                 return ENOTDIR;
1284
1285         tmp = VFS_TO_TMPFS(vp->v_mount);
1286         node = VP_TO_TMPFS_DIR(vp);
1287         startoff = uio->uio_offset;
1288
1289         if (uio->uio_offset == TMPFS_DIRCOOKIE_DOT) {
1290                 error = tmpfs_dir_getdotdent(node, uio);
1291                 if (error != 0)
1292                         goto outok;
1293                 cnt++;
1294         }
1295
1296         if (uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT) {
1297                 error = tmpfs_dir_getdotdotdent(tmp, node, uio);
1298                 if (error != 0)
1299                         goto outok;
1300                 cnt++;
1301         }
1302
1303         error = tmpfs_dir_getdents(node, uio, &cnt);
1304
1305 outok:
1306         KKASSERT(error >= -1);
1307
1308         if (error == -1)
1309                 error = 0;
1310
1311         if (eofflag != NULL)
1312                 *eofflag =
1313                     (error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF);
1314
1315         /* Update NFS-related variables. */
1316         if (error == 0 && cookies != NULL && ncookies != NULL) {
1317                 off_t i;
1318                 off_t off = startoff;
1319                 struct tmpfs_dirent *de = NULL;
1320
1321                 *ncookies = cnt;
1322                 *cookies = kmalloc(cnt * sizeof(off_t), M_TEMP, M_WAITOK);
1323
1324                 for (i = 0; i < cnt; i++) {
1325                         KKASSERT(off != TMPFS_DIRCOOKIE_EOF);
1326                         if (off == TMPFS_DIRCOOKIE_DOT) {
1327                                 off = TMPFS_DIRCOOKIE_DOTDOT;
1328                         } else {
1329                                 if (off == TMPFS_DIRCOOKIE_DOTDOT) {
1330                                         de = TAILQ_FIRST(&node->tn_dir.tn_dirhead);
1331                                 } else if (de != NULL) {
1332                                         de = TAILQ_NEXT(de, td_entries);
1333                                 } else {
1334                                         de = tmpfs_dir_lookupbycookie(node,
1335                                             off);
1336                                         KKASSERT(de != NULL);
1337                                         de = TAILQ_NEXT(de, td_entries);
1338                                 }
1339                                 if (de == NULL)
1340                                         off = TMPFS_DIRCOOKIE_EOF;
1341                                 else
1342                                         off = tmpfs_dircookie(de);
1343                         }
1344
1345                         (*cookies)[i] = off;
1346                 }
1347                 KKASSERT(uio->uio_offset == off);
1348         }
1349
1350         return error;
1351 }
1352
1353 /* --------------------------------------------------------------------- */
1354
1355 static int
1356 tmpfs_readlink(struct vop_readlink_args *v)
1357 {
1358         struct vnode *vp = v->a_vp;
1359         struct uio *uio = v->a_uio;
1360
1361         int error;
1362         struct tmpfs_node *node;
1363
1364         KKASSERT(uio->uio_offset == 0);
1365         KKASSERT(vp->v_type == VLNK);
1366
1367         node = VP_TO_TMPFS_NODE(vp);
1368
1369         error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid),
1370             uio);
1371         TMPFS_NODE_LOCK(node);
1372         node->tn_status |= TMPFS_NODE_ACCESSED;
1373         TMPFS_NODE_UNLOCK(node);
1374
1375         return error;
1376 }
1377
1378 /* --------------------------------------------------------------------- */
1379
1380 static int
1381 tmpfs_inactive(struct vop_inactive_args *v)
1382 {
1383         struct vnode *vp = v->a_vp;
1384
1385         struct tmpfs_node *node;
1386
1387         node = VP_TO_TMPFS_NODE(vp);
1388
1389         /*
1390          * Get rid of unreferenced deleted vnodes sooner rather than
1391          * later so the data memory can be recovered immediately.
1392          */
1393         TMPFS_NODE_LOCK(node);
1394         if (node->tn_links == 0 &&
1395             (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0) {
1396                 node->tn_vpstate = TMPFS_VNODE_DOOMED;
1397                 TMPFS_NODE_UNLOCK(node);
1398                 vrecycle(vp);
1399         } else {
1400                 TMPFS_NODE_UNLOCK(node);
1401         }
1402
1403         return 0;
1404 }
1405
1406 /* --------------------------------------------------------------------- */
1407
1408 int
1409 tmpfs_reclaim(struct vop_reclaim_args *v)
1410 {
1411         struct vnode *vp = v->a_vp;
1412         struct tmpfs_mount *tmp;
1413         struct tmpfs_node *node;
1414
1415         node = VP_TO_TMPFS_NODE(vp);
1416         tmp = VFS_TO_TMPFS(vp->v_mount);
1417
1418         tmpfs_free_vp(vp);
1419
1420         /* If the node referenced by this vnode was deleted by the user,
1421          * we must free its associated data structures (now that the vnode
1422          * is being reclaimed). */
1423         TMPFS_NODE_LOCK(node);
1424         if (node->tn_links == 0 &&
1425             (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0) {
1426                 node->tn_vpstate = TMPFS_VNODE_DOOMED;
1427                 tmpfs_free_node(tmp, node);
1428                 /* eats the lock */
1429         } else {
1430                 TMPFS_NODE_UNLOCK(node);
1431         }
1432
1433         KKASSERT(vp->v_data == NULL);
1434         return 0;
1435 }
1436
1437 /* --------------------------------------------------------------------- */
1438
1439 static int
1440 tmpfs_print(struct vop_print_args *v)
1441 {
1442         struct vnode *vp = v->a_vp;
1443
1444         struct tmpfs_node *node;
1445
1446         node = VP_TO_TMPFS_NODE(vp);
1447
1448         kprintf("tag VT_TMPFS, tmpfs_node %p, flags 0x%x, links %d\n",
1449             node, node->tn_flags, node->tn_links);
1450         kprintf("\tmode 0%o, owner %d, group %d, size %ju, status 0x%x\n",
1451             node->tn_mode, node->tn_uid, node->tn_gid,
1452             (uintmax_t)node->tn_size, node->tn_status);
1453
1454         if (vp->v_type == VFIFO)
1455                 fifo_printinfo(vp);
1456
1457         kprintf("\n");
1458
1459         return 0;
1460 }
1461
1462 /* --------------------------------------------------------------------- */
1463
1464 static int
1465 tmpfs_pathconf(struct vop_pathconf_args *v)
1466 {
1467         int name = v->a_name;
1468         register_t *retval = v->a_retval;
1469
1470         int error;
1471
1472         error = 0;
1473
1474         switch (name) {
1475         case _PC_LINK_MAX:
1476                 *retval = LINK_MAX;
1477                 break;
1478
1479         case _PC_NAME_MAX:
1480                 *retval = NAME_MAX;
1481                 break;
1482
1483         case _PC_PATH_MAX:
1484                 *retval = PATH_MAX;
1485                 break;
1486
1487         case _PC_PIPE_BUF:
1488                 *retval = PIPE_BUF;
1489                 break;
1490
1491         case _PC_CHOWN_RESTRICTED:
1492                 *retval = 1;
1493                 break;
1494
1495         case _PC_NO_TRUNC:
1496                 *retval = 1;
1497                 break;
1498
1499         case _PC_SYNC_IO:
1500                 *retval = 1;
1501                 break;
1502
1503         case _PC_FILESIZEBITS:
1504                 *retval = 0; /* XXX Don't know which value should I return. */
1505                 break;
1506
1507         default:
1508                 error = EINVAL;
1509         }
1510
1511         return error;
1512 }
1513
1514 /* --------------------------------------------------------------------- */
1515
1516 /*
1517  * vnode operations vector used for files stored in a tmpfs file system.
1518  */
1519 struct vop_ops tmpfs_vnode_vops = {
1520         .vop_default =                  vop_defaultop,
1521         .vop_getpages =                 vop_stdgetpages,
1522         .vop_putpages =                 vop_stdputpages,
1523         .vop_ncreate =                  tmpfs_ncreate,
1524         .vop_nresolve =                 tmpfs_nresolve,
1525         .vop_nlookupdotdot =            tmpfs_nlookupdotdot,
1526         .vop_nmknod =                   tmpfs_nmknod,
1527         .vop_open =                     tmpfs_open,
1528         .vop_close =                    tmpfs_close,
1529         .vop_access =                   tmpfs_access,
1530         .vop_getattr =                  tmpfs_getattr,
1531         .vop_setattr =                  tmpfs_setattr,
1532         .vop_read =                     tmpfs_read,
1533         .vop_write =                    tmpfs_write,
1534         .vop_fsync =                    tmpfs_fsync,
1535         .vop_nremove =                  tmpfs_nremove,
1536         .vop_nlink =                    tmpfs_nlink,
1537         .vop_nrename =                  tmpfs_nrename,
1538         .vop_nmkdir =                   tmpfs_nmkdir,
1539         .vop_nrmdir =                   tmpfs_nrmdir,
1540         .vop_nsymlink =                 tmpfs_nsymlink,
1541         .vop_readdir =                  tmpfs_readdir,
1542         .vop_readlink =                 tmpfs_readlink,
1543         .vop_inactive =                 tmpfs_inactive,
1544         .vop_reclaim =                  tmpfs_reclaim,
1545         .vop_print =                    tmpfs_print,
1546         .vop_pathconf =                 tmpfs_pathconf,
1547         .vop_bmap =                     tmpfs_bmap,
1548         .vop_bmap =                     (void *)vop_eopnotsupp,
1549         .vop_strategy =                 tmpfs_strategy,
1550         .vop_advlock =                  tmpfs_advlock,
1551 };