Index: sys/fs/tmpfs/tmpfs.h =================================================================== --- sys/fs/tmpfs/tmpfs.h +++ sys/fs/tmpfs/tmpfs.h @@ -174,10 +174,8 @@ * operations to do modifications to the node in a delayed * fashion. */ - int tn_status; /* (vi) */ -#define TMPFS_NODE_ACCESSED (1 << 1) -#define TMPFS_NODE_MODIFIED (1 << 2) -#define TMPFS_NODE_CHANGED (1 << 3) + uint8_t tn_status; /* (vi) */ + uint8_t tn_accessed; /* unlocked */ /* * The node size. It does not necessarily match the real amount @@ -317,11 +315,16 @@ #define TMPFS_ASSERT_LOCKED(node) (void)0 #endif +/* tn_vpstate */ #define TMPFS_VNODE_ALLOCATING 1 #define TMPFS_VNODE_WANT 2 #define TMPFS_VNODE_DOOMED 4 #define TMPFS_VNODE_WRECLAIM 8 +/* tn_status */ +#define TMPFS_NODE_MODIFIED 0x01 +#define TMPFS_NODE_CHANGED 0x02 + /* * Internal representation of a tmpfs mount point. */ @@ -452,6 +455,7 @@ void tmpfs_itimes(struct vnode *, const struct timespec *, const struct timespec *); +void tmpfs_set_accessed(struct tmpfs_mount *tm, struct tmpfs_node *node); void tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node, int status); int tmpfs_truncate(struct vnode *, off_t); @@ -551,12 +555,10 @@ tmpfs_update_getattr(struct vnode *vp) { struct tmpfs_node *node; - int update_flags; - - update_flags = TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED; node = VP_TO_TMPFS_NODE(vp); - if (__predict_false(node->tn_status & update_flags) != 0) + if (__predict_false((node->tn_status & (TMPFS_NODE_MODIFIED | + TMPFS_NODE_CHANGED)) != 0 || node->tn_accessed)) tmpfs_update(vp); } Index: sys/fs/tmpfs/tmpfs_fifoops.c =================================================================== --- sys/fs/tmpfs/tmpfs_fifoops.c +++ sys/fs/tmpfs/tmpfs_fifoops.c @@ -56,8 +56,7 @@ struct tmpfs_node *node; node = VP_TO_TMPFS_NODE(v->a_vp); - tmpfs_set_status(VFS_TO_TMPFS(v->a_vp->v_mount), node, - TMPFS_NODE_ACCESSED); + tmpfs_set_accessed(VFS_TO_TMPFS(v->a_vp->v_mount), node); tmpfs_update(v->a_vp); return (fifo_specops.vop_close(v)); } Index: sys/fs/tmpfs/tmpfs_subr.c =================================================================== --- sys/fs/tmpfs/tmpfs_subr.c +++ sys/fs/tmpfs/tmpfs_subr.c @@ -88,6 +88,7 @@ node->tn_gen++; node->tn_size = 0; node->tn_status = 0; + node->tn_accessed = false; node->tn_flags = 0; node->tn_links = 0; node->tn_vnode = NULL; @@ -1098,8 +1099,8 @@ tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, de); } dnode->tn_size += sizeof(struct tmpfs_dirent); - dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ - TMPFS_NODE_MODIFIED; + dnode->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + dnode->tn_accessed = true; tmpfs_update(vp); } @@ -1145,8 +1146,8 @@ RB_REMOVE(tmpfs_dir, head, de); dnode->tn_size -= sizeof(struct tmpfs_dirent); - dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ - TMPFS_NODE_MODIFIED; + dnode->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + dnode->tn_accessed = true; tmpfs_update(vp); } @@ -1199,7 +1200,7 @@ else error = uiomove(&dent, dent.d_reclen, uio); - tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); + tmpfs_set_accessed(tm, node); return (error); } @@ -1246,7 +1247,7 @@ else error = uiomove(&dent, dent.d_reclen, uio); - tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); + tmpfs_set_accessed(tm, node); return (error); } @@ -1391,8 +1392,8 @@ node->tn_dir.tn_readdir_lastn = off; node->tn_dir.tn_readdir_lastp = de; - tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); - return error; + tmpfs_set_accessed(tm, node); + return (error); } int @@ -1818,18 +1819,18 @@ /* Disallow this operation if the file system is mounted read-only. */ if (vp->v_mount->mnt_flag & MNT_RDONLY) - return EROFS; + return (EROFS); /* Immutable or append-only files cannot be modified, either. */ if (node->tn_flags & (IMMUTABLE | APPEND)) - return EPERM; + return (EPERM); error = vn_utimes_perm(vp, vap, cred, l); if (error != 0) return (error); if (vap->va_atime.tv_sec != VNOVAL) - node->tn_status |= TMPFS_NODE_ACCESSED; + node->tn_accessed = true; if (vap->va_mtime.tv_sec != VNOVAL) node->tn_status |= TMPFS_NODE_MODIFIED; @@ -1857,6 +1858,14 @@ TMPFS_NODE_UNLOCK(node); } +void +tmpfs_set_accessed(struct tmpfs_mount *tm, struct tmpfs_node *node) +{ + if (node->tn_accessed || tm->tm_ronly) + return; + node->tn_accessed = true; +} + /* Sync timestamps */ void tmpfs_itimes(struct vnode *vp, const struct timespec *acc, @@ -1868,13 +1877,13 @@ ASSERT_VOP_LOCKED(vp, "tmpfs_itimes"); node = VP_TO_TMPFS_NODE(vp); - if ((node->tn_status & (TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | - TMPFS_NODE_CHANGED)) == 0) + if (!node->tn_accessed || + (node->tn_status & (TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED)) == 0) return; vfs_timestamp(&now); TMPFS_NODE_LOCK(node); - if (node->tn_status & TMPFS_NODE_ACCESSED) { + if (node->tn_accessed) { if (acc == NULL) acc = &now; node->tn_atime = *acc; @@ -1886,8 +1895,8 @@ } if (node->tn_status & TMPFS_NODE_CHANGED) node->tn_ctime = now; - node->tn_status &= ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | - TMPFS_NODE_CHANGED); + node->tn_status &= ~(TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED); + node->tn_accessed = false; TMPFS_NODE_UNLOCK(node); /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */ Index: sys/fs/tmpfs/tmpfs_vnops.c =================================================================== --- sys/fs/tmpfs/tmpfs_vnops.c +++ sys/fs/tmpfs/tmpfs_vnops.c @@ -584,7 +584,7 @@ if (uio->uio_offset < 0) return (EINVAL); node = VP_TO_TMPFS_NODE(vp); - tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED); + tmpfs_set_accessed(VFS_TO_TMPFS(vp->v_mount), node); return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio)); } @@ -620,6 +620,7 @@ if (!VN_IS_DOOMED(vp)) { /* size cannot become shorter due to rangelock. */ size = node->tn_size; + tmpfs_set_accessed(node->tn_reg.tn_tmp, node); vfs_smr_exit(); error = uiomove_object(object, size, v->a_uio); return (error); @@ -665,8 +666,8 @@ } error = uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio); - node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | - TMPFS_NODE_CHANGED; + node->tn_status |= TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED; + node->tn_accessed = true; if (node->tn_mode & (S_ISUID | S_ISGID)) { if (priv_check_cred(v->a_cred, PRIV_VFS_RETAINSUGID)) { newmode = node->tn_mode & ~(S_ISUID | S_ISGID); @@ -742,12 +743,12 @@ * reclaimed. */ tmpfs_free_dirent(tmp, de); - node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED; + node->tn_status |= TMPFS_NODE_CHANGED; + node->tn_accessed = true; error = 0; out: - - return error; + return (error); } static int @@ -1316,15 +1317,15 @@ TMPFS_NODE_LOCK(node); node->tn_links--; node->tn_dir.tn_parent = NULL; - node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | - TMPFS_NODE_MODIFIED; + node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + node->tn_accessed = true; TMPFS_NODE_UNLOCK(node); TMPFS_NODE_LOCK(dnode); dnode->tn_links--; - dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | - TMPFS_NODE_MODIFIED; + dnode->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + dnode->tn_accessed = true; TMPFS_NODE_UNLOCK(dnode); if (tmpfs_use_nc(dvp)) { @@ -1443,7 +1444,7 @@ error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid), uio); - tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED); + tmpfs_set_accessed(VFS_TO_TMPFS(vp->v_mount), node); return (error); }