kernel -- tmpfs: Mark tmpfs_write MPSAFE.
[dragonfly.git] / sys / vfs / tmpfs / tmpfs_vnops.c
index 11a9614..5ae3183 100644 (file)
@@ -303,6 +303,7 @@ tmpfs_getattr(struct vop_getattr_args *v)
 
        node = VP_TO_TMPFS_NODE(vp);
 
+       lwkt_gettoken(&vp->v_mount->mnt_token);
        tmpfs_update(vp);
 
        vap->va_type = vp->v_type;
@@ -330,6 +331,8 @@ tmpfs_getattr(struct vop_getattr_args *v)
        vap->va_bytes = round_page(node->tn_size);
        vap->va_filerev = 0;
 
+       lwkt_reltoken(&vp->v_mount->mnt_token);
+
        return 0;
 }
 
@@ -427,7 +430,6 @@ tmpfs_read (struct vop_read_args *ap)
        off_t base_offset;
        size_t offset;
        size_t len;
-       int got_mplock;
        int error;
 
        error = 0;
@@ -442,40 +444,24 @@ tmpfs_read (struct vop_read_args *ap)
        if (vp->v_type != VREG)
                return (EINVAL);
 
-#ifdef SMP
-       if(curthread->td_mpcount)
-               got_mplock = -1;
-       else
-               got_mplock = 0;
-#else
-               got_mplock = -1;
-#endif
-
        while (uio->uio_resid > 0 && uio->uio_offset < node->tn_size) {
                /*
                 * Use buffer cache I/O (via tmpfs_strategy)
                 */
                offset = (size_t)uio->uio_offset & BMASK;
                base_offset = (off_t)uio->uio_offset - offset;
-               bp = getcacheblk(vp, base_offset);
+               bp = getcacheblk(vp, base_offset, BSIZE);
                if (bp == NULL)
                {
-                       if (got_mplock == 0) {
-                               got_mplock = 1;
-                               get_mplock();
-                       }
-
+                       lwkt_gettoken(&vp->v_mount->mnt_token);
                        error = bread(vp, base_offset, BSIZE, &bp);
                        if (error) {
                                brelse(bp);
+                               lwkt_reltoken(&vp->v_mount->mnt_token);
                                kprintf("tmpfs_read bread error %d\n", error);
                                break;
                        }
-               }
-
-               if (got_mplock == 0) {
-                       got_mplock = 1;
-                       get_mplock();
+                       lwkt_reltoken(&vp->v_mount->mnt_token);
                }
 
                /*
@@ -495,9 +481,6 @@ tmpfs_read (struct vop_read_args *ap)
                }
        }
 
-       if (got_mplock > 0)
-               rel_mplock();
-
        TMPFS_NODE_LOCK(node);
        node->tn_status |= TMPFS_NODE_ACCESSED;
        TMPFS_NODE_UNLOCK(node);
@@ -520,7 +503,6 @@ tmpfs_write (struct vop_write_args *ap)
        size_t offset;
        size_t len;
        struct rlimit limit;
-       int got_mplock;
        int trivial = 0;
        int kflags = 0;
 
@@ -534,6 +516,8 @@ tmpfs_write (struct vop_write_args *ap)
        if (vp->v_type != VREG)
                return (EINVAL);
 
+       lwkt_gettoken(&vp->v_mount->mnt_token);
+
        oldsize = node->tn_size;
        if (ap->a_ioflag & IO_APPEND)
                uio->uio_offset = node->tn_size;
@@ -542,15 +526,20 @@ tmpfs_write (struct vop_write_args *ap)
         * Check for illegal write offsets.
         */
        if (uio->uio_offset + uio->uio_resid >
-         VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
+         VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize) {
+               lwkt_reltoken(&vp->v_mount->mnt_token);
                return (EFBIG);
+       }
 
        if (vp->v_type == VREG && td != NULL) {
                error = kern_getrlimit(RLIMIT_FSIZE, &limit);
-               if (error != 0)
+               if (error != 0) {
+                       lwkt_reltoken(&vp->v_mount->mnt_token);
                        return error;
+               }
                if (uio->uio_offset + uio->uio_resid > limit.rlim_cur) {
                        ksignal(td->td_proc, SIGXFSZ);
+                       lwkt_reltoken(&vp->v_mount->mnt_token);
                        return (EFBIG);
                }
        }
@@ -561,16 +550,8 @@ tmpfs_write (struct vop_write_args *ap)
         */
        extended = ((uio->uio_offset + uio->uio_resid) > node->tn_size);
 
-#ifdef SMP
-       if (curthread->td_mpcount) {
-               got_mplock = -1;
-       } else {
-               got_mplock = 1;
-               get_mplock();
-       }
-#else
-       got_mplock = -1;
-#endif
+       get_mplock();
+
        while (uio->uio_resid > 0) {
                /*
                 * Use buffer cache I/O (via tmpfs_strategy)
@@ -651,8 +632,7 @@ tmpfs_write (struct vop_write_args *ap)
                }
        }
 
-       if (got_mplock > 0)
-               rel_mplock();
+       rel_mplock();
 
        if (error) {
                if (extended) {
@@ -674,6 +654,9 @@ tmpfs_write (struct vop_write_args *ap)
 done:
 
        tmpfs_knote(vp, kflags);
+
+
+       lwkt_reltoken(&vp->v_mount->mnt_token);
        return(error);
 }
 
@@ -705,6 +688,7 @@ tmpfs_strategy(struct vop_strategy_args *ap)
                return(0);
        }
 
+       lwkt_gettoken(&vp->v_mount->mnt_token);
        node = VP_TO_TMPFS_NODE(vp);
 
        uobj = node->tn_reg.tn_aobj;
@@ -715,6 +699,7 @@ tmpfs_strategy(struct vop_strategy_args *ap)
         */
        swap_pager_strategy(uobj, bio);
 
+       lwkt_reltoken(&vp->v_mount->mnt_token);
        return 0;
 }