Author: kib
Date: Tue Apr 16 17:33:08 2019
New Revision: 346285
URL: https://svnweb.freebsd.org/changeset/base/346285

Log:
  MFC r345425, r345514, r345799, r345800, r345803, r346157:
  Enable tmpfs rw->ro remounts.

Modified:
  stable/12/sys/fs/tmpfs/tmpfs.h
  stable/12/sys/fs/tmpfs/tmpfs_fifoops.c
  stable/12/sys/fs/tmpfs/tmpfs_subr.c
  stable/12/sys/fs/tmpfs/tmpfs_vfsops.c
  stable/12/sys/fs/tmpfs/tmpfs_vnops.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- stable/12/sys/fs/tmpfs/tmpfs.h      Tue Apr 16 17:16:18 2019        
(r346284)
+++ stable/12/sys/fs/tmpfs/tmpfs.h      Tue Apr 16 17:33:08 2019        
(r346285)
@@ -325,6 +325,11 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
  */
 struct tmpfs_mount {
        /*
+        * Original value of the "size" parameter, for reference purposes,
+        * mostly.
+        */
+       off_t                   tm_size_max;
+       /*
         * Maximum number of memory pages available for use by the file
         * system, set during mount time.  This variable must never be
         * used directly as it may be bigger than the current amount of
@@ -432,8 +437,8 @@ void        tmpfs_dir_destroy(struct tmpfs_mount *, struct 
tm
 struct tmpfs_dirent *  tmpfs_dir_lookup(struct tmpfs_node *node,
                            struct tmpfs_node *f,
                            struct componentname *cnp);
-int    tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, int,
-           u_long *, int *);
+int    tmpfs_dir_getdents(struct tmpfs_mount *, struct tmpfs_node *,
+           struct uio *, int, u_long *, int *);
 int    tmpfs_dir_whiteout_add(struct vnode *, struct componentname *);
 void   tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *);
 int    tmpfs_reg_resize(struct vnode *, off_t, boolean_t);
@@ -447,7 +452,8 @@ int tmpfs_chtimes(struct vnode *, struct vattr *, stru
 void   tmpfs_itimes(struct vnode *, const struct timespec *,
            const struct timespec *);
 
-void   tmpfs_set_status(struct tmpfs_node *node, int status);
+void   tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node,
+           int status);
 void   tmpfs_update(struct vnode *);
 int    tmpfs_truncate(struct vnode *, off_t);
 struct tmpfs_dirent *tmpfs_dir_first(struct tmpfs_node *dnode,

Modified: stable/12/sys/fs/tmpfs/tmpfs_fifoops.c
==============================================================================
--- stable/12/sys/fs/tmpfs/tmpfs_fifoops.c      Tue Apr 16 17:16:18 2019        
(r346284)
+++ stable/12/sys/fs/tmpfs/tmpfs_fifoops.c      Tue Apr 16 17:33:08 2019        
(r346285)
@@ -56,7 +56,8 @@ tmpfs_fifo_close(struct vop_close_args *v)
        struct tmpfs_node *node;
 
        node = VP_TO_TMPFS_NODE(v->a_vp);
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(VFS_TO_TMPFS(v->a_vp->v_mount), node,
+           TMPFS_NODE_ACCESSED);
        tmpfs_update(v->a_vp);
        return (fifo_specops.vop_close(v));
 }

Modified: stable/12/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- stable/12/sys/fs/tmpfs/tmpfs_subr.c Tue Apr 16 17:16:18 2019        
(r346284)
+++ stable/12/sys/fs/tmpfs/tmpfs_subr.c Tue Apr 16 17:33:08 2019        
(r346285)
@@ -218,6 +218,8 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount 
                 */
                return (EBUSY);
        }
+       if ((mp->mnt_kern_flag & MNT_RDONLY) != 0)
+               return (EROFS);
 
        nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp,
            M_WAITOK);
@@ -1108,7 +1110,8 @@ tmpfs_dir_destroy(struct tmpfs_mount *tmp, struct tmpf
  * error happens.
  */
 static int
-tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
+tmpfs_dir_getdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
+    struct uio *uio)
 {
        int error;
        struct dirent dent;
@@ -1128,7 +1131,7 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct u
        else
                error = uiomove(&dent, dent.d_reclen, uio);
 
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
 
        return (error);
 }
@@ -1141,7 +1144,8 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct u
  * error happens.
  */
 static int
-tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
+tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
+    struct uio *uio)
 {
        int error;
        struct dirent dent;
@@ -1172,7 +1176,7 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struc
        else
                error = uiomove(&dent, dent.d_reclen, uio);
 
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
 
        return (error);
 }
@@ -1185,8 +1189,8 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struc
  * error code if another error happens.
  */
 int
-tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
-    u_long *cookies, int *ncookies)
+tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node,
+    struct uio *uio, int maxcookies, u_long *cookies, int *ncookies)
 {
        struct tmpfs_dir_cursor dc;
        struct tmpfs_dirent *de;
@@ -1207,7 +1211,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio
         */
        switch (uio->uio_offset) {
        case TMPFS_DIRCOOKIE_DOT:
-               error = tmpfs_dir_getdotdent(node, uio);
+               error = tmpfs_dir_getdotdent(tm, node, uio);
                if (error != 0)
                        return (error);
                uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
@@ -1215,7 +1219,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio
                        cookies[(*ncookies)++] = off = uio->uio_offset;
                /* FALLTHROUGH */
        case TMPFS_DIRCOOKIE_DOTDOT:
-               error = tmpfs_dir_getdotdotdent(node, uio);
+               error = tmpfs_dir_getdotdotdent(tm, node, uio);
                if (error != 0)
                        return (error);
                de = tmpfs_dir_first(node, &dc);
@@ -1317,7 +1321,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio
        node->tn_dir.tn_readdir_lastn = off;
        node->tn_dir.tn_readdir_lastp = de;
 
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
        return error;
 }
 
@@ -1772,10 +1776,10 @@ tmpfs_chtimes(struct vnode *vp, struct vattr *vap,
 }
 
 void
-tmpfs_set_status(struct tmpfs_node *node, int status)
+tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node, int status)
 {
 
-       if ((node->tn_status & status) == status)
+       if ((node->tn_status & status) == status || tm->tm_ronly)
                return;
        TMPFS_NODE_LOCK(node);
        node->tn_status |= status;

Modified: stable/12/sys/fs/tmpfs/tmpfs_vfsops.c
==============================================================================
--- stable/12/sys/fs/tmpfs/tmpfs_vfsops.c       Tue Apr 16 17:16:18 2019        
(r346284)
+++ stable/12/sys/fs/tmpfs/tmpfs_vfsops.c       Tue Apr 16 17:33:08 2019        
(r346285)
@@ -57,10 +57,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/rwlock.h>
 #include <sys/stat.h>
+#include <sys/sx.h>
 #include <sys/sysctl.h>
 #include <sys/vnode.h>
 
 #include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
 #include <vm/vm_object.h>
 #include <vm/vm_param.h>
 
@@ -88,7 +93,7 @@ static const char *tmpfs_opts[] = {
 };
 
 static const char *tmpfs_updateopts[] = {
-       "from", "export", NULL
+       "from", "export", "size", NULL
 };
 
 static int
@@ -134,7 +139,228 @@ tmpfs_node_fini(void *mem, int size)
        mtx_destroy(&node->tn_interlock);
 }
 
+/*
+ * Handle updates of time from writes to mmaped regions.  Use
+ * MNT_VNODE_FOREACH_ALL instead of MNT_VNODE_FOREACH_ACTIVE, since
+ * unmap of the tmpfs-backed vnode does not call vinactive(), due to
+ * vm object type is OBJT_SWAP.
+ * If lazy, only handle delayed update of mtime due to the writes to
+ * mapped files.
+ */
+static void
+tmpfs_update_mtime(struct mount *mp, bool lazy)
+{
+       struct vnode *vp, *mvp;
+       struct vm_object *obj;
+
+       MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
+               if (vp->v_type != VREG) {
+                       VI_UNLOCK(vp);
+                       continue;
+               }
+               obj = vp->v_object;
+               KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
+                   (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
+
+               /*
+                * In lazy case, do unlocked read, avoid taking vnode
+                * lock if not needed.  Lost update will be handled on
+                * the next call.
+                * For non-lazy case, we must flush all pending
+                * metadata changes now.
+                */
+               if (!lazy || (obj->flags & OBJ_TMPFS_DIRTY) != 0) {
+                       if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK,
+                           curthread) != 0)
+                               continue;
+                       tmpfs_check_mtime(vp);
+                       if (!lazy)
+                               tmpfs_update(vp);
+                       vput(vp);
+               } else {
+                       VI_UNLOCK(vp);
+                       continue;
+               }
+       }
+}
+
+struct tmpfs_check_rw_maps_arg {
+       bool found;
+};
+
+static bool
+tmpfs_check_rw_maps_cb(struct mount *mp __unused, vm_map_t map __unused,
+    vm_map_entry_t entry __unused, void *arg)
+{
+       struct tmpfs_check_rw_maps_arg *a;
+
+       a = arg;
+       a->found = true;
+       return (true);
+}
+
+/*
+ * Revoke write permissions from all mappings of regular files
+ * belonging to the specified tmpfs mount.
+ */
+static bool
+tmpfs_revoke_rw_maps_cb(struct mount *mp __unused, vm_map_t map,
+    vm_map_entry_t entry, void *arg __unused)
+{
+
+       /*
+        * XXXKIB: might be invalidate the mapping
+        * instead ?  The process is not going to be
+        * happy in any case.
+        */
+       entry->max_protection &= ~VM_PROT_WRITE;
+       if ((entry->protection & VM_PROT_WRITE) != 0) {
+               entry->protection &= ~VM_PROT_WRITE;
+               pmap_protect(map->pmap, entry->start, entry->end,
+                   entry->protection);
+       }
+       return (false);
+}
+
+static void
+tmpfs_all_rw_maps(struct mount *mp, bool (*cb)(struct mount *mp, vm_map_t,
+    vm_map_entry_t, void *), void *cb_arg)
+{
+       struct proc *p;
+       struct vmspace *vm;
+       vm_map_t map;
+       vm_map_entry_t entry;
+       vm_object_t object;
+       struct vnode *vp;
+       int gen;
+       bool terminate;
+
+       terminate = false;
+       sx_slock(&allproc_lock);
+again:
+       gen = allproc_gen;
+       FOREACH_PROC_IN_SYSTEM(p) {
+               PROC_LOCK(p);
+               if (p->p_state != PRS_NORMAL || (p->p_flag & (P_INEXEC |
+                   P_SYSTEM | P_WEXIT)) != 0) {
+                       PROC_UNLOCK(p);
+                       continue;
+               }
+               vm = vmspace_acquire_ref(p);
+               _PHOLD_LITE(p);
+               PROC_UNLOCK(p);
+               if (vm == NULL) {
+                       PRELE(p);
+                       continue;
+               }
+               sx_sunlock(&allproc_lock);
+               map = &vm->vm_map;
+
+               vm_map_lock(map);
+               if (map->busy)
+                       vm_map_wait_busy(map);
+               for (entry = map->header.next; entry != &map->header;
+                   entry = entry->next) {
+                       if ((entry->eflags & (MAP_ENTRY_GUARD |
+                           MAP_ENTRY_IS_SUB_MAP | MAP_ENTRY_COW)) != 0 ||
+                           (entry->max_protection & VM_PROT_WRITE) == 0)
+                               continue;
+                       object = entry->object.vm_object;
+                       if (object == NULL || object->type != OBJT_SWAP ||
+                           (object->flags & OBJ_TMPFS_NODE) == 0)
+                               continue;
+                       /*
+                        * No need to dig into shadow chain, mapping
+                        * of the object not at top is readonly.
+                        */
+
+                       VM_OBJECT_RLOCK(object);
+                       if (object->type == OBJT_DEAD) {
+                               VM_OBJECT_RUNLOCK(object);
+                               continue;
+                       }
+                       MPASS(object->ref_count > 1);
+                       if ((object->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) !=
+                           (OBJ_TMPFS_NODE | OBJ_TMPFS)) {
+                               VM_OBJECT_RUNLOCK(object);
+                               continue;
+                       }
+                       vp = object->un_pager.swp.swp_tmpfs;
+                       if (vp->v_mount != mp) {
+                               VM_OBJECT_RUNLOCK(object);
+                               continue;
+                       }
+
+                       terminate = cb(mp, map, entry, cb_arg);
+                       VM_OBJECT_RUNLOCK(object);
+                       if (terminate)
+                               break;
+               }
+               vm_map_unlock(map);
+
+               vmspace_free(vm);
+               sx_slock(&allproc_lock);
+               PRELE(p);
+               if (terminate)
+                       break;
+       }
+       if (!terminate && gen != allproc_gen)
+               goto again;
+       sx_sunlock(&allproc_lock);
+}
+
+static bool
+tmpfs_check_rw_maps(struct mount *mp)
+{
+       struct tmpfs_check_rw_maps_arg ca;
+
+       ca.found = false;
+       tmpfs_all_rw_maps(mp, tmpfs_check_rw_maps_cb, &ca);
+       return (ca.found);
+}
+
 static int
+tmpfs_rw_to_ro(struct mount *mp)
+{
+       int error, flags;
+       bool forced;
+
+       forced = (mp->mnt_flag & MNT_FORCE) != 0;
+       flags = WRITECLOSE | (forced ? FORCECLOSE : 0);
+
+       if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
+               return (error);
+       error = vfs_write_suspend_umnt(mp);
+       if (error != 0)
+               return (error);
+       if (!forced && tmpfs_check_rw_maps(mp)) {
+               error = EBUSY;
+               goto out;
+       }
+       VFS_TO_TMPFS(mp)->tm_ronly = 1;
+       MNT_ILOCK(mp);
+       mp->mnt_flag |= MNT_RDONLY;
+       MNT_IUNLOCK(mp);
+       for (;;) {
+               tmpfs_all_rw_maps(mp, tmpfs_revoke_rw_maps_cb, NULL);
+               tmpfs_update_mtime(mp, false);
+               error = vflush(mp, 0, flags, curthread);
+               if (error != 0) {
+                       VFS_TO_TMPFS(mp)->tm_ronly = 0;
+                       MNT_ILOCK(mp);
+                       mp->mnt_flag &= ~MNT_RDONLY;
+                       MNT_IUNLOCK(mp);
+                       goto out;
+               }
+               if (!tmpfs_check_rw_maps(mp))
+                       break;
+       }
+out:
+       vfs_write_resume(mp, 0);
+       return (error);
+}
+
+static int
 tmpfs_mount(struct mount *mp)
 {
        const size_t nodes_per_page = howmany(PAGE_SIZE,
@@ -161,9 +387,29 @@ tmpfs_mount(struct mount *mp)
                /* Only support update mounts for certain options. */
                if (vfs_filteropt(mp->mnt_optnew, tmpfs_updateopts) != 0)
                        return (EOPNOTSUPP);
-               if (vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) !=
-                   ((struct tmpfs_mount *)mp->mnt_data)->tm_ronly)
-                       return (EOPNOTSUPP);
+               if (vfs_getopt_size(mp->mnt_optnew, "size", &size_max) == 0) {
+                       /*
+                        * On-the-fly resizing is not supported (yet). We still
+                        * need to have "size" listed as "supported", otherwise
+                        * trying to update fs that is listed in fstab with size
+                        * parameter, say trying to change rw to ro or vice
+                        * versa, would cause vfs_filteropt() to bail.
+                        */
+                       if (size_max != VFS_TO_TMPFS(mp)->tm_size_max)
+                               return (EOPNOTSUPP);
+               }
+               if (vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) &&
+                   !(VFS_TO_TMPFS(mp)->tm_ronly)) {
+                       /* RW -> RO */
+                       return (tmpfs_rw_to_ro(mp));
+               } else if (!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) &&
+                   VFS_TO_TMPFS(mp)->tm_ronly) {
+                       /* RO -> RW */
+                       VFS_TO_TMPFS(mp)->tm_ronly = 0;
+                       MNT_ILOCK(mp);
+                       mp->mnt_flag &= ~MNT_RDONLY;
+                       MNT_IUNLOCK(mp);
+               }
                return (0);
        }
 
@@ -229,6 +475,7 @@ tmpfs_mount(struct mount *mp)
        tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : OFF_MAX;
        LIST_INIT(&tmp->tm_nodes_used);
 
+       tmp->tm_size_max = size_max;
        tmp->tm_pages_max = pages;
        tmp->tm_pages_used = 0;
        new_unrhdr64(&tmp->tm_ino_unr, 2);
@@ -433,45 +680,13 @@ tmpfs_statfs(struct mount *mp, struct statfs *sbp)
 static int
 tmpfs_sync(struct mount *mp, int waitfor)
 {
-       struct vnode *vp, *mvp;
-       struct vm_object *obj;
 
        if (waitfor == MNT_SUSPEND) {
                MNT_ILOCK(mp);
                mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED;
                MNT_IUNLOCK(mp);
        } else if (waitfor == MNT_LAZY) {
-               /*
-                * Handle lazy updates of mtime from writes to mmaped
-                * regions.  Use MNT_VNODE_FOREACH_ALL instead of
-                * MNT_VNODE_FOREACH_ACTIVE, since unmap of the
-                * tmpfs-backed vnode does not call vinactive(), due
-                * to vm object type is OBJT_SWAP.
-                */
-               MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
-                       if (vp->v_type != VREG) {
-                               VI_UNLOCK(vp);
-                               continue;
-                       }
-                       obj = vp->v_object;
-                       KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
-                           (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
-
-                       /*
-                        * Unlocked read, avoid taking vnode lock if
-                        * not needed.  Lost update will be handled on
-                        * the next call.
-                        */
-                       if ((obj->flags & OBJ_TMPFS_DIRTY) == 0) {
-                               VI_UNLOCK(vp);
-                               continue;
-                       }
-                       if (vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK,
-                           curthread) != 0)
-                               continue;
-                       tmpfs_check_mtime(vp);
-                       vput(vp);
-               }
+               tmpfs_update_mtime(mp, true);
        }
        return (0);
 }

Modified: stable/12/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- stable/12/sys/fs/tmpfs/tmpfs_vnops.c        Tue Apr 16 17:16:18 2019        
(r346284)
+++ stable/12/sys/fs/tmpfs/tmpfs_vnops.c        Tue Apr 16 17:33:08 2019        
(r346285)
@@ -481,7 +481,7 @@ tmpfs_read(struct vop_read_args *v)
        if (uio->uio_offset < 0)
                return (EINVAL);
        node = VP_TO_TMPFS_NODE(vp);
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
        return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio));
 }
 
@@ -1188,25 +1188,30 @@ tmpfs_symlink(struct vop_symlink_args *v)
 }
 
 static int
-tmpfs_readdir(struct vop_readdir_args *v)
+tmpfs_readdir(struct vop_readdir_args *va)
 {
-       struct vnode *vp = v->a_vp;
-       struct uio *uio = v->a_uio;
-       int *eofflag = v->a_eofflag;
-       u_long **cookies = v->a_cookies;
-       int *ncookies = v->a_ncookies;
-
-       int error;
-       ssize_t startresid;
-       int maxcookies;
+       struct vnode *vp;
+       struct uio *uio;
+       struct tmpfs_mount *tm;
        struct tmpfs_node *node;
+       u_long **cookies;
+       int *eofflag, *ncookies;
+       ssize_t startresid;
+       int error, maxcookies;
 
+       vp = va->a_vp;
+       uio = va->a_uio;
+       eofflag = va->a_eofflag;
+       cookies = va->a_cookies;
+       ncookies = va->a_ncookies;
+
        /* This operation only makes sense on directory nodes. */
        if (vp->v_type != VDIR)
                return ENOTDIR;
 
        maxcookies = 0;
        node = VP_TO_TMPFS_DIR(vp);
+       tm = VFS_TO_TMPFS(vp->v_mount);
 
        startresid = uio->uio_resid;
 
@@ -1220,9 +1225,9 @@ tmpfs_readdir(struct vop_readdir_args *v)
        }
 
        if (cookies == NULL)
-               error = tmpfs_dir_getdents(node, uio, 0, NULL, NULL);
+               error = tmpfs_dir_getdents(tm, node, uio, 0, NULL, NULL);
        else
-               error = tmpfs_dir_getdents(node, uio, maxcookies, *cookies,
+               error = tmpfs_dir_getdents(tm, node, uio, maxcookies, *cookies,
                    ncookies);
 
        /* Buffer was filled without hitting EOF. */
@@ -1258,7 +1263,7 @@ tmpfs_readlink(struct vop_readlink_args *v)
 
        error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid),
            uio);
-       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
+       tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
 
        return (error);
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to