Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136042877
D25580.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D25580.diff
View Options
Index: head/sys/fs/tmpfs/tmpfs.h
===================================================================
--- head/sys/fs/tmpfs/tmpfs.h
+++ head/sys/fs/tmpfs/tmpfs.h
@@ -526,6 +526,9 @@
return (node);
}
+#define VP_TO_TMPFS_NODE_SMR(vp) \
+ ((struct tmpfs_node *)vn_load_v_data_smr(vp))
+
static inline struct tmpfs_node *
VP_TO_TMPFS_DIR(struct vnode *vp)
{
Index: head/sys/fs/tmpfs/tmpfs_subr.c
===================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c
+++ head/sys/fs/tmpfs/tmpfs_subr.c
@@ -75,6 +75,7 @@
static uma_zone_t tmpfs_dirent_pool;
static uma_zone_t tmpfs_node_pool;
+VFS_SMR_DECLARE;
static int
tmpfs_node_ctor(void *mem, int size, void *arg, int flags)
@@ -131,6 +132,7 @@
tmpfs_node_pool = uma_zcreate("TMPFS node",
sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor,
tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0);
+ VFS_SMR_ZONE_SET(tmpfs_node_pool);
}
void
@@ -288,7 +290,7 @@
if ((mp->mnt_kern_flag & MNT_RDONLY) != 0)
return (EROFS);
- nnode = uma_zalloc_arg(tmpfs_node_pool, tmp, M_WAITOK);
+ nnode = uma_zalloc_smr(tmpfs_node_pool, M_WAITOK);
/* Generic initialization. */
nnode->tn_type = type;
@@ -435,7 +437,7 @@
panic("tmpfs_free_node: type %p %d", node, (int)node->tn_type);
}
- uma_zfree(tmpfs_node_pool, node);
+ uma_zfree_smr(tmpfs_node_pool, node);
TMPFS_LOCK(tmp);
tmpfs_free_tmp(tmp);
return (true);
@@ -1621,8 +1623,10 @@
{
int error;
struct tmpfs_node *node;
+ mode_t newmode;
ASSERT_VOP_ELOCKED(vp, "chmod");
+ ASSERT_VOP_IN_SEQC(vp);
node = VP_TO_TMPFS_NODE(vp);
@@ -1656,10 +1660,10 @@
return (error);
}
+ newmode = node->tn_mode & ~ALLPERMS;
+ newmode |= mode & ALLPERMS;
+ atomic_store_short(&node->tn_mode, newmode);
- node->tn_mode &= ~ALLPERMS;
- node->tn_mode |= mode & ALLPERMS;
-
node->tn_status |= TMPFS_NODE_CHANGED;
ASSERT_VOP_ELOCKED(vp, "chmod2");
@@ -1682,8 +1686,10 @@
struct tmpfs_node *node;
uid_t ouid;
gid_t ogid;
+ mode_t newmode;
ASSERT_VOP_ELOCKED(vp, "chown");
+ ASSERT_VOP_IN_SEQC(vp);
node = VP_TO_TMPFS_NODE(vp);
@@ -1729,8 +1735,10 @@
node->tn_status |= TMPFS_NODE_CHANGED;
if ((node->tn_mode & (S_ISUID | S_ISGID)) && (ouid != uid || ogid != gid)) {
- if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID))
- node->tn_mode &= ~(S_ISUID | S_ISGID);
+ if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID)) {
+ newmode = node->tn_mode & ~(S_ISUID | S_ISGID);
+ atomic_store_short(&node->tn_mode, newmode);
+ }
}
ASSERT_VOP_ELOCKED(vp, "chown2");
Index: head/sys/fs/tmpfs/tmpfs_vfsops.c
===================================================================
--- head/sys/fs/tmpfs/tmpfs_vfsops.c
+++ head/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -462,6 +462,8 @@
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED |
MNTK_TEXT_REFS | MNTK_NOMSYNC;
+ if (!nonc)
+ mp->mnt_kern_flag |= MNTK_FPLOOKUP;
MNT_IUNLOCK(mp);
mp->mnt_data = tmp;
Index: head/sys/fs/tmpfs/tmpfs_vnops.h
===================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.h
+++ head/sys/fs/tmpfs/tmpfs_vnops.h
@@ -49,6 +49,7 @@
extern struct vop_vector tmpfs_vnodeop_nonc_entries;
vop_access_t tmpfs_access;
+vop_fplookup_vexec_t tmpfs_fplookup_vexec;
vop_getattr_t tmpfs_getattr;
vop_setattr_t tmpfs_setattr;
vop_pathconf_t tmpfs_pathconf;
Index: head/sys/fs/tmpfs/tmpfs_vnops.c
===================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c
+++ head/sys/fs/tmpfs/tmpfs_vnops.c
@@ -55,6 +55,7 @@
#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
+#include <sys/smr.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -64,6 +65,7 @@
#include <fs/tmpfs/tmpfs.h>
SYSCTL_DECL(_vfs_tmpfs);
+VFS_SMR_DECLARE;
static volatile int tmpfs_rename_restarts;
SYSCTL_INT(_vfs_tmpfs, OID_AUTO, rename_restarts, CTLFLAG_RD,
@@ -317,7 +319,33 @@
return (0);
}
+/*
+ * VOP_FPLOOKUP_VEXEC routines are subject to special circumstances, see
+ * the comment above cache_fplookup for details.
+ */
int
+tmpfs_fplookup_vexec(struct vop_fplookup_vexec_args *v)
+{
+ struct vnode *vp;
+ struct tmpfs_node *node;
+ struct ucred *cred;
+ mode_t all_x, mode;
+
+ vp = v->a_vp;
+ node = VP_TO_TMPFS_NODE_SMR(vp);
+ if (__predict_false(node == NULL))
+ return (EAGAIN);
+
+ all_x = S_IXUSR | S_IXGRP | S_IXOTH;
+ mode = atomic_load_short(&node->tn_mode);
+ if (__predict_true((mode & all_x) == all_x))
+ return (0);
+
+ cred = v->a_cred;
+ return (vaccess_vexec_smr(mode, node->tn_uid, node->tn_gid, cred));
+}
+
+int
tmpfs_access(struct vop_access_args *v)
{
struct vnode *vp = v->a_vp;
@@ -427,6 +455,7 @@
int error;
MPASS(VOP_ISLOCKED(vp));
+ ASSERT_VOP_IN_SEQC(vp);
error = 0;
@@ -497,6 +526,7 @@
struct tmpfs_node *node;
off_t oldsize;
int error, ioflag;
+ mode_t newmode;
vp = v->a_vp;
uio = v->a_uio;
@@ -527,8 +557,12 @@
node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
TMPFS_NODE_CHANGED;
if (node->tn_mode & (S_ISUID | S_ISGID)) {
- if (priv_check_cred(v->a_cred, PRIV_VFS_RETAINSUGID))
- 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);
+ vn_seqc_write_begin(vp);
+ atomic_store_short(&node->tn_mode, newmode);
+ vn_seqc_write_end(vp);
+ }
}
if (error != 0)
(void)tmpfs_reg_resize(vp, oldsize, TRUE);
@@ -806,12 +840,15 @@
struct tmpfs_node *tnode;
struct tmpfs_node *tdnode;
int error;
+ bool want_seqc_end;
MPASS(VOP_ISLOCKED(tdvp));
MPASS(IMPLIES(tvp != NULL, VOP_ISLOCKED(tvp)));
MPASS(fcnp->cn_flags & HASBUF);
MPASS(tcnp->cn_flags & HASBUF);
+ want_seqc_end = false;
+
/*
* Disallow cross-device renames.
* XXX Why isn't this done by the caller?
@@ -852,6 +889,13 @@
}
}
+ if (tvp != NULL)
+ vn_seqc_write_begin(tvp);
+ vn_seqc_write_begin(tdvp);
+ vn_seqc_write_begin(fvp);
+ vn_seqc_write_begin(fdvp);
+ want_seqc_end = true;
+
tmp = VFS_TO_TMPFS(tdvp->v_mount);
tdnode = VP_TO_TMPFS_DIR(tdvp);
tnode = (tvp == NULL) ? NULL : VP_TO_TMPFS_NODE(tvp);
@@ -1065,6 +1109,14 @@
VOP_UNLOCK(fdvp);
out:
+ if (want_seqc_end) {
+ if (tvp != NULL)
+ vn_seqc_write_end(tvp);
+ vn_seqc_write_end(tdvp);
+ vn_seqc_write_end(fvp);
+ vn_seqc_write_end(fdvp);
+ }
+
/*
* Release target nodes.
* XXX: I don't understand when tdvp can be the same as tvp, but
@@ -1621,6 +1673,7 @@
.vop_mknod = tmpfs_mknod,
.vop_open = tmpfs_open,
.vop_close = tmpfs_close,
+ .vop_fplookup_vexec = tmpfs_fplookup_vexec,
.vop_access = tmpfs_access,
.vop_getattr = tmpfs_getattr,
.vop_setattr = tmpfs_setattr,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 16, 8:38 AM (11 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25360014
Default Alt Text
D25580.diff (6 KB)
Attached To
Mode
D25580: (lookup 5) tmpfs: add support for lockless lookup
Attached
Detach File
Event Timeline
Log In to Comment