Author: kib
Date: Wed Feb 11 09:02:21 2015
New Revision: 278571
URL: https://svnweb.freebsd.org/changeset/base/278571

Log:
  MFC r277828:
  Update mtime for tmpfs files modified through memory mapping.
  
  MFC r277969:
  Update both ctime and mtime for writes to tmpfs files.
  
  MFC r277972:
  Remove single-use boolean.
  
  MFC r278151:
  Remove duplicated assignment.

Modified:
  stable/10/sys/fs/tmpfs/tmpfs.h
  stable/10/sys/fs/tmpfs/tmpfs_subr.c
  stable/10/sys/fs/tmpfs/tmpfs_vfsops.c
  stable/10/sys/fs/tmpfs/tmpfs_vnops.c
  stable/10/sys/vm/vm_fault.c
  stable/10/sys/vm/vm_object.c
  stable/10/sys/vm/vm_object.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs.h      Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/fs/tmpfs/tmpfs.h      Wed Feb 11 09:02:21 2015        
(r278571)
@@ -398,6 +398,7 @@ int tmpfs_alloc_vp(struct mount *, struc
 void   tmpfs_free_vp(struct vnode *);
 int    tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *,
            struct componentname *, char *);
+void   tmpfs_check_mtime(struct vnode *);
 void   tmpfs_dir_attach(struct vnode *, struct tmpfs_dirent *);
 void   tmpfs_dir_detach(struct vnode *, struct tmpfs_dirent *);
 void   tmpfs_dir_destroy(struct tmpfs_mount *, struct tmpfs_node *);

Modified: stable/10/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs_subr.c Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/fs/tmpfs/tmpfs_subr.c Wed Feb 11 09:02:21 2015        
(r278571)
@@ -1417,6 +1417,31 @@ retry:
        return (0);
 }
 
+void
+tmpfs_check_mtime(struct vnode *vp)
+{
+       struct tmpfs_node *node;
+       struct vm_object *obj;
+
+       ASSERT_VOP_ELOCKED(vp, "check_mtime");
+       if (vp->v_type != VREG)
+               return;
+       obj = vp->v_object;
+       KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
+           (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
+       /* unlocked read */
+       if ((obj->flags & OBJ_TMPFS_DIRTY) != 0) {
+               VM_OBJECT_WLOCK(obj);
+               if ((obj->flags & OBJ_TMPFS_DIRTY) != 0) {
+                       obj->flags &= ~OBJ_TMPFS_DIRTY;
+                       node = VP_TO_TMPFS_NODE(vp);
+                       node->tn_status |= TMPFS_NODE_MODIFIED |
+                           TMPFS_NODE_CHANGED;
+               }
+               VM_OBJECT_WUNLOCK(obj);
+       }
+}
+
 /*
  * Change flags of the given vnode.
  * Caller should execute tmpfs_update on vp after a successful execution.

Modified: stable/10/sys/fs/tmpfs/tmpfs_vfsops.c
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs_vfsops.c       Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/fs/tmpfs/tmpfs_vfsops.c       Wed Feb 11 09:02:21 2015        
(r278571)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/jail.h>
 #include <sys/kernel.h>
+#include <sys/rwlock.h>
 #include <sys/stat.h>
 #include <sys/systm.h>
 #include <sys/sysctl.h>
@@ -417,11 +418,45 @@ tmpfs_statfs(struct mount *mp, struct st
 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);
+               }
        }
        return (0);
 }

Modified: stable/10/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- stable/10/sys/fs/tmpfs/tmpfs_vnops.c        Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/fs/tmpfs/tmpfs_vnops.c        Wed Feb 11 09:02:21 2015        
(r278571)
@@ -453,7 +453,6 @@ tmpfs_write(struct vop_write_args *v)
        struct tmpfs_node *node;
        off_t oldsize;
        int error, ioflag;
-       boolean_t extended;
 
        vp = v->a_vp;
        uio = v->a_uio;
@@ -473,8 +472,7 @@ tmpfs_write(struct vop_write_args *v)
                return (EFBIG);
        if (vn_rlimit_fsize(vp, uio, uio->uio_td))
                return (EFBIG);
-       extended = uio->uio_offset + uio->uio_resid > node->tn_size;
-       if (extended) {
+       if (uio->uio_offset + uio->uio_resid > node->tn_size) {
                error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid,
                    FALSE);
                if (error != 0)
@@ -483,7 +481,7 @@ tmpfs_write(struct vop_write_args *v)
 
        error = uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio);
        node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
-           (extended ? TMPFS_NODE_CHANGED : 0);
+           TMPFS_NODE_CHANGED;
        if (node->tn_mode & (S_ISUID | S_ISGID)) {
                if (priv_check_cred(v->a_cred, PRIV_VFS_RETAINSUGID, 0))
                        node->tn_mode &= ~(S_ISUID | S_ISGID);
@@ -505,6 +503,7 @@ tmpfs_fsync(struct vop_fsync_args *v)
 
        MPASS(VOP_ISLOCKED(vp));
 
+       tmpfs_check_mtime(vp);
        tmpfs_update(vp);
 
        return 0;
@@ -1222,16 +1221,16 @@ tmpfs_readlink(struct vop_readlink_args 
 static int
 tmpfs_inactive(struct vop_inactive_args *v)
 {
-       struct vnode *vp = v->a_vp;
-
+       struct vnode *vp;
        struct tmpfs_node *node;
 
+       vp = v->a_vp;
        node = VP_TO_TMPFS_NODE(vp);
-
        if (node->tn_links == 0)
                vrecycle(vp);
-
-       return 0;
+       else
+               tmpfs_check_mtime(vp);
+       return (0);
 }
 
 int

Modified: stable/10/sys/vm/vm_fault.c
==============================================================================
--- stable/10/sys/vm/vm_fault.c Wed Feb 11 09:00:22 2015        (r278570)
+++ stable/10/sys/vm/vm_fault.c Wed Feb 11 09:02:21 2015        (r278571)
@@ -358,11 +358,13 @@ RetryFault:;
            (fault_flags & (VM_FAULT_CHANGE_WIRING | VM_FAULT_DIRTY)) == 0 &&
            /* avoid calling vm_object_set_writeable_dirty() */
            ((prot & VM_PROT_WRITE) == 0 ||
-           fs.first_object->type != OBJT_VNODE ||
+           (fs.first_object->type != OBJT_VNODE &&
+           (fs.first_object->flags & OBJ_TMPFS_NODE) == 0) ||
            (fs.first_object->flags & OBJ_MIGHTBEDIRTY) != 0)) {
                VM_OBJECT_RLOCK(fs.first_object);
                if ((prot & VM_PROT_WRITE) != 0 &&
-                   fs.first_object->type == OBJT_VNODE &&
+                   (fs.first_object->type == OBJT_VNODE ||
+                   (fs.first_object->flags & OBJ_TMPFS_NODE) != 0) &&
                    (fs.first_object->flags & OBJ_MIGHTBEDIRTY) == 0)
                        goto fast_failed;
                m = vm_page_lookup(fs.first_object, fs.first_pindex);

Modified: stable/10/sys/vm/vm_object.c
==============================================================================
--- stable/10/sys/vm/vm_object.c        Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/vm/vm_object.c        Wed Feb 11 09:02:21 2015        
(r278571)
@@ -2200,8 +2200,13 @@ vm_object_set_writeable_dirty(vm_object_
 {
 
        VM_OBJECT_ASSERT_WLOCKED(object);
-       if (object->type != OBJT_VNODE)
+       if (object->type != OBJT_VNODE) {
+               if ((object->flags & OBJ_TMPFS_NODE) != 0) {
+                       KASSERT(object->type == OBJT_SWAP, ("non-swap tmpfs"));
+                       vm_object_set_flag(object, OBJ_TMPFS_DIRTY);
+               }
                return;
+       }
        object->generation++;
        if ((object->flags & OBJ_MIGHTBEDIRTY) != 0)
                return;

Modified: stable/10/sys/vm/vm_object.h
==============================================================================
--- stable/10/sys/vm/vm_object.h        Wed Feb 11 09:00:22 2015        
(r278570)
+++ stable/10/sys/vm/vm_object.h        Wed Feb 11 09:02:21 2015        
(r278571)
@@ -187,6 +187,7 @@ struct vm_object {
 #define OBJ_PIPWNT     0x0040          /* paging in progress wanted */
 #define OBJ_MIGHTBEDIRTY 0x0100                /* object might be dirty, only 
for vnode */
 #define        OBJ_TMPFS_NODE  0x0200          /* object belongs to tmpfs VREG 
node */
+#define        OBJ_TMPFS_DIRTY 0x0400          /* dirty tmpfs obj */
 #define        OBJ_COLORED     0x1000          /* pg_color is defined */
 #define        OBJ_ONEMAPPING  0x2000          /* One USE (a single, 
non-forked) mapping flag */
 #define        OBJ_DISCONNECTWNT 0x4000        /* disconnect from vnode wanted 
*/
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "[email protected]"

Reply via email to