Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177001985
D26451.1793715025.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
D26451.1793715025.diff
View Options
Index: sys/fs/tmpfs/tmpfs.h
===================================================================
--- sys/fs/tmpfs/tmpfs.h
+++ sys/fs/tmpfs/tmpfs.h
@@ -173,11 +173,13 @@
* Node's internal status. This is used by several file system
* operations to do modifications to the node in a delayed
* fashion.
+ *
+ * tn_accessed has a dedicated byte to allow update by store without
+ * using atomics. This provides a micro-optimization to e.g.
+ * tmpfs_read_pgcache().
*/
- 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 +319,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 +459,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 +559,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
@@ -1579,7 +1580,7 @@
/* Disallow this operation if the file system is mounted read-only. */
if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return EROFS;
+ return (EROFS);
/*
* Callers may only modify the file flags on objects they
@@ -1702,11 +1703,11 @@
/* 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);
/*
* To modify the ownership of a file, must possess VADMIN for that
@@ -1765,11 +1766,11 @@
error = 0;
switch (vp->v_type) {
case VDIR:
- return EISDIR;
+ return (EISDIR);
case VREG:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return EROFS;
+ return (EROFS);
break;
case VBLK:
@@ -1777,23 +1778,27 @@
case VCHR:
/* FALLTHROUGH */
case VFIFO:
- /* Allow modifications of special files even if in the file
+ /*
+ * Allow modifications of special files even if in the file
* system is mounted read-only (we are not modifying the
- * files themselves, but the objects they represent). */
- return 0;
+ * files themselves, but the objects they represent).
+ */
+ return (0);
default:
/* Anything else is unsupported. */
- return EOPNOTSUPP;
+ return (EOPNOTSUPP);
}
/* Immutable or append-only files cannot be modified, either. */
if (node->tn_flags & (IMMUTABLE | APPEND))
- return EPERM;
+ return (EPERM);
error = tmpfs_truncate(vp, size);
- /* tmpfs_truncate will raise the NOTE_EXTEND and NOTE_ATTRIB kevents
- * for us, as will update tn_status; no need to do that here. */
+ /*
+ * tmpfs_truncate will raise the NOTE_EXTEND and NOTE_ATTRIB kevents
+ * for us, as will update tn_status; no need to do that here.
+ */
ASSERT_VOP_ELOCKED(vp, "chsize2");
@@ -1818,18 +1823,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 +1862,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;
+ atomic_store_8(&node->tn_accessed, true);
+}
+
/* Sync timestamps */
void
tmpfs_itimes(struct vnode *vp, const struct timespec *acc,
@@ -1868,13 +1881,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 +1899,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
@@ -426,7 +426,7 @@
out:
MPASS(VOP_ISLOCKED(vp));
- return error;
+ return (error);
}
int
@@ -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);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 3, 2:10 PM (10 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41372211
Default Alt Text
D26451.1793715025.diff (9 KB)
Attached To
Mode
D26451: tmpfs: restore atime updates for reads from page cache.
Attached
Detach File
Event Timeline