aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/tmpfs/tmpfs_vfsops.c
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2021-05-07 14:43:43 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2021-05-22 18:28:55 +0000
commit443baed524c9171c3774bf2e3a118970f2fa8c0f (patch)
treee99d04e5db59532bd2cb5f3cb2754eee2be67e0b /sys/fs/tmpfs/tmpfs_vfsops.c
parent90b82ea9a64fe3bc1c5caa26228d1983b9681fa1 (diff)
downloadsrc-443baed524c9171c3774bf2e3a118970f2fa8c0f.tar.gz
src-443baed524c9171c3774bf2e3a118970f2fa8c0f.zip
tmpfs: reimplement the mtime scan to use the lazy list
Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D30065 (cherry picked from commit eec2e4ef7f964d18fcec3dc2cdcd7530be490835)
Diffstat (limited to 'sys/fs/tmpfs/tmpfs_vfsops.c')
-rw-r--r--sys/fs/tmpfs/tmpfs_vfsops.c67
1 files changed, 35 insertions, 32 deletions
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index 4f29b5dfc6f0..7dffb9027946 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -99,18 +99,38 @@ static const char *tmpfs_updateopts[] = {
"from", "export", "nomtime", "size", NULL
};
-/*
- * Handle updates of time from writes to mmaped regions, if allowed.
- * Use MNT_VNODE_FOREACH_ALL instead of MNT_VNODE_FOREACH_LAZY, since
- * unmap of the tmpfs-backed vnode does not call vinactive(), due to
- * vm object type is basically OBJT_SWAP. If lazy, only handle
- * delayed update of mtime due to the writes to mapped files.
- */
+static int
+tmpfs_update_mtime_lazy_filter(struct vnode *vp, void *arg)
+{
+ struct vm_object *obj;
+
+ if (vp->v_type != VREG)
+ return (0);
+
+ obj = atomic_load_ptr(&vp->v_object);
+ if (obj == NULL)
+ return (0);
+
+ return (vm_object_mightbedirty_(obj));
+}
+
static void
-tmpfs_update_mtime(struct mount *mp, bool lazy)
+tmpfs_update_mtime_lazy(struct mount *mp)
+{
+ struct vnode *vp, *mvp;
+
+ MNT_VNODE_FOREACH_LAZY(vp, mp, mvp, tmpfs_update_mtime_lazy_filter, NULL) {
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) != 0)
+ continue;
+ tmpfs_check_mtime(vp);
+ vput(vp);
+ }
+}
+
+static void
+tmpfs_update_mtime_all(struct mount *mp)
{
struct vnode *vp, *mvp;
- struct vm_object *obj;
if (VFS_TO_TMPFS(mp)->tm_nomtime)
return;
@@ -119,28 +139,11 @@ tmpfs_update_mtime(struct mount *mp, bool lazy)
VI_UNLOCK(vp);
continue;
}
- obj = vp->v_object;
- MPASS(obj->type == tmpfs_pager_type);
- MPASS((obj->flags & OBJ_TMPFS) != 0);
-
- /*
- * 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->generation != obj->cleangeneration) {
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) != 0)
- continue;
- tmpfs_check_mtime(vp);
- if (!lazy)
- tmpfs_update(vp);
- vput(vp);
- } else {
- VI_UNLOCK(vp);
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) != 0)
continue;
- }
+ tmpfs_check_mtime(vp);
+ tmpfs_update(vp);
+ vput(vp);
}
}
@@ -300,7 +303,7 @@ tmpfs_rw_to_ro(struct mount *mp)
MNT_IUNLOCK(mp);
for (;;) {
tmpfs_all_rw_maps(mp, tmpfs_revoke_rw_maps_cb, NULL);
- tmpfs_update_mtime(mp, false);
+ tmpfs_update_mtime_all(mp);
error = vflush(mp, 0, flags, curthread);
if (error != 0) {
VFS_TO_TMPFS(mp)->tm_ronly = 0;
@@ -653,7 +656,7 @@ tmpfs_sync(struct mount *mp, int waitfor)
mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED;
MNT_IUNLOCK(mp);
} else if (waitfor == MNT_LAZY) {
- tmpfs_update_mtime(mp, true);
+ tmpfs_update_mtime_lazy(mp);
}
return (0);
}