summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/tmpfs/tmpfs.h1
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c42
2 files changed, 22 insertions, 21 deletions
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h
index 9ef7731..f681e32 100644
--- a/sys/fs/tmpfs/tmpfs.h
+++ b/sys/fs/tmpfs/tmpfs.h
@@ -256,6 +256,7 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
#define TMPFS_NODE_LOCK(node) mtx_lock(&(node)->tn_interlock)
#define TMPFS_NODE_UNLOCK(node) mtx_unlock(&(node)->tn_interlock)
+#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock)
#define TMPFS_VNODE_ALLOCATING 1
#define TMPFS_VNODE_WANT 2
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 24c0dc9..4a2ae2d 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -215,9 +215,8 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
break;
case VREG:
- if (node->tn_reg.tn_aobj != NULL) {
+ if (node->tn_reg.tn_aobj != NULL)
vm_object_deallocate(node->tn_reg.tn_aobj);
- }
pages = node->tn_reg.tn_aobj_pages;
break;
@@ -309,11 +308,8 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, struct vnode **vpp,
int error;
struct vnode *vp;
- vp = NULL;
-
loop:
- if (node->tn_vnode != NULL) {
- vp = node->tn_vnode;
+ if ((vp = node->tn_vnode) != NULL) {
error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (error)
return error;
@@ -337,12 +333,16 @@ loop:
TMPFS_NODE_LOCK(node);
if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) {
node->tn_vpstate |= TMPFS_VNODE_WANT;
- TMPFS_NODE_UNLOCK(node);
- (void) tsleep((caddr_t) &node->tn_vpstate, 0, "tmpfs_vplock", 0);
- goto loop;
- }
+ error = msleep((caddr_t) &node->tn_vpstate,
+ TMPFS_NODE_MTX(node), PDROP | PCATCH,
+ "tmpfs_vplock", 0);
+ if (error)
+ return error;
- node->tn_vpstate |= TMPFS_VNODE_ALLOCATING;
+ goto loop;
+ } else
+ node->tn_vpstate |= TMPFS_VNODE_ALLOCATING;
+
TMPFS_NODE_UNLOCK(node);
/* Get a new vnode and associate it with our node. */
@@ -367,21 +367,18 @@ loop:
case VBLK:
/* FALLTHROUGH */
case VCHR:
- break;
-
+ /* FALLTHROUGH */
case VDIR:
- break;
-
- case VFIFO:
- vp->v_op = &tmpfs_fifoop_entries;
- break;
-
+ /* FALLTHROUGH */
case VLNK:
/* FALLTHROUGH */
case VREG:
/* FALLTHROUGH */
case VSOCK:
break;
+ case VFIFO:
+ vp->v_op = &tmpfs_fifoop_entries;
+ break;
default:
MPASS(0);
@@ -391,6 +388,7 @@ loop:
error = insmntque(vp, mp);
if (error) {
node->tn_vnode = NULL;
+ TMPFS_NODE_LOCK(node);
if (node->tn_vpstate & TMPFS_VNODE_WANT) {
node->tn_vpstate &= ~TMPFS_VNODE_WANT;
TMPFS_NODE_UNLOCK(node);
@@ -402,8 +400,8 @@ loop:
node->tn_vnode = vp;
unlock:
- MPASS(node->tn_vpstate & TMPFS_VNODE_ALLOCATING);
TMPFS_NODE_LOCK(node);
+ MPASS(node->tn_vpstate & TMPFS_VNODE_ALLOCATING);
node->tn_vpstate &= ~TMPFS_VNODE_ALLOCATING;
if (node->tn_vpstate & TMPFS_VNODE_WANT) {
@@ -530,6 +528,7 @@ tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de)
{
struct tmpfs_node *dnode;
+ ASSERT_VOP_ELOCKED(vp, __func__);
dnode = VP_TO_TMPFS_DIR(vp);
TAILQ_INSERT_TAIL(&dnode->tn_dir.tn_dirhead, de, td_entries);
dnode->tn_size += sizeof(struct tmpfs_dirent);
@@ -549,6 +548,7 @@ tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
{
struct tmpfs_node *dnode;
+ ASSERT_VOP_ELOCKED(vp, __func__);
dnode = VP_TO_TMPFS_DIR(vp);
if (dnode->tn_dir.tn_readdir_lastp == de) {
@@ -873,7 +873,7 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize)
swap_pager_freespace(uobj,
newpages, oldpages - newpages);
vm_object_page_remove(uobj,
- OFF_TO_IDX(newsize + PAGE_MASK), 0, FALSE);
+ OFF_TO_IDX(newsize + PAGE_MASK), 0, FALSE);
}
/*
OpenPOWER on IntegriCloud