tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Move the vnode lock into file systems



The vnode lock operations currently work on a rw lock located inside the
vnode.  I propose to move this lock into the file system node.

This place is more logical as we lock a file system node and not a vnode.
This becomes clear if we think of a file system where one file system node
is attached to more than one vnode.  Ptyfs allowing multiple mounts is such
a candidate.

A diff implemeting this for ufs, lfs and ext2fs is attached.

Comments or objections anyone?

-- 
Juergen Hannken-Illjes - hannken%eis.cs.tu-bs.de@localhost - TU Braunschweig 
(Germany)

Index: sys/ufs/ufs/inode.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/inode.h,v
retrieving revision 1.56
diff -p -u -4 -r1.56 inode.h
--- sys/ufs/ufs/inode.h 22 Feb 2009 20:28:07 -0000      1.56
+++ sys/ufs/ufs/inode.h 25 Jun 2010 20:43:24 -0000
@@ -91,9 +91,9 @@ struct inode {
 #define        i_fs    inode_u.fs
 #define        i_lfs   inode_u.lfs
 #define        i_e2fs  inode_u.e2fs
 
-       void    *i_unused1;     /* Unused. */
+       krwlock_t       i_lock; /* Inode lock. */
        struct   dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
        u_quad_t i_modrev;      /* Revision level for NFS lease. */
        struct   lockf *i_lockf;/* Head of byte-level lock list. */
 
Index: sys/ufs/ufs/ufs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v
retrieving revision 1.62
diff -p -u -4 -r1.62 ufs_extern.h
--- sys/ufs/ufs/ufs_extern.h    13 Sep 2009 05:17:37 -0000      1.62
+++ sys/ufs/ufs/ufs_extern.h    25 Jun 2010 20:43:24 -0000
@@ -67,11 +67,11 @@ int ufs_create(void *);
 int    ufs_getattr(void *);
 int    ufs_inactive(void *);
 #define        ufs_fcntl       genfs_fcntl
 #define        ufs_ioctl       genfs_enoioctl
-#define        ufs_islocked    genfs_islocked
+int    ufs_islocked(void *);
 int    ufs_link(void *);
-#define        ufs_lock        genfs_lock
+int    ufs_lock(void *);
 int    ufs_lookup(void *);
 int    ufs_mkdir(void *);
 int    ufs_mknod(void *);
 #define        ufs_mmap        genfs_mmap
@@ -88,9 +88,9 @@ int   ufs_rmdir(void *);
 #define        ufs_poll        genfs_poll
 int    ufs_setattr(void *);
 int    ufs_strategy(void *);
 int    ufs_symlink(void *);
-#define        ufs_unlock      genfs_unlock
+int    ufs_unlock(void *);
 int    ufs_whiteout(void *);
 int    ufsspec_close(void *);
 int    ufsspec_read(void *);
 int    ufsspec_write(void *);
Index: sys/ufs/ufs/ufs_ihash.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_ihash.c,v
retrieving revision 1.28
diff -p -u -4 -r1.28 ufs_ihash.c
--- sys/ufs/ufs/ufs_ihash.c     5 Nov 2009 08:18:02 -0000       1.28
+++ sys/ufs/ufs/ufs_ihash.c     25 Jun 2010 20:43:24 -0000
@@ -170,9 +170,10 @@ ufs_ihashins(struct inode *ip)
 
        KASSERT(mutex_owned(&ufs_hashlock));
 
        /* lock the inode, then put it on the appropriate hash list */
-       vlockmgr(&ip->i_vnode->v_lock, LK_EXCLUSIVE);
+       rw_init(&ip->i_lock);
+       rw_enter(&ip->i_lock, RW_WRITER);
 
        mutex_enter(&ufs_ihash_lock);
        ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
        LIST_INSERT_HEAD(ipp, ip, i_hash);
@@ -187,5 +188,6 @@ ufs_ihashrem(struct inode *ip)
 {
        mutex_enter(&ufs_ihash_lock);
        LIST_REMOVE(ip, i_hash);
        mutex_exit(&ufs_ihash_lock);
+       rw_destroy(&ip->i_lock);
 }
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.183
diff -p -u -4 -r1.183 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c     24 Jun 2010 13:03:20 -0000      1.183
+++ sys/ufs/ufs/ufs_vnops.c     25 Jun 2010 20:43:25 -0000
@@ -2346,4 +2346,66 @@ ufs_gop_markupdate(struct vnode *vp, int
 
                ip->i_flag |= mask;
        }
 }
+
+/*
+ * Lock the node.
+ */
+int
+ufs_lock(void *v)
+{
+       struct vop_lock_args /* {
+               struct vnode *a_vp;
+               int a_flags;
+       } */ *ap = v;
+       struct inode *ip = VTOI(ap->a_vp);
+       int flags = ap->a_flags;
+       krw_t op;
+
+       KASSERT((flags & ~(LK_EXCLUSIVE | LK_SHARED | LK_NOWAIT)) == 0);
+
+       op = ((flags & LK_EXCLUSIVE) != 0 ? RW_WRITER : RW_READER);
+
+       if ((flags & LK_NOWAIT) != 0)
+               return (rw_tryenter(&ip->i_lock, op) ? 0 : EBUSY);
+
+       rw_enter(&ip->i_lock, op);
+
+       return 0;
+}
+
+/*
+ * Unlock the node.
+ */
+int
+ufs_unlock(void *v)
+{
+       struct vop_unlock_args /* {
+               struct vnode *a_vp;
+       } */ *ap = v;
+       struct inode *ip = VTOI(ap->a_vp);
+
+       rw_exit(&ip->i_lock);
+
+       return 0;
+}
+
+/*
+ * Return whether or not the node is locked.
+ */
+int
+ufs_islocked(void *v)
+{
+       struct vop_islocked_args /* {
+               struct vnode *a_vp;
+       } */ *ap = v;
+       struct inode *ip = VTOI(ap->a_vp);
+
+       if (rw_write_held(&ip->i_lock))
+               return LK_EXCLUSIVE;
+
+       if (rw_read_held(&ip->i_lock))
+               return LK_SHARED;
+
+       return 0;
+}
Index: sys/ufs/lfs/lfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_syscalls.c,v
retrieving revision 1.137
diff -p -u -4 -r1.137 lfs_syscalls.c
--- sys/ufs/lfs/lfs_syscalls.c  24 Jun 2010 13:03:19 -0000      1.137
+++ sys/ufs/lfs/lfs_syscalls.c  25 Jun 2010 20:43:24 -0000
@@ -1136,12 +1136,12 @@ lfs_fastvget(struct mount *mp, ino_t ino
                error = copyin(dinp, ip->i_din.ffs1_din, sizeof (struct 
ufs1_dinode));
                if (error) {
                        DLOG((DLOG_CLEAN, "lfs_fastvget: dinode copyin failed"
                              " for ino %d\n", ino));
+                       /* Unlock and discard unneeded inode. */
+                       rw_exit(&ip->i_lock);
                        ufs_ihashrem(ip);
 
-                       /* Unlock and discard unneeded inode. */
-                       vlockmgr(&vp->v_lock, LK_RELEASE);
                        lfs_vunref(vp);
                        *vpp = NULL;
                        return (error);
                }
@@ -1158,13 +1158,13 @@ lfs_fastvget(struct mount *mp, ino_t ino
                        /*
                         * The inode does not contain anything useful, so it
                         * would be misleading to leave it on its hash chain.
                         * Iput() will return it to the free list.
+                        * Unlock and discard unneeded inode.
                         */
+                       rw_exit(&ip->i_lock);
                        ufs_ihashrem(ip);
 
-                       /* Unlock and discard unneeded inode. */
-                       vlockmgr(&vp->v_lock, LK_RELEASE);
                        lfs_vunref(vp);
                        brelse(bp, 0);
                        *vpp = NULL;
                        return (error);


Home | Main Index | Thread Index | Old Index