Page MenuHomeFreeBSD

D26451.1793715025.diff
No OneTemporary

Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None

D26451.1793715025.diff

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

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)

Event Timeline