]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/fs/tmpfs/tmpfs_subr.c
vm_ooffset_t is now unsigned
[FreeBSD/FreeBSD.git] / sys / fs / tmpfs / tmpfs_subr.c
1 /*      $NetBSD: tmpfs_subr.c,v 1.35 2007/07/09 21:10:50 ad Exp $       */
2
3 /*-
4  * SPDX-License-Identifier: BSD-2-Clause-NetBSD
5  *
6  * Copyright (c) 2005 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
11  * 2005 program.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 /*
36  * Efficient memory file system supporting functions.
37  */
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/dirent.h>
44 #include <sys/fnv_hash.h>
45 #include <sys/lock.h>
46 #include <sys/limits.h>
47 #include <sys/mount.h>
48 #include <sys/namei.h>
49 #include <sys/priv.h>
50 #include <sys/proc.h>
51 #include <sys/random.h>
52 #include <sys/refcount.h>
53 #include <sys/rwlock.h>
54 #include <sys/smr.h>
55 #include <sys/stat.h>
56 #include <sys/sysctl.h>
57 #include <sys/vnode.h>
58 #include <sys/vmmeter.h>
59
60 #include <vm/vm.h>
61 #include <vm/vm_param.h>
62 #include <vm/vm_object.h>
63 #include <vm/vm_page.h>
64 #include <vm/vm_pageout.h>
65 #include <vm/vm_pager.h>
66 #include <vm/vm_extern.h>
67 #include <vm/swap_pager.h>
68
69 #include <fs/tmpfs/tmpfs.h>
70 #include <fs/tmpfs/tmpfs_fifoops.h>
71 #include <fs/tmpfs/tmpfs_vnops.h>
72
73 SYSCTL_NODE(_vfs, OID_AUTO, tmpfs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
74     "tmpfs file system");
75
76 static long tmpfs_pages_reserved = TMPFS_PAGES_MINRESERVED;
77
78 static uma_zone_t tmpfs_dirent_pool;
79 static uma_zone_t tmpfs_node_pool;
80 VFS_SMR_DECLARE;
81
82 static int
83 tmpfs_node_ctor(void *mem, int size, void *arg, int flags)
84 {
85         struct tmpfs_node *node;
86
87         node = mem;
88         node->tn_gen++;
89         node->tn_size = 0;
90         node->tn_status = 0;
91         node->tn_accessed = false;
92         node->tn_flags = 0;
93         node->tn_links = 0;
94         node->tn_vnode = NULL;
95         node->tn_vpstate = 0;
96         return (0);
97 }
98
99 static void
100 tmpfs_node_dtor(void *mem, int size, void *arg)
101 {
102         struct tmpfs_node *node;
103
104         node = mem;
105         node->tn_type = VNON;
106 }
107
108 static int
109 tmpfs_node_init(void *mem, int size, int flags)
110 {
111         struct tmpfs_node *node;
112
113         node = mem;
114         node->tn_id = 0;
115         mtx_init(&node->tn_interlock, "tmpfsni", NULL, MTX_DEF);
116         node->tn_gen = arc4random();
117         return (0);
118 }
119
120 static void
121 tmpfs_node_fini(void *mem, int size)
122 {
123         struct tmpfs_node *node;
124
125         node = mem;
126         mtx_destroy(&node->tn_interlock);
127 }
128
129 void
130 tmpfs_subr_init(void)
131 {
132         tmpfs_dirent_pool = uma_zcreate("TMPFS dirent",
133             sizeof(struct tmpfs_dirent), NULL, NULL, NULL, NULL,
134             UMA_ALIGN_PTR, 0);
135         tmpfs_node_pool = uma_zcreate("TMPFS node",
136             sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor,
137             tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0);
138         VFS_SMR_ZONE_SET(tmpfs_node_pool);
139 }
140
141 void
142 tmpfs_subr_uninit(void)
143 {
144         uma_zdestroy(tmpfs_node_pool);
145         uma_zdestroy(tmpfs_dirent_pool);
146 }
147
148 static int
149 sysctl_mem_reserved(SYSCTL_HANDLER_ARGS)
150 {
151         int error;
152         long pages, bytes;
153
154         pages = *(long *)arg1;
155         bytes = pages * PAGE_SIZE;
156
157         error = sysctl_handle_long(oidp, &bytes, 0, req);
158         if (error || !req->newptr)
159                 return (error);
160
161         pages = bytes / PAGE_SIZE;
162         if (pages < TMPFS_PAGES_MINRESERVED)
163                 return (EINVAL);
164
165         *(long *)arg1 = pages;
166         return (0);
167 }
168
169 SYSCTL_PROC(_vfs_tmpfs, OID_AUTO, memory_reserved,
170     CTLTYPE_LONG|CTLFLAG_MPSAFE|CTLFLAG_RW, &tmpfs_pages_reserved, 0,
171     sysctl_mem_reserved, "L",
172     "Amount of available memory and swap below which tmpfs growth stops");
173
174 static __inline int tmpfs_dirtree_cmp(struct tmpfs_dirent *a,
175     struct tmpfs_dirent *b);
176 RB_PROTOTYPE_STATIC(tmpfs_dir, tmpfs_dirent, uh.td_entries, tmpfs_dirtree_cmp);
177
178 size_t
179 tmpfs_mem_avail(void)
180 {
181         size_t avail;
182         long reserved;
183
184         avail = swap_pager_avail + vm_free_count();
185         reserved = atomic_load_long(&tmpfs_pages_reserved);
186         if (__predict_false(avail < reserved))
187                 return (0);
188         return (avail - reserved);
189 }
190
191 size_t
192 tmpfs_pages_used(struct tmpfs_mount *tmp)
193 {
194         const size_t node_size = sizeof(struct tmpfs_node) +
195             sizeof(struct tmpfs_dirent);
196         size_t meta_pages;
197
198         meta_pages = howmany((uintmax_t)tmp->tm_nodes_inuse * node_size,
199             PAGE_SIZE);
200         return (meta_pages + tmp->tm_pages_used);
201 }
202
203 static size_t
204 tmpfs_pages_check_avail(struct tmpfs_mount *tmp, size_t req_pages)
205 {
206         if (tmpfs_mem_avail() < req_pages)
207                 return (0);
208
209         if (tmp->tm_pages_max != ULONG_MAX &&
210             tmp->tm_pages_max < req_pages + tmpfs_pages_used(tmp))
211                         return (0);
212
213         return (1);
214 }
215
216 void
217 tmpfs_ref_node(struct tmpfs_node *node)
218 {
219 #ifdef INVARIANTS
220         u_int old;
221
222         old =
223 #endif
224         refcount_acquire(&node->tn_refcount);
225 #ifdef INVARIANTS
226         KASSERT(old > 0, ("node %p zero refcount", node));
227 #endif
228 }
229
230 /*
231  * Allocates a new node of type 'type' inside the 'tmp' mount point, with
232  * its owner set to 'uid', its group to 'gid' and its mode set to 'mode',
233  * using the credentials of the process 'p'.
234  *
235  * If the node type is set to 'VDIR', then the parent parameter must point
236  * to the parent directory of the node being created.  It may only be NULL
237  * while allocating the root node.
238  *
239  * If the node type is set to 'VBLK' or 'VCHR', then the rdev parameter
240  * specifies the device the node represents.
241  *
242  * If the node type is set to 'VLNK', then the parameter target specifies
243  * the file name of the target file for the symbolic link that is being
244  * created.
245  *
246  * Note that new nodes are retrieved from the available list if it has
247  * items or, if it is empty, from the node pool as long as there is enough
248  * space to create them.
249  *
250  * Returns zero on success or an appropriate error code on failure.
251  */
252 int
253 tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type,
254     uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *parent,
255     const char *target, dev_t rdev, struct tmpfs_node **node)
256 {
257         struct tmpfs_node *nnode;
258         vm_object_t obj;
259
260         /* If the root directory of the 'tmp' file system is not yet
261          * allocated, this must be the request to do it. */
262         MPASS(IMPLIES(tmp->tm_root == NULL, parent == NULL && type == VDIR));
263
264         MPASS(IFF(type == VLNK, target != NULL));
265         MPASS(IFF(type == VBLK || type == VCHR, rdev != VNOVAL));
266
267         if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max)
268                 return (ENOSPC);
269         if (tmpfs_pages_check_avail(tmp, 1) == 0)
270                 return (ENOSPC);
271
272         if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) {
273                 /*
274                  * When a new tmpfs node is created for fully
275                  * constructed mount point, there must be a parent
276                  * node, which vnode is locked exclusively.  As
277                  * consequence, if the unmount is executing in
278                  * parallel, vflush() cannot reclaim the parent vnode.
279                  * Due to this, the check for MNTK_UNMOUNT flag is not
280                  * racy: if we did not see MNTK_UNMOUNT flag, then tmp
281                  * cannot be destroyed until node construction is
282                  * finished and the parent vnode unlocked.
283                  *
284                  * Tmpfs does not need to instantiate new nodes during
285                  * unmount.
286                  */
287                 return (EBUSY);
288         }
289         if ((mp->mnt_kern_flag & MNT_RDONLY) != 0)
290                 return (EROFS);
291
292         nnode = uma_zalloc_smr(tmpfs_node_pool, M_WAITOK);
293
294         /* Generic initialization. */
295         nnode->tn_type = type;
296         vfs_timestamp(&nnode->tn_atime);
297         nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime =
298             nnode->tn_atime;
299         nnode->tn_uid = uid;
300         nnode->tn_gid = gid;
301         nnode->tn_mode = mode;
302         nnode->tn_id = alloc_unr64(&tmp->tm_ino_unr);
303         nnode->tn_refcount = 1;
304
305         /* Type-specific initialization. */
306         switch (nnode->tn_type) {
307         case VBLK:
308         case VCHR:
309                 nnode->tn_rdev = rdev;
310                 break;
311
312         case VDIR:
313                 RB_INIT(&nnode->tn_dir.tn_dirhead);
314                 LIST_INIT(&nnode->tn_dir.tn_dupindex);
315                 MPASS(parent != nnode);
316                 MPASS(IMPLIES(parent == NULL, tmp->tm_root == NULL));
317                 nnode->tn_dir.tn_parent = (parent == NULL) ? nnode : parent;
318                 nnode->tn_dir.tn_readdir_lastn = 0;
319                 nnode->tn_dir.tn_readdir_lastp = NULL;
320                 nnode->tn_links++;
321                 TMPFS_NODE_LOCK(nnode->tn_dir.tn_parent);
322                 nnode->tn_dir.tn_parent->tn_links++;
323                 TMPFS_NODE_UNLOCK(nnode->tn_dir.tn_parent);
324                 break;
325
326         case VFIFO:
327                 /* FALLTHROUGH */
328         case VSOCK:
329                 break;
330
331         case VLNK:
332                 MPASS(strlen(target) < MAXPATHLEN);
333                 nnode->tn_size = strlen(target);
334                 nnode->tn_link = malloc(nnode->tn_size, M_TMPFSNAME,
335                     M_WAITOK);
336                 memcpy(nnode->tn_link, target, nnode->tn_size);
337                 break;
338
339         case VREG:
340                 obj = nnode->tn_reg.tn_aobj =
341                     vm_pager_allocate(OBJT_SWAP, NULL, 0, VM_PROT_DEFAULT, 0,
342                         NULL /* XXXKIB - tmpfs needs swap reservation */);
343                 VM_OBJECT_WLOCK(obj);
344                 /* OBJ_TMPFS is set together with the setting of vp->v_object */
345                 vm_object_set_flag(obj, OBJ_TMPFS_NODE);
346                 VM_OBJECT_WUNLOCK(obj);
347                 nnode->tn_reg.tn_tmp = tmp;
348                 break;
349
350         default:
351                 panic("tmpfs_alloc_node: type %p %d", nnode,
352                     (int)nnode->tn_type);
353         }
354
355         TMPFS_LOCK(tmp);
356         LIST_INSERT_HEAD(&tmp->tm_nodes_used, nnode, tn_entries);
357         nnode->tn_attached = true;
358         tmp->tm_nodes_inuse++;
359         tmp->tm_refcount++;
360         TMPFS_UNLOCK(tmp);
361
362         *node = nnode;
363         return (0);
364 }
365
366 /*
367  * Destroys the node pointed to by node from the file system 'tmp'.
368  * If the node references a directory, no entries are allowed.
369  */
370 void
371 tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
372 {
373         if (refcount_release_if_not_last(&node->tn_refcount))
374                 return;
375
376         TMPFS_LOCK(tmp);
377         TMPFS_NODE_LOCK(node);
378         if (!tmpfs_free_node_locked(tmp, node, false)) {
379                 TMPFS_NODE_UNLOCK(node);
380                 TMPFS_UNLOCK(tmp);
381         }
382 }
383
384 bool
385 tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
386     bool detach)
387 {
388         vm_object_t uobj;
389         bool last;
390
391         TMPFS_MP_ASSERT_LOCKED(tmp);
392         TMPFS_NODE_ASSERT_LOCKED(node);
393
394         last = refcount_release(&node->tn_refcount);
395         if (node->tn_attached && (detach || last)) {
396                 MPASS(tmp->tm_nodes_inuse > 0);
397                 tmp->tm_nodes_inuse--;
398                 LIST_REMOVE(node, tn_entries);
399                 node->tn_attached = false;
400         }
401         if (!last)
402                 return (false);
403
404 #ifdef INVARIANTS
405         MPASS(node->tn_vnode == NULL);
406         MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0);
407 #endif
408         TMPFS_NODE_UNLOCK(node);
409         TMPFS_UNLOCK(tmp);
410
411         switch (node->tn_type) {
412         case VBLK:
413                 /* FALLTHROUGH */
414         case VCHR:
415                 /* FALLTHROUGH */
416         case VDIR:
417                 /* FALLTHROUGH */
418         case VFIFO:
419                 /* FALLTHROUGH */
420         case VSOCK:
421                 break;
422
423         case VLNK:
424                 free(node->tn_link, M_TMPFSNAME);
425                 break;
426
427         case VREG:
428                 uobj = node->tn_reg.tn_aobj;
429                 if (uobj != NULL) {
430                         if (uobj->size != 0)
431                                 atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
432                         KASSERT((uobj->flags & OBJ_TMPFS) == 0,
433                             ("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj));
434                         vm_object_deallocate(uobj);
435                 }
436                 break;
437
438         default:
439                 panic("tmpfs_free_node: type %p %d", node, (int)node->tn_type);
440         }
441
442         uma_zfree_smr(tmpfs_node_pool, node);
443         TMPFS_LOCK(tmp);
444         tmpfs_free_tmp(tmp);
445         return (true);
446 }
447
448 static __inline uint32_t
449 tmpfs_dirent_hash(const char *name, u_int len)
450 {
451         uint32_t hash;
452
453         hash = fnv_32_buf(name, len, FNV1_32_INIT + len) & TMPFS_DIRCOOKIE_MASK;
454 #ifdef TMPFS_DEBUG_DIRCOOKIE_DUP
455         hash &= 0xf;
456 #endif
457         if (hash < TMPFS_DIRCOOKIE_MIN)
458                 hash += TMPFS_DIRCOOKIE_MIN;
459
460         return (hash);
461 }
462
463 static __inline off_t
464 tmpfs_dirent_cookie(struct tmpfs_dirent *de)
465 {
466         if (de == NULL)
467                 return (TMPFS_DIRCOOKIE_EOF);
468
469         MPASS(de->td_cookie >= TMPFS_DIRCOOKIE_MIN);
470
471         return (de->td_cookie);
472 }
473
474 static __inline boolean_t
475 tmpfs_dirent_dup(struct tmpfs_dirent *de)
476 {
477         return ((de->td_cookie & TMPFS_DIRCOOKIE_DUP) != 0);
478 }
479
480 static __inline boolean_t
481 tmpfs_dirent_duphead(struct tmpfs_dirent *de)
482 {
483         return ((de->td_cookie & TMPFS_DIRCOOKIE_DUPHEAD) != 0);
484 }
485
486 void
487 tmpfs_dirent_init(struct tmpfs_dirent *de, const char *name, u_int namelen)
488 {
489         de->td_hash = de->td_cookie = tmpfs_dirent_hash(name, namelen);
490         memcpy(de->ud.td_name, name, namelen);
491         de->td_namelen = namelen;
492 }
493
494 /*
495  * Allocates a new directory entry for the node node with a name of name.
496  * The new directory entry is returned in *de.
497  *
498  * The link count of node is increased by one to reflect the new object
499  * referencing it.
500  *
501  * Returns zero on success or an appropriate error code on failure.
502  */
503 int
504 tmpfs_alloc_dirent(struct tmpfs_mount *tmp, struct tmpfs_node *node,
505     const char *name, u_int len, struct tmpfs_dirent **de)
506 {
507         struct tmpfs_dirent *nde;
508
509         nde = uma_zalloc(tmpfs_dirent_pool, M_WAITOK);
510         nde->td_node = node;
511         if (name != NULL) {
512                 nde->ud.td_name = malloc(len, M_TMPFSNAME, M_WAITOK);
513                 tmpfs_dirent_init(nde, name, len);
514         } else
515                 nde->td_namelen = 0;
516         if (node != NULL)
517                 node->tn_links++;
518
519         *de = nde;
520
521         return 0;
522 }
523
524 /*
525  * Frees a directory entry.  It is the caller's responsibility to destroy
526  * the node referenced by it if needed.
527  *
528  * The link count of node is decreased by one to reflect the removal of an
529  * object that referenced it.  This only happens if 'node_exists' is true;
530  * otherwise the function will not access the node referred to by the
531  * directory entry, as it may already have been released from the outside.
532  */
533 void
534 tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de)
535 {
536         struct tmpfs_node *node;
537
538         node = de->td_node;
539         if (node != NULL) {
540                 MPASS(node->tn_links > 0);
541                 node->tn_links--;
542         }
543         if (!tmpfs_dirent_duphead(de) && de->ud.td_name != NULL)
544                 free(de->ud.td_name, M_TMPFSNAME);
545         uma_zfree(tmpfs_dirent_pool, de);
546 }
547
548 void
549 tmpfs_destroy_vobject(struct vnode *vp, vm_object_t obj)
550 {
551
552         ASSERT_VOP_ELOCKED(vp, "tmpfs_destroy_vobject");
553         if (vp->v_type != VREG || obj == NULL)
554                 return;
555
556         VM_OBJECT_WLOCK(obj);
557         VI_LOCK(vp);
558         vm_object_clear_flag(obj, OBJ_TMPFS);
559         obj->un_pager.swp.swp_tmpfs = NULL;
560         if (vp->v_writecount < 0)
561                 vp->v_writecount = 0;
562         VI_UNLOCK(vp);
563         VM_OBJECT_WUNLOCK(obj);
564 }
565
566 /*
567  * Need to clear v_object for insmntque failure.
568  */
569 static void
570 tmpfs_insmntque_dtr(struct vnode *vp, void *dtr_arg)
571 {
572
573         tmpfs_destroy_vobject(vp, vp->v_object);
574         vp->v_object = NULL;
575         vp->v_data = NULL;
576         vp->v_op = &dead_vnodeops;
577         vgone(vp);
578         vput(vp);
579 }
580
581 /*
582  * Allocates a new vnode for the node node or returns a new reference to
583  * an existing one if the node had already a vnode referencing it.  The
584  * resulting locked vnode is returned in *vpp.
585  *
586  * Returns zero on success or an appropriate error code on failure.
587  */
588 int
589 tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
590     struct vnode **vpp)
591 {
592         struct vnode *vp;
593         enum vgetstate vs;
594         struct tmpfs_mount *tm;
595         vm_object_t object;
596         int error;
597
598         error = 0;
599         tm = VFS_TO_TMPFS(mp);
600         TMPFS_NODE_LOCK(node);
601         tmpfs_ref_node(node);
602 loop:
603         TMPFS_NODE_ASSERT_LOCKED(node);
604         if ((vp = node->tn_vnode) != NULL) {
605                 MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0);
606                 if ((node->tn_type == VDIR && node->tn_dir.tn_parent == NULL) ||
607                     (VN_IS_DOOMED(vp) &&
608                      (lkflag & LK_NOWAIT) != 0)) {
609                         TMPFS_NODE_UNLOCK(node);
610                         error = ENOENT;
611                         vp = NULL;
612                         goto out;
613                 }
614                 if (VN_IS_DOOMED(vp)) {
615                         node->tn_vpstate |= TMPFS_VNODE_WRECLAIM;
616                         while ((node->tn_vpstate & TMPFS_VNODE_WRECLAIM) != 0) {
617                                 msleep(&node->tn_vnode, TMPFS_NODE_MTX(node),
618                                     0, "tmpfsE", 0);
619                         }
620                         goto loop;
621                 }
622                 vs = vget_prep(vp);
623                 TMPFS_NODE_UNLOCK(node);
624                 error = vget_finish(vp, lkflag, vs);
625                 if (error == ENOENT) {
626                         TMPFS_NODE_LOCK(node);
627                         goto loop;
628                 }
629                 if (error != 0) {
630                         vp = NULL;
631                         goto out;
632                 }
633
634                 /*
635                  * Make sure the vnode is still there after
636                  * getting the interlock to avoid racing a free.
637                  */
638                 if (node->tn_vnode == NULL || node->tn_vnode != vp) {
639                         vput(vp);
640                         TMPFS_NODE_LOCK(node);
641                         goto loop;
642                 }
643
644                 goto out;
645         }
646
647         if ((node->tn_vpstate & TMPFS_VNODE_DOOMED) ||
648             (node->tn_type == VDIR && node->tn_dir.tn_parent == NULL)) {
649                 TMPFS_NODE_UNLOCK(node);
650                 error = ENOENT;
651                 vp = NULL;
652                 goto out;
653         }
654
655         /*
656          * otherwise lock the vp list while we call getnewvnode
657          * since that can block.
658          */
659         if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) {
660                 node->tn_vpstate |= TMPFS_VNODE_WANT;
661                 error = msleep((caddr_t) &node->tn_vpstate,
662                     TMPFS_NODE_MTX(node), 0, "tmpfs_alloc_vp", 0);
663                 if (error != 0)
664                         goto out;
665                 goto loop;
666         } else
667                 node->tn_vpstate |= TMPFS_VNODE_ALLOCATING;
668
669         TMPFS_NODE_UNLOCK(node);
670
671         /* Get a new vnode and associate it with our node. */
672         error = getnewvnode("tmpfs", mp, VFS_TO_TMPFS(mp)->tm_nonc ?
673             &tmpfs_vnodeop_nonc_entries : &tmpfs_vnodeop_entries, &vp);
674         if (error != 0)
675                 goto unlock;
676         MPASS(vp != NULL);
677
678         /* lkflag is ignored, the lock is exclusive */
679         (void) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
680
681         vp->v_data = node;
682         vp->v_type = node->tn_type;
683
684         /* Type-specific initialization. */
685         switch (node->tn_type) {
686         case VBLK:
687                 /* FALLTHROUGH */
688         case VCHR:
689                 /* FALLTHROUGH */
690         case VLNK:
691                 /* FALLTHROUGH */
692         case VSOCK:
693                 break;
694         case VFIFO:
695                 vp->v_op = &tmpfs_fifoop_entries;
696                 break;
697         case VREG:
698                 object = node->tn_reg.tn_aobj;
699                 VM_OBJECT_WLOCK(object);
700                 VI_LOCK(vp);
701                 KASSERT(vp->v_object == NULL, ("Not NULL v_object in tmpfs"));
702                 vp->v_object = object;
703                 object->un_pager.swp.swp_tmpfs = vp;
704                 vm_object_set_flag(object, OBJ_TMPFS);
705                 vp->v_irflag |= VIRF_PGREAD;
706                 VI_UNLOCK(vp);
707                 VM_OBJECT_WUNLOCK(object);
708                 break;
709         case VDIR:
710                 MPASS(node->tn_dir.tn_parent != NULL);
711                 if (node->tn_dir.tn_parent == node)
712                         vp->v_vflag |= VV_ROOT;
713                 break;
714
715         default:
716                 panic("tmpfs_alloc_vp: type %p %d", node, (int)node->tn_type);
717         }
718         if (vp->v_type != VFIFO)
719                 VN_LOCK_ASHARE(vp);
720
721         error = insmntque1(vp, mp, tmpfs_insmntque_dtr, NULL);
722         if (error != 0)
723                 vp = NULL;
724
725 unlock:
726         TMPFS_NODE_LOCK(node);
727
728         MPASS(node->tn_vpstate & TMPFS_VNODE_ALLOCATING);
729         node->tn_vpstate &= ~TMPFS_VNODE_ALLOCATING;
730         node->tn_vnode = vp;
731
732         if (node->tn_vpstate & TMPFS_VNODE_WANT) {
733                 node->tn_vpstate &= ~TMPFS_VNODE_WANT;
734                 TMPFS_NODE_UNLOCK(node);
735                 wakeup((caddr_t) &node->tn_vpstate);
736         } else
737                 TMPFS_NODE_UNLOCK(node);
738
739 out:
740         if (error == 0) {
741                 *vpp = vp;
742
743 #ifdef INVARIANTS
744                 MPASS(*vpp != NULL && VOP_ISLOCKED(*vpp));
745                 TMPFS_NODE_LOCK(node);
746                 MPASS(*vpp == node->tn_vnode);
747                 TMPFS_NODE_UNLOCK(node);
748 #endif
749         }
750         tmpfs_free_node(tm, node);
751
752         return (error);
753 }
754
755 /*
756  * Destroys the association between the vnode vp and the node it
757  * references.
758  */
759 void
760 tmpfs_free_vp(struct vnode *vp)
761 {
762         struct tmpfs_node *node;
763
764         node = VP_TO_TMPFS_NODE(vp);
765
766         TMPFS_NODE_ASSERT_LOCKED(node);
767         node->tn_vnode = NULL;
768         if ((node->tn_vpstate & TMPFS_VNODE_WRECLAIM) != 0)
769                 wakeup(&node->tn_vnode);
770         node->tn_vpstate &= ~TMPFS_VNODE_WRECLAIM;
771         vp->v_data = NULL;
772 }
773
774 /*
775  * Allocates a new file of type 'type' and adds it to the parent directory
776  * 'dvp'; this addition is done using the component name given in 'cnp'.
777  * The ownership of the new file is automatically assigned based on the
778  * credentials of the caller (through 'cnp'), the group is set based on
779  * the parent directory and the mode is determined from the 'vap' argument.
780  * If successful, *vpp holds a vnode to the newly created file and zero
781  * is returned.  Otherwise *vpp is NULL and the function returns an
782  * appropriate error code.
783  */
784 int
785 tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
786     struct componentname *cnp, const char *target)
787 {
788         int error;
789         struct tmpfs_dirent *de;
790         struct tmpfs_mount *tmp;
791         struct tmpfs_node *dnode;
792         struct tmpfs_node *node;
793         struct tmpfs_node *parent;
794
795         ASSERT_VOP_ELOCKED(dvp, "tmpfs_alloc_file");
796         MPASS(cnp->cn_flags & HASBUF);
797
798         tmp = VFS_TO_TMPFS(dvp->v_mount);
799         dnode = VP_TO_TMPFS_DIR(dvp);
800         *vpp = NULL;
801
802         /* If the entry we are creating is a directory, we cannot overflow
803          * the number of links of its parent, because it will get a new
804          * link. */
805         if (vap->va_type == VDIR) {
806                 /* Ensure that we do not overflow the maximum number of links
807                  * imposed by the system. */
808                 MPASS(dnode->tn_links <= TMPFS_LINK_MAX);
809                 if (dnode->tn_links == TMPFS_LINK_MAX) {
810                         return (EMLINK);
811                 }
812
813                 parent = dnode;
814                 MPASS(parent != NULL);
815         } else
816                 parent = NULL;
817
818         /* Allocate a node that represents the new file. */
819         error = tmpfs_alloc_node(dvp->v_mount, tmp, vap->va_type,
820             cnp->cn_cred->cr_uid, dnode->tn_gid, vap->va_mode, parent,
821             target, vap->va_rdev, &node);
822         if (error != 0)
823                 return (error);
824
825         /* Allocate a directory entry that points to the new file. */
826         error = tmpfs_alloc_dirent(tmp, node, cnp->cn_nameptr, cnp->cn_namelen,
827             &de);
828         if (error != 0) {
829                 tmpfs_free_node(tmp, node);
830                 return (error);
831         }
832
833         /* Allocate a vnode for the new file. */
834         error = tmpfs_alloc_vp(dvp->v_mount, node, LK_EXCLUSIVE, vpp);
835         if (error != 0) {
836                 tmpfs_free_dirent(tmp, de);
837                 tmpfs_free_node(tmp, node);
838                 return (error);
839         }
840
841         /* Now that all required items are allocated, we can proceed to
842          * insert the new node into the directory, an operation that
843          * cannot fail. */
844         if (cnp->cn_flags & ISWHITEOUT)
845                 tmpfs_dir_whiteout_remove(dvp, cnp);
846         tmpfs_dir_attach(dvp, de);
847         return (0);
848 }
849
850 struct tmpfs_dirent *
851 tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
852 {
853         struct tmpfs_dirent *de;
854
855         de = RB_MIN(tmpfs_dir, &dnode->tn_dir.tn_dirhead);
856         dc->tdc_tree = de;
857         if (de != NULL && tmpfs_dirent_duphead(de))
858                 de = LIST_FIRST(&de->ud.td_duphead);
859         dc->tdc_current = de;
860
861         return (dc->tdc_current);
862 }
863
864 struct tmpfs_dirent *
865 tmpfs_dir_next(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
866 {
867         struct tmpfs_dirent *de;
868
869         MPASS(dc->tdc_tree != NULL);
870         if (tmpfs_dirent_dup(dc->tdc_current)) {
871                 dc->tdc_current = LIST_NEXT(dc->tdc_current, uh.td_dup.entries);
872                 if (dc->tdc_current != NULL)
873                         return (dc->tdc_current);
874         }
875         dc->tdc_tree = dc->tdc_current = RB_NEXT(tmpfs_dir,
876             &dnode->tn_dir.tn_dirhead, dc->tdc_tree);
877         if ((de = dc->tdc_current) != NULL && tmpfs_dirent_duphead(de)) {
878                 dc->tdc_current = LIST_FIRST(&de->ud.td_duphead);
879                 MPASS(dc->tdc_current != NULL);
880         }
881
882         return (dc->tdc_current);
883 }
884
885 /* Lookup directory entry in RB-Tree. Function may return duphead entry. */
886 static struct tmpfs_dirent *
887 tmpfs_dir_xlookup_hash(struct tmpfs_node *dnode, uint32_t hash)
888 {
889         struct tmpfs_dirent *de, dekey;
890
891         dekey.td_hash = hash;
892         de = RB_FIND(tmpfs_dir, &dnode->tn_dir.tn_dirhead, &dekey);
893         return (de);
894 }
895
896 /* Lookup directory entry by cookie, initialize directory cursor accordingly. */
897 static struct tmpfs_dirent *
898 tmpfs_dir_lookup_cookie(struct tmpfs_node *node, off_t cookie,
899     struct tmpfs_dir_cursor *dc)
900 {
901         struct tmpfs_dir *dirhead = &node->tn_dir.tn_dirhead;
902         struct tmpfs_dirent *de, dekey;
903
904         MPASS(cookie >= TMPFS_DIRCOOKIE_MIN);
905
906         if (cookie == node->tn_dir.tn_readdir_lastn &&
907             (de = node->tn_dir.tn_readdir_lastp) != NULL) {
908                 /* Protect against possible race, tn_readdir_last[pn]
909                  * may be updated with only shared vnode lock held. */
910                 if (cookie == tmpfs_dirent_cookie(de))
911                         goto out;
912         }
913
914         if ((cookie & TMPFS_DIRCOOKIE_DUP) != 0) {
915                 LIST_FOREACH(de, &node->tn_dir.tn_dupindex,
916                     uh.td_dup.index_entries) {
917                         MPASS(tmpfs_dirent_dup(de));
918                         if (de->td_cookie == cookie)
919                                 goto out;
920                         /* dupindex list is sorted. */
921                         if (de->td_cookie < cookie) {
922                                 de = NULL;
923                                 goto out;
924                         }
925                 }
926                 MPASS(de == NULL);
927                 goto out;
928         }
929
930         if ((cookie & TMPFS_DIRCOOKIE_MASK) != cookie) {
931                 de = NULL;
932         } else {
933                 dekey.td_hash = cookie;
934                 /* Recover if direntry for cookie was removed */
935                 de = RB_NFIND(tmpfs_dir, dirhead, &dekey);
936         }
937         dc->tdc_tree = de;
938         dc->tdc_current = de;
939         if (de != NULL && tmpfs_dirent_duphead(de)) {
940                 dc->tdc_current = LIST_FIRST(&de->ud.td_duphead);
941                 MPASS(dc->tdc_current != NULL);
942         }
943         return (dc->tdc_current);
944
945 out:
946         dc->tdc_tree = de;
947         dc->tdc_current = de;
948         if (de != NULL && tmpfs_dirent_dup(de))
949                 dc->tdc_tree = tmpfs_dir_xlookup_hash(node,
950                     de->td_hash);
951         return (dc->tdc_current);
952 }
953
954 /*
955  * Looks for a directory entry in the directory represented by node.
956  * 'cnp' describes the name of the entry to look for.  Note that the .
957  * and .. components are not allowed as they do not physically exist
958  * within directories.
959  *
960  * Returns a pointer to the entry when found, otherwise NULL.
961  */
962 struct tmpfs_dirent *
963 tmpfs_dir_lookup(struct tmpfs_node *node, struct tmpfs_node *f,
964     struct componentname *cnp)
965 {
966         struct tmpfs_dir_duphead *duphead;
967         struct tmpfs_dirent *de;
968         uint32_t hash;
969
970         MPASS(IMPLIES(cnp->cn_namelen == 1, cnp->cn_nameptr[0] != '.'));
971         MPASS(IMPLIES(cnp->cn_namelen == 2, !(cnp->cn_nameptr[0] == '.' &&
972             cnp->cn_nameptr[1] == '.')));
973         TMPFS_VALIDATE_DIR(node);
974
975         hash = tmpfs_dirent_hash(cnp->cn_nameptr, cnp->cn_namelen);
976         de = tmpfs_dir_xlookup_hash(node, hash);
977         if (de != NULL && tmpfs_dirent_duphead(de)) {
978                 duphead = &de->ud.td_duphead;
979                 LIST_FOREACH(de, duphead, uh.td_dup.entries) {
980                         if (TMPFS_DIRENT_MATCHES(de, cnp->cn_nameptr,
981                             cnp->cn_namelen))
982                                 break;
983                 }
984         } else if (de != NULL) {
985                 if (!TMPFS_DIRENT_MATCHES(de, cnp->cn_nameptr,
986                     cnp->cn_namelen))
987                         de = NULL;
988         }
989         if (de != NULL && f != NULL && de->td_node != f)
990                 de = NULL;
991
992         return (de);
993 }
994
995 /*
996  * Attach duplicate-cookie directory entry nde to dnode and insert to dupindex
997  * list, allocate new cookie value.
998  */
999 static void
1000 tmpfs_dir_attach_dup(struct tmpfs_node *dnode,
1001     struct tmpfs_dir_duphead *duphead, struct tmpfs_dirent *nde)
1002 {
1003         struct tmpfs_dir_duphead *dupindex;
1004         struct tmpfs_dirent *de, *pde;
1005
1006         dupindex = &dnode->tn_dir.tn_dupindex;
1007         de = LIST_FIRST(dupindex);
1008         if (de == NULL || de->td_cookie < TMPFS_DIRCOOKIE_DUP_MAX) {
1009                 if (de == NULL)
1010                         nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
1011                 else
1012                         nde->td_cookie = de->td_cookie + 1;
1013                 MPASS(tmpfs_dirent_dup(nde));
1014                 LIST_INSERT_HEAD(dupindex, nde, uh.td_dup.index_entries);
1015                 LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
1016                 return;
1017         }
1018
1019         /*
1020          * Cookie numbers are near exhaustion. Scan dupindex list for unused
1021          * numbers. dupindex list is sorted in descending order. Keep it so
1022          * after inserting nde.
1023          */
1024         while (1) {
1025                 pde = de;
1026                 de = LIST_NEXT(de, uh.td_dup.index_entries);
1027                 if (de == NULL && pde->td_cookie != TMPFS_DIRCOOKIE_DUP_MIN) {
1028                         /*
1029                          * Last element of the index doesn't have minimal cookie
1030                          * value, use it.
1031                          */
1032                         nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
1033                         LIST_INSERT_AFTER(pde, nde, uh.td_dup.index_entries);
1034                         LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
1035                         return;
1036                 } else if (de == NULL) {
1037                         /*
1038                          * We are so lucky have 2^30 hash duplicates in single
1039                          * directory :) Return largest possible cookie value.
1040                          * It should be fine except possible issues with
1041                          * VOP_READDIR restart.
1042                          */
1043                         nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MAX;
1044                         LIST_INSERT_HEAD(dupindex, nde,
1045                             uh.td_dup.index_entries);
1046                         LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
1047                         return;
1048                 }
1049                 if (de->td_cookie + 1 == pde->td_cookie ||
1050                     de->td_cookie >= TMPFS_DIRCOOKIE_DUP_MAX)
1051                         continue;       /* No hole or invalid cookie. */
1052                 nde->td_cookie = de->td_cookie + 1;
1053                 MPASS(tmpfs_dirent_dup(nde));
1054                 MPASS(pde->td_cookie > nde->td_cookie);
1055                 MPASS(nde->td_cookie > de->td_cookie);
1056                 LIST_INSERT_BEFORE(de, nde, uh.td_dup.index_entries);
1057                 LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
1058                 return;
1059         }
1060 }
1061
1062 /*
1063  * Attaches the directory entry de to the directory represented by vp.
1064  * Note that this does not change the link count of the node pointed by
1065  * the directory entry, as this is done by tmpfs_alloc_dirent.
1066  */
1067 void
1068 tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de)
1069 {
1070         struct tmpfs_node *dnode;
1071         struct tmpfs_dirent *xde, *nde;
1072
1073         ASSERT_VOP_ELOCKED(vp, __func__);
1074         MPASS(de->td_namelen > 0);
1075         MPASS(de->td_hash >= TMPFS_DIRCOOKIE_MIN);
1076         MPASS(de->td_cookie == de->td_hash);
1077
1078         dnode = VP_TO_TMPFS_DIR(vp);
1079         dnode->tn_dir.tn_readdir_lastn = 0;
1080         dnode->tn_dir.tn_readdir_lastp = NULL;
1081
1082         MPASS(!tmpfs_dirent_dup(de));
1083         xde = RB_INSERT(tmpfs_dir, &dnode->tn_dir.tn_dirhead, de);
1084         if (xde != NULL && tmpfs_dirent_duphead(xde))
1085                 tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, de);
1086         else if (xde != NULL) {
1087                 /*
1088                  * Allocate new duphead. Swap xde with duphead to avoid
1089                  * adding/removing elements with the same hash.
1090                  */
1091                 MPASS(!tmpfs_dirent_dup(xde));
1092                 tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), NULL, NULL, 0,
1093                     &nde);
1094                 /* *nde = *xde; XXX gcc 4.2.1 may generate invalid code. */
1095                 memcpy(nde, xde, sizeof(*xde));
1096                 xde->td_cookie |= TMPFS_DIRCOOKIE_DUPHEAD;
1097                 LIST_INIT(&xde->ud.td_duphead);
1098                 xde->td_namelen = 0;
1099                 xde->td_node = NULL;
1100                 tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, nde);
1101                 tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, de);
1102         }
1103         dnode->tn_size += sizeof(struct tmpfs_dirent);
1104         dnode->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
1105         dnode->tn_accessed = true;
1106         tmpfs_update(vp);
1107 }
1108
1109 /*
1110  * Detaches the directory entry de from the directory represented by vp.
1111  * Note that this does not change the link count of the node pointed by
1112  * the directory entry, as this is done by tmpfs_free_dirent.
1113  */
1114 void
1115 tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
1116 {
1117         struct tmpfs_mount *tmp;
1118         struct tmpfs_dir *head;
1119         struct tmpfs_node *dnode;
1120         struct tmpfs_dirent *xde;
1121
1122         ASSERT_VOP_ELOCKED(vp, __func__);
1123
1124         dnode = VP_TO_TMPFS_DIR(vp);
1125         head = &dnode->tn_dir.tn_dirhead;
1126         dnode->tn_dir.tn_readdir_lastn = 0;
1127         dnode->tn_dir.tn_readdir_lastp = NULL;
1128
1129         if (tmpfs_dirent_dup(de)) {
1130                 /* Remove duphead if de was last entry. */
1131                 if (LIST_NEXT(de, uh.td_dup.entries) == NULL) {
1132                         xde = tmpfs_dir_xlookup_hash(dnode, de->td_hash);
1133                         MPASS(tmpfs_dirent_duphead(xde));
1134                 } else
1135                         xde = NULL;
1136                 LIST_REMOVE(de, uh.td_dup.entries);
1137                 LIST_REMOVE(de, uh.td_dup.index_entries);
1138                 if (xde != NULL) {
1139                         if (LIST_EMPTY(&xde->ud.td_duphead)) {
1140                                 RB_REMOVE(tmpfs_dir, head, xde);
1141                                 tmp = VFS_TO_TMPFS(vp->v_mount);
1142                                 MPASS(xde->td_node == NULL);
1143                                 tmpfs_free_dirent(tmp, xde);
1144                         }
1145                 }
1146                 de->td_cookie = de->td_hash;
1147         } else
1148                 RB_REMOVE(tmpfs_dir, head, de);
1149
1150         dnode->tn_size -= sizeof(struct tmpfs_dirent);
1151         dnode->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
1152         dnode->tn_accessed = true;
1153         tmpfs_update(vp);
1154 }
1155
1156 void
1157 tmpfs_dir_destroy(struct tmpfs_mount *tmp, struct tmpfs_node *dnode)
1158 {
1159         struct tmpfs_dirent *de, *dde, *nde;
1160
1161         RB_FOREACH_SAFE(de, tmpfs_dir, &dnode->tn_dir.tn_dirhead, nde) {
1162                 RB_REMOVE(tmpfs_dir, &dnode->tn_dir.tn_dirhead, de);
1163                 /* Node may already be destroyed. */
1164                 de->td_node = NULL;
1165                 if (tmpfs_dirent_duphead(de)) {
1166                         while ((dde = LIST_FIRST(&de->ud.td_duphead)) != NULL) {
1167                                 LIST_REMOVE(dde, uh.td_dup.entries);
1168                                 dde->td_node = NULL;
1169                                 tmpfs_free_dirent(tmp, dde);
1170                         }
1171                 }
1172                 tmpfs_free_dirent(tmp, de);
1173         }
1174 }
1175
1176 /*
1177  * Helper function for tmpfs_readdir.  Creates a '.' entry for the given
1178  * directory and returns it in the uio space.  The function returns 0
1179  * on success, -1 if there was not enough space in the uio structure to
1180  * hold the directory entry or an appropriate error code if another
1181  * error happens.
1182  */
1183 static int
1184 tmpfs_dir_getdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
1185     struct uio *uio)
1186 {
1187         int error;
1188         struct dirent dent;
1189
1190         TMPFS_VALIDATE_DIR(node);
1191         MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT);
1192
1193         dent.d_fileno = node->tn_id;
1194         dent.d_type = DT_DIR;
1195         dent.d_namlen = 1;
1196         dent.d_name[0] = '.';
1197         dent.d_reclen = GENERIC_DIRSIZ(&dent);
1198         dirent_terminate(&dent);
1199
1200         if (dent.d_reclen > uio->uio_resid)
1201                 error = EJUSTRETURN;
1202         else
1203                 error = uiomove(&dent, dent.d_reclen, uio);
1204
1205         tmpfs_set_accessed(tm, node);
1206
1207         return (error);
1208 }
1209
1210 /*
1211  * Helper function for tmpfs_readdir.  Creates a '..' entry for the given
1212  * directory and returns it in the uio space.  The function returns 0
1213  * on success, -1 if there was not enough space in the uio structure to
1214  * hold the directory entry or an appropriate error code if another
1215  * error happens.
1216  */
1217 static int
1218 tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
1219     struct uio *uio)
1220 {
1221         struct tmpfs_node *parent;
1222         struct dirent dent;
1223         int error;
1224
1225         TMPFS_VALIDATE_DIR(node);
1226         MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
1227
1228         /*
1229          * Return ENOENT if the current node is already removed.
1230          */
1231         TMPFS_ASSERT_LOCKED(node);
1232         parent = node->tn_dir.tn_parent;
1233         if (parent == NULL)
1234                 return (ENOENT);
1235
1236         TMPFS_NODE_LOCK(parent);
1237         dent.d_fileno = parent->tn_id;
1238         TMPFS_NODE_UNLOCK(parent);
1239
1240         dent.d_type = DT_DIR;
1241         dent.d_namlen = 2;
1242         dent.d_name[0] = '.';
1243         dent.d_name[1] = '.';
1244         dent.d_reclen = GENERIC_DIRSIZ(&dent);
1245         dirent_terminate(&dent);
1246
1247         if (dent.d_reclen > uio->uio_resid)
1248                 error = EJUSTRETURN;
1249         else
1250                 error = uiomove(&dent, dent.d_reclen, uio);
1251
1252         tmpfs_set_accessed(tm, node);
1253
1254         return (error);
1255 }
1256
1257 /*
1258  * Helper function for tmpfs_readdir.  Returns as much directory entries
1259  * as can fit in the uio space.  The read starts at uio->uio_offset.
1260  * The function returns 0 on success, -1 if there was not enough space
1261  * in the uio structure to hold the directory entry or an appropriate
1262  * error code if another error happens.
1263  */
1264 int
1265 tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node,
1266     struct uio *uio, int maxcookies, u_long *cookies, int *ncookies)
1267 {
1268         struct tmpfs_dir_cursor dc;
1269         struct tmpfs_dirent *de;
1270         off_t off;
1271         int error;
1272
1273         TMPFS_VALIDATE_DIR(node);
1274
1275         off = 0;
1276
1277         /*
1278          * Lookup the node from the current offset.  The starting offset of
1279          * 0 will lookup both '.' and '..', and then the first real entry,
1280          * or EOF if there are none.  Then find all entries for the dir that
1281          * fit into the buffer.  Once no more entries are found (de == NULL),
1282          * the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next
1283          * call to return 0.
1284          */
1285         switch (uio->uio_offset) {
1286         case TMPFS_DIRCOOKIE_DOT:
1287                 error = tmpfs_dir_getdotdent(tm, node, uio);
1288                 if (error != 0)
1289                         return (error);
1290                 uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
1291                 if (cookies != NULL)
1292                         cookies[(*ncookies)++] = off = uio->uio_offset;
1293                 /* FALLTHROUGH */
1294         case TMPFS_DIRCOOKIE_DOTDOT:
1295                 error = tmpfs_dir_getdotdotdent(tm, node, uio);
1296                 if (error != 0)
1297                         return (error);
1298                 de = tmpfs_dir_first(node, &dc);
1299                 uio->uio_offset = tmpfs_dirent_cookie(de);
1300                 if (cookies != NULL)
1301                         cookies[(*ncookies)++] = off = uio->uio_offset;
1302                 /* EOF. */
1303                 if (de == NULL)
1304                         return (0);
1305                 break;
1306         case TMPFS_DIRCOOKIE_EOF:
1307                 return (0);
1308         default:
1309                 de = tmpfs_dir_lookup_cookie(node, uio->uio_offset, &dc);
1310                 if (de == NULL)
1311                         return (EINVAL);
1312                 if (cookies != NULL)
1313                         off = tmpfs_dirent_cookie(de);
1314         }
1315
1316         /* Read as much entries as possible; i.e., until we reach the end of
1317          * the directory or we exhaust uio space. */
1318         do {
1319                 struct dirent d;
1320
1321                 /* Create a dirent structure representing the current
1322                  * tmpfs_node and fill it. */
1323                 if (de->td_node == NULL) {
1324                         d.d_fileno = 1;
1325                         d.d_type = DT_WHT;
1326                 } else {
1327                         d.d_fileno = de->td_node->tn_id;
1328                         switch (de->td_node->tn_type) {
1329                         case VBLK:
1330                                 d.d_type = DT_BLK;
1331                                 break;
1332
1333                         case VCHR:
1334                                 d.d_type = DT_CHR;
1335                                 break;
1336
1337                         case VDIR:
1338                                 d.d_type = DT_DIR;
1339                                 break;
1340
1341                         case VFIFO:
1342                                 d.d_type = DT_FIFO;
1343                                 break;
1344
1345                         case VLNK:
1346                                 d.d_type = DT_LNK;
1347                                 break;
1348
1349                         case VREG:
1350                                 d.d_type = DT_REG;
1351                                 break;
1352
1353                         case VSOCK:
1354                                 d.d_type = DT_SOCK;
1355                                 break;
1356
1357                         default:
1358                                 panic("tmpfs_dir_getdents: type %p %d",
1359                                     de->td_node, (int)de->td_node->tn_type);
1360                         }
1361                 }
1362                 d.d_namlen = de->td_namelen;
1363                 MPASS(de->td_namelen < sizeof(d.d_name));
1364                 (void)memcpy(d.d_name, de->ud.td_name, de->td_namelen);
1365                 d.d_reclen = GENERIC_DIRSIZ(&d);
1366                 dirent_terminate(&d);
1367
1368                 /* Stop reading if the directory entry we are treating is
1369                  * bigger than the amount of data that can be returned. */
1370                 if (d.d_reclen > uio->uio_resid) {
1371                         error = EJUSTRETURN;
1372                         break;
1373                 }
1374
1375                 /* Copy the new dirent structure into the output buffer and
1376                  * advance pointers. */
1377                 error = uiomove(&d, d.d_reclen, uio);
1378                 if (error == 0) {
1379                         de = tmpfs_dir_next(node, &dc);
1380                         if (cookies != NULL) {
1381                                 off = tmpfs_dirent_cookie(de);
1382                                 MPASS(*ncookies < maxcookies);
1383                                 cookies[(*ncookies)++] = off;
1384                         }
1385                 }
1386         } while (error == 0 && uio->uio_resid > 0 && de != NULL);
1387
1388         /* Skip setting off when using cookies as it is already done above. */
1389         if (cookies == NULL)
1390                 off = tmpfs_dirent_cookie(de);
1391
1392         /* Update the offset and cache. */
1393         uio->uio_offset = off;
1394         node->tn_dir.tn_readdir_lastn = off;
1395         node->tn_dir.tn_readdir_lastp = de;
1396
1397         tmpfs_set_accessed(tm, node);
1398         return (error);
1399 }
1400
1401 int
1402 tmpfs_dir_whiteout_add(struct vnode *dvp, struct componentname *cnp)
1403 {
1404         struct tmpfs_dirent *de;
1405         int error;
1406
1407         error = tmpfs_alloc_dirent(VFS_TO_TMPFS(dvp->v_mount), NULL,
1408             cnp->cn_nameptr, cnp->cn_namelen, &de);
1409         if (error != 0)
1410                 return (error);
1411         tmpfs_dir_attach(dvp, de);
1412         return (0);
1413 }
1414
1415 void
1416 tmpfs_dir_whiteout_remove(struct vnode *dvp, struct componentname *cnp)
1417 {
1418         struct tmpfs_dirent *de;
1419
1420         de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(dvp), NULL, cnp);
1421         MPASS(de != NULL && de->td_node == NULL);
1422         tmpfs_dir_detach(dvp, de);
1423         tmpfs_free_dirent(VFS_TO_TMPFS(dvp->v_mount), de);
1424 }
1425
1426 /*
1427  * Resizes the aobj associated with the regular file pointed to by 'vp' to the
1428  * size 'newsize'.  'vp' must point to a vnode that represents a regular file.
1429  * 'newsize' must be positive.
1430  *
1431  * Returns zero on success or an appropriate error code on failure.
1432  */
1433 int
1434 tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
1435 {
1436         struct tmpfs_mount *tmp;
1437         struct tmpfs_node *node;
1438         vm_object_t uobj;
1439         vm_page_t m;
1440         vm_pindex_t idx, newpages, oldpages;
1441         off_t oldsize;
1442         int base, rv;
1443
1444         MPASS(vp->v_type == VREG);
1445         MPASS(newsize >= 0);
1446
1447         node = VP_TO_TMPFS_NODE(vp);
1448         uobj = node->tn_reg.tn_aobj;
1449         tmp = VFS_TO_TMPFS(vp->v_mount);
1450
1451         /*
1452          * Convert the old and new sizes to the number of pages needed to
1453          * store them.  It may happen that we do not need to do anything
1454          * because the last allocated page can accommodate the change on
1455          * its own.
1456          */
1457         oldsize = node->tn_size;
1458         oldpages = OFF_TO_IDX(oldsize + PAGE_MASK);
1459         MPASS(oldpages == uobj->size);
1460         newpages = OFF_TO_IDX(newsize + PAGE_MASK);
1461
1462         if (__predict_true(newpages == oldpages && newsize >= oldsize)) {
1463                 node->tn_size = newsize;
1464                 return (0);
1465         }
1466
1467         if (newpages > oldpages &&
1468             tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0)
1469                 return (ENOSPC);
1470
1471         VM_OBJECT_WLOCK(uobj);
1472         if (newsize < oldsize) {
1473                 /*
1474                  * Zero the truncated part of the last page.
1475                  */
1476                 base = newsize & PAGE_MASK;
1477                 if (base != 0) {
1478                         idx = OFF_TO_IDX(newsize);
1479 retry:
1480                         m = vm_page_grab(uobj, idx, VM_ALLOC_NOCREAT);
1481                         if (m != NULL) {
1482                                 MPASS(vm_page_all_valid(m));
1483                         } else if (vm_pager_has_page(uobj, idx, NULL, NULL)) {
1484                                 m = vm_page_alloc(uobj, idx, VM_ALLOC_NORMAL |
1485                                     VM_ALLOC_WAITFAIL);
1486                                 if (m == NULL)
1487                                         goto retry;
1488                                 vm_object_pip_add(uobj, 1);
1489                                 VM_OBJECT_WUNLOCK(uobj);
1490                                 rv = vm_pager_get_pages(uobj, &m, 1, NULL,
1491                                     NULL);
1492                                 VM_OBJECT_WLOCK(uobj);
1493                                 vm_object_pip_wakeup(uobj);
1494                                 if (rv == VM_PAGER_OK) {
1495                                         /*
1496                                          * Since the page was not resident,
1497                                          * and therefore not recently
1498                                          * accessed, immediately enqueue it
1499                                          * for asynchronous laundering.  The
1500                                          * current operation is not regarded
1501                                          * as an access.
1502                                          */
1503                                         vm_page_launder(m);
1504                                 } else {
1505                                         vm_page_free(m);
1506                                         if (ignerr)
1507                                                 m = NULL;
1508                                         else {
1509                                                 VM_OBJECT_WUNLOCK(uobj);
1510                                                 return (EIO);
1511                                         }
1512                                 }
1513                         }
1514                         if (m != NULL) {
1515                                 pmap_zero_page_area(m, base, PAGE_SIZE - base);
1516                                 vm_page_set_dirty(m);
1517                                 vm_page_xunbusy(m);
1518                         }
1519                 }
1520
1521                 /*
1522                  * Release any swap space and free any whole pages.
1523                  */
1524                 if (newpages < oldpages)
1525                         vm_object_page_remove(uobj, newpages, 0, 0);
1526         }
1527         uobj->size = newpages;
1528         VM_OBJECT_WUNLOCK(uobj);
1529
1530         atomic_add_long(&tmp->tm_pages_used, newpages - oldpages);
1531
1532         node->tn_size = newsize;
1533         return (0);
1534 }
1535
1536 void
1537 tmpfs_check_mtime(struct vnode *vp)
1538 {
1539         struct tmpfs_node *node;
1540         struct vm_object *obj;
1541
1542         ASSERT_VOP_ELOCKED(vp, "check_mtime");
1543         if (vp->v_type != VREG)
1544                 return;
1545         obj = vp->v_object;
1546         KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
1547             (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
1548         /* unlocked read */
1549         if (obj->generation != obj->cleangeneration) {
1550                 VM_OBJECT_WLOCK(obj);
1551                 if (obj->generation != obj->cleangeneration) {
1552                         obj->cleangeneration = obj->generation;
1553                         node = VP_TO_TMPFS_NODE(vp);
1554                         node->tn_status |= TMPFS_NODE_MODIFIED |
1555                             TMPFS_NODE_CHANGED;
1556                 }
1557                 VM_OBJECT_WUNLOCK(obj);
1558         }
1559 }
1560
1561 /*
1562  * Change flags of the given vnode.
1563  * Caller should execute tmpfs_update on vp after a successful execution.
1564  * The vnode must be locked on entry and remain locked on exit.
1565  */
1566 int
1567 tmpfs_chflags(struct vnode *vp, u_long flags, struct ucred *cred,
1568     struct thread *p)
1569 {
1570         int error;
1571         struct tmpfs_node *node;
1572
1573         ASSERT_VOP_ELOCKED(vp, "chflags");
1574
1575         node = VP_TO_TMPFS_NODE(vp);
1576
1577         if ((flags & ~(SF_APPEND | SF_ARCHIVED | SF_IMMUTABLE | SF_NOUNLINK |
1578             UF_APPEND | UF_ARCHIVE | UF_HIDDEN | UF_IMMUTABLE | UF_NODUMP |
1579             UF_NOUNLINK | UF_OFFLINE | UF_OPAQUE | UF_READONLY | UF_REPARSE |
1580             UF_SPARSE | UF_SYSTEM)) != 0)
1581                 return (EOPNOTSUPP);
1582
1583         /* Disallow this operation if the file system is mounted read-only. */
1584         if (vp->v_mount->mnt_flag & MNT_RDONLY)
1585                 return (EROFS);
1586
1587         /*
1588          * Callers may only modify the file flags on objects they
1589          * have VADMIN rights for.
1590          */
1591         if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
1592                 return (error);
1593         /*
1594          * Unprivileged processes are not permitted to unset system
1595          * flags, or modify flags if any system flags are set.
1596          */
1597         if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS)) {
1598                 if (node->tn_flags &
1599                     (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
1600                         error = securelevel_gt(cred, 0);
1601                         if (error)
1602                                 return (error);
1603                 }
1604         } else {
1605                 if (node->tn_flags &
1606                     (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
1607                     ((flags ^ node->tn_flags) & SF_SETTABLE))
1608                         return (EPERM);
1609         }
1610         node->tn_flags = flags;
1611         node->tn_status |= TMPFS_NODE_CHANGED;
1612
1613         ASSERT_VOP_ELOCKED(vp, "chflags2");
1614
1615         return (0);
1616 }
1617
1618 /*
1619  * Change access mode on the given vnode.
1620  * Caller should execute tmpfs_update on vp after a successful execution.
1621  * The vnode must be locked on entry and remain locked on exit.
1622  */
1623 int
1624 tmpfs_chmod(struct vnode *vp, mode_t mode, struct ucred *cred, struct thread *p)
1625 {
1626         int error;
1627         struct tmpfs_node *node;
1628         mode_t newmode;
1629
1630         ASSERT_VOP_ELOCKED(vp, "chmod");
1631         ASSERT_VOP_IN_SEQC(vp);
1632
1633         node = VP_TO_TMPFS_NODE(vp);
1634
1635         /* Disallow this operation if the file system is mounted read-only. */
1636         if (vp->v_mount->mnt_flag & MNT_RDONLY)
1637                 return EROFS;
1638
1639         /* Immutable or append-only files cannot be modified, either. */
1640         if (node->tn_flags & (IMMUTABLE | APPEND))
1641                 return EPERM;
1642
1643         /*
1644          * To modify the permissions on a file, must possess VADMIN
1645          * for that file.
1646          */
1647         if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
1648                 return (error);
1649
1650         /*
1651          * Privileged processes may set the sticky bit on non-directories,
1652          * as well as set the setgid bit on a file with a group that the
1653          * process is not a member of.
1654          */
1655         if (vp->v_type != VDIR && (mode & S_ISTXT)) {
1656                 if (priv_check_cred(cred, PRIV_VFS_STICKYFILE))
1657                         return (EFTYPE);
1658         }
1659         if (!groupmember(node->tn_gid, cred) && (mode & S_ISGID)) {
1660                 error = priv_check_cred(cred, PRIV_VFS_SETGID);
1661                 if (error)
1662                         return (error);
1663         }
1664
1665         newmode = node->tn_mode & ~ALLPERMS;
1666         newmode |= mode & ALLPERMS;
1667         atomic_store_short(&node->tn_mode, newmode);
1668
1669         node->tn_status |= TMPFS_NODE_CHANGED;
1670
1671         ASSERT_VOP_ELOCKED(vp, "chmod2");
1672
1673         return (0);
1674 }
1675
1676 /*
1677  * Change ownership of the given vnode.  At least one of uid or gid must
1678  * be different than VNOVAL.  If one is set to that value, the attribute
1679  * is unchanged.
1680  * Caller should execute tmpfs_update on vp after a successful execution.
1681  * The vnode must be locked on entry and remain locked on exit.
1682  */
1683 int
1684 tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred,
1685     struct thread *p)
1686 {
1687         int error;
1688         struct tmpfs_node *node;
1689         uid_t ouid;
1690         gid_t ogid;
1691         mode_t newmode;
1692
1693         ASSERT_VOP_ELOCKED(vp, "chown");
1694         ASSERT_VOP_IN_SEQC(vp);
1695
1696         node = VP_TO_TMPFS_NODE(vp);
1697
1698         /* Assign default values if they are unknown. */
1699         MPASS(uid != VNOVAL || gid != VNOVAL);
1700         if (uid == VNOVAL)
1701                 uid = node->tn_uid;
1702         if (gid == VNOVAL)
1703                 gid = node->tn_gid;
1704         MPASS(uid != VNOVAL && gid != VNOVAL);
1705
1706         /* Disallow this operation if the file system is mounted read-only. */
1707         if (vp->v_mount->mnt_flag & MNT_RDONLY)
1708                 return (EROFS);
1709
1710         /* Immutable or append-only files cannot be modified, either. */
1711         if (node->tn_flags & (IMMUTABLE | APPEND))
1712                 return (EPERM);
1713
1714         /*
1715          * To modify the ownership of a file, must possess VADMIN for that
1716          * file.
1717          */
1718         if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
1719                 return (error);
1720
1721         /*
1722          * To change the owner of a file, or change the group of a file to a
1723          * group of which we are not a member, the caller must have
1724          * privilege.
1725          */
1726         if ((uid != node->tn_uid ||
1727             (gid != node->tn_gid && !groupmember(gid, cred))) &&
1728             (error = priv_check_cred(cred, PRIV_VFS_CHOWN)))
1729                 return (error);
1730
1731         ogid = node->tn_gid;
1732         ouid = node->tn_uid;
1733
1734         node->tn_uid = uid;
1735         node->tn_gid = gid;
1736
1737         node->tn_status |= TMPFS_NODE_CHANGED;
1738
1739         if ((node->tn_mode & (S_ISUID | S_ISGID)) && (ouid != uid || ogid != gid)) {
1740                 if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID)) {
1741                         newmode = node->tn_mode & ~(S_ISUID | S_ISGID);
1742                         atomic_store_short(&node->tn_mode, newmode);
1743                 }
1744         }
1745
1746         ASSERT_VOP_ELOCKED(vp, "chown2");
1747
1748         return (0);
1749 }
1750
1751 /*
1752  * Change size of the given vnode.
1753  * Caller should execute tmpfs_update on vp after a successful execution.
1754  * The vnode must be locked on entry and remain locked on exit.
1755  */
1756 int
1757 tmpfs_chsize(struct vnode *vp, u_quad_t size, struct ucred *cred,
1758     struct thread *p)
1759 {
1760         int error;
1761         struct tmpfs_node *node;
1762
1763         ASSERT_VOP_ELOCKED(vp, "chsize");
1764
1765         node = VP_TO_TMPFS_NODE(vp);
1766
1767         /* Decide whether this is a valid operation based on the file type. */
1768         error = 0;
1769         switch (vp->v_type) {
1770         case VDIR:
1771                 return (EISDIR);
1772
1773         case VREG:
1774                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
1775                         return (EROFS);
1776                 break;
1777
1778         case VBLK:
1779                 /* FALLTHROUGH */
1780         case VCHR:
1781                 /* FALLTHROUGH */
1782         case VFIFO:
1783                 /*
1784                  * Allow modifications of special files even if in the file
1785                  * system is mounted read-only (we are not modifying the
1786                  * files themselves, but the objects they represent).
1787                  */
1788                 return (0);
1789
1790         default:
1791                 /* Anything else is unsupported. */
1792                 return (EOPNOTSUPP);
1793         }
1794
1795         /* Immutable or append-only files cannot be modified, either. */
1796         if (node->tn_flags & (IMMUTABLE | APPEND))
1797                 return (EPERM);
1798
1799         error = tmpfs_truncate(vp, size);
1800         /*
1801          * tmpfs_truncate will raise the NOTE_EXTEND and NOTE_ATTRIB kevents
1802          * for us, as will update tn_status; no need to do that here.
1803          */
1804
1805         ASSERT_VOP_ELOCKED(vp, "chsize2");
1806
1807         return (error);
1808 }
1809
1810 /*
1811  * Change access and modification times of the given vnode.
1812  * Caller should execute tmpfs_update on vp after a successful execution.
1813  * The vnode must be locked on entry and remain locked on exit.
1814  */
1815 int
1816 tmpfs_chtimes(struct vnode *vp, struct vattr *vap,
1817     struct ucred *cred, struct thread *l)
1818 {
1819         int error;
1820         struct tmpfs_node *node;
1821
1822         ASSERT_VOP_ELOCKED(vp, "chtimes");
1823
1824         node = VP_TO_TMPFS_NODE(vp);
1825
1826         /* Disallow this operation if the file system is mounted read-only. */
1827         if (vp->v_mount->mnt_flag & MNT_RDONLY)
1828                 return (EROFS);
1829
1830         /* Immutable or append-only files cannot be modified, either. */
1831         if (node->tn_flags & (IMMUTABLE | APPEND))
1832                 return (EPERM);
1833
1834         error = vn_utimes_perm(vp, vap, cred, l);
1835         if (error != 0)
1836                 return (error);
1837
1838         if (vap->va_atime.tv_sec != VNOVAL)
1839                 node->tn_accessed = true;
1840
1841         if (vap->va_mtime.tv_sec != VNOVAL)
1842                 node->tn_status |= TMPFS_NODE_MODIFIED;
1843
1844         if (vap->va_birthtime.tv_sec != VNOVAL)
1845                 node->tn_status |= TMPFS_NODE_MODIFIED;
1846
1847         tmpfs_itimes(vp, &vap->va_atime, &vap->va_mtime);
1848
1849         if (vap->va_birthtime.tv_sec != VNOVAL)
1850                 node->tn_birthtime = vap->va_birthtime;
1851         ASSERT_VOP_ELOCKED(vp, "chtimes2");
1852
1853         return (0);
1854 }
1855
1856 void
1857 tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node, int status)
1858 {
1859
1860         if ((node->tn_status & status) == status || tm->tm_ronly)
1861                 return;
1862         TMPFS_NODE_LOCK(node);
1863         node->tn_status |= status;
1864         TMPFS_NODE_UNLOCK(node);
1865 }
1866
1867 void
1868 tmpfs_set_accessed(struct tmpfs_mount *tm, struct tmpfs_node *node)
1869 {
1870         if (node->tn_accessed || tm->tm_ronly)
1871                 return;
1872         atomic_store_8(&node->tn_accessed, true);
1873 }
1874
1875 /* Sync timestamps */
1876 void
1877 tmpfs_itimes(struct vnode *vp, const struct timespec *acc,
1878     const struct timespec *mod)
1879 {
1880         struct tmpfs_node *node;
1881         struct timespec now;
1882
1883         ASSERT_VOP_LOCKED(vp, "tmpfs_itimes");
1884         node = VP_TO_TMPFS_NODE(vp);
1885
1886         if (!node->tn_accessed &&
1887             (node->tn_status & (TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED)) == 0)
1888                 return;
1889
1890         vfs_timestamp(&now);
1891         TMPFS_NODE_LOCK(node);
1892         if (node->tn_accessed) {
1893                 if (acc == NULL)
1894                          acc = &now;
1895                 node->tn_atime = *acc;
1896         }
1897         if (node->tn_status & TMPFS_NODE_MODIFIED) {
1898                 if (mod == NULL)
1899                         mod = &now;
1900                 node->tn_mtime = *mod;
1901         }
1902         if (node->tn_status & TMPFS_NODE_CHANGED)
1903                 node->tn_ctime = now;
1904         node->tn_status &= ~(TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED);
1905         node->tn_accessed = false;
1906         TMPFS_NODE_UNLOCK(node);
1907
1908         /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
1909         random_harvest_queue(node, sizeof(*node), RANDOM_FS_ATIME);
1910 }
1911
1912 int
1913 tmpfs_truncate(struct vnode *vp, off_t length)
1914 {
1915         int error;
1916         struct tmpfs_node *node;
1917
1918         node = VP_TO_TMPFS_NODE(vp);
1919
1920         if (length < 0) {
1921                 error = EINVAL;
1922                 goto out;
1923         }
1924
1925         if (node->tn_size == length) {
1926                 error = 0;
1927                 goto out;
1928         }
1929
1930         if (length > VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
1931                 return (EFBIG);
1932
1933         error = tmpfs_reg_resize(vp, length, FALSE);
1934         if (error == 0)
1935                 node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
1936
1937 out:
1938         tmpfs_update(vp);
1939
1940         return (error);
1941 }
1942
1943 static __inline int
1944 tmpfs_dirtree_cmp(struct tmpfs_dirent *a, struct tmpfs_dirent *b)
1945 {
1946         if (a->td_hash > b->td_hash)
1947                 return (1);
1948         else if (a->td_hash < b->td_hash)
1949                 return (-1);
1950         return (0);
1951 }
1952
1953 RB_GENERATE_STATIC(tmpfs_dir, tmpfs_dirent, uh.td_entries, tmpfs_dirtree_cmp);