diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-08 04:44:33 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-10 12:44:34 +0000 |
| commit | c2012c7faf74c9e7b4e3de2472e10b58ed096996 (patch) | |
| tree | 6e61ce7f2bd9bb37edd000a4f8c37cbe3a199766 /sys | |
| parent | 2b256f00aaee4713b8e6f0e3c0f3493065f710c4 (diff) | |
This should prevent seeing inconsistent flags values when updating it
under the shared vnode lock.
Noted and reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D55665
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/fs/p9fs/p9fs.h | 9 | ||||
| -rw-r--r-- | sys/fs/p9fs/p9fs_vfsops.c | 6 | ||||
| -rw-r--r-- | sys/fs/p9fs/p9fs_vnops.c | 8 |
3 files changed, 13 insertions, 10 deletions
diff --git a/sys/fs/p9fs/p9fs.h b/sys/fs/p9fs/p9fs.h index a270d8b5ce5f..2470734fef4d 100644 --- a/sys/fs/p9fs/p9fs.h +++ b/sys/fs/p9fs/p9fs.h @@ -103,7 +103,7 @@ struct p9fs_node { struct p9fs_inode inode; /* in memory representation of ondisk information*/ struct p9fs_session *p9fs_ses; /* Session_ptr for this node */ STAILQ_ENTRY(p9fs_node) p9fs_node_next; - uint64_t flags; + u_int flags; }; #define P9FS_VTON(vp) ((struct p9fs_node *)(vp)->v_data) @@ -111,10 +111,13 @@ struct p9fs_node { #define VFSTOP9(mp) ((struct p9fs_mount *)(mp)->mnt_data) #define QEMU_DIRENTRY_SZ 25 #define P9FS_NODE_MODIFIED 0x1 /* indicating file change */ -#define P9FS_ROOT 0x2 /* indicating root p9fs node */ +#define P9FS_NODE_ROOT 0x2 /* indicating root p9fs node */ #define P9FS_NODE_DELETED 0x4 /* indicating file or directory delete */ #define P9FS_NODE_IN_SESSION 0x8 /* p9fs_node is in the session - virt_node_list */ -#define IS_ROOT(node) (node->flags & P9FS_ROOT) +#define IS_ROOT(node) (((node)->flags & P9FS_NODE_ROOT) != 0) + +#define P9FS_NODE_SETF(n, f) atomic_set_int(&(n)->flags, (f)) +#define P9FS_NODE_CLRF(n, f) atomic_clear_int(&(n)->flags, (f)) #define P9FS_SET_LINKS(inode) do { \ (inode)->i_links_count = 1; \ diff --git a/sys/fs/p9fs/p9fs_vfsops.c b/sys/fs/p9fs/p9fs_vfsops.c index 953e6eda547a..0e09c58e57b6 100644 --- a/sys/fs/p9fs/p9fs_vfsops.c +++ b/sys/fs/p9fs/p9fs_vfsops.c @@ -284,7 +284,7 @@ p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags, node = vp->v_data; /* Remove stale vnode from hash list */ vfs_hash_remove(vp); - node->flags |= P9FS_NODE_DELETED; + P9FS_NODE_SETF(node, P9FS_NODE_DELETED); vput(vp); *vpp = NULL; @@ -372,7 +372,7 @@ p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags, if (*vpp == NULL) { P9FS_LOCK(vses); STAILQ_INSERT_TAIL(&vses->virt_node_list, np, p9fs_node_next); - np->flags |= P9FS_NODE_IN_SESSION; + P9FS_NODE_SETF(np, P9FS_NODE_IN_SESSION); P9FS_UNLOCK(vses); vn_set_state(vp, VSTATE_CONSTRUCTED); *vpp = vp; @@ -448,7 +448,7 @@ p9_mount(struct mount *mp) P9FS_VOFID_LOCK_INIT(p9fs_root); STAILQ_INIT(&p9fs_root->vofid_list); p9fs_root->parent = p9fs_root; - p9fs_root->flags |= P9FS_ROOT; + P9FS_NODE_SETF(p9fs_root, P9FS_NODE_ROOT); p9fs_root->p9fs_ses = vses; vfs_getnewfsid(mp); strlcpy(mp->mnt_stat.f_mntfromname, from, diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c index c6d35548e9ed..081903d73e5e 100644 --- a/sys/fs/p9fs/p9fs_vnops.c +++ b/sys/fs/p9fs/p9fs_vnops.c @@ -111,7 +111,7 @@ p9fs_cleanup(struct p9fs_node *np) P9FS_LOCK(vses); if ((np->flags & P9FS_NODE_IN_SESSION) != 0) { - np->flags &= ~P9FS_NODE_IN_SESSION; + P9FS_NODE_CLRF(np, P9FS_NODE_IN_SESSION); STAILQ_REMOVE(&vses->virt_node_list, np, p9fs_node, p9fs_node_next); } else { P9FS_UNLOCK(vses); @@ -675,7 +675,7 @@ p9fs_open(struct vop_open_args *ap) error = vinvalbuf(vp, 0, 0, 0); if (error != 0) return (error); - np->flags &= ~P9FS_NODE_MODIFIED; + P9FS_NODE_CLRF(np, P9FS_NODE_MODIFIED); } vfid = p9fs_get_fid(vses->clnt, np, ap->a_cred, VFID, -1, &error); @@ -1003,7 +1003,7 @@ p9fs_stat_vnode_dotl(struct p9_stat_dotl *stat, struct vnode *vp) /* Setting a flag if file changes based on qid version */ if (np->vqid.qid_version != stat->qid.version) - np->flags |= P9FS_NODE_MODIFIED; + P9FS_NODE_SETF(np, P9FS_NODE_MODIFIED); memcpy(&np->vqid, &stat->qid, sizeof(stat->qid)); if (!excl_locked) VI_UNLOCK(vp); @@ -1549,7 +1549,7 @@ remove_common(struct p9fs_node *dnp, struct p9fs_node *np, const char *name, cache_purge(vp); vfs_hash_remove(vp); - np->flags |= P9FS_NODE_DELETED; + P9FS_NODE_SETF(np, P9FS_NODE_DELETED); return (error); } |
