]> git.hungrycats.org Git - linux/commitdiff
[PATCH] namei.c: take vfsmount_lock
authorAndrew Morton <akpm@osdl.org>
Wed, 4 Feb 2004 02:47:27 +0000 (18:47 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 4 Feb 2004 02:47:27 +0000 (18:47 -0800)
From: Mike Waychison <Michael.Waychison@Sun.COM>

The attached patch ensures that we grab vfsmount_lock when grabbing a
reference to mnt_parent in follow_up and follow_dotdot.

We also don't need to access ->mnt_parent in follow_mount and
__follow_down to mntput because we already the parent pointer on the stack.

fs/namei.c

index fd7bf97afda5be52fd20d0fc4acbb358a6d6b18d..b3aa2a22c8f0b439bce2b509a862ae3817665c9e 100644 (file)
@@ -420,15 +420,15 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry)
 {
        struct vfsmount *parent;
        struct dentry *mountpoint;
-       spin_lock(&dcache_lock);
+       spin_lock(&vfsmount_lock);
        parent=(*mnt)->mnt_parent;
        if (parent == *mnt) {
-               spin_unlock(&dcache_lock);
+               spin_unlock(&vfsmount_lock);
                return 0;
        }
        mntget(parent);
        mountpoint=dget((*mnt)->mnt_mountpoint);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&vfsmount_lock);
        dput(*dentry);
        *dentry = mountpoint;
        mntput(*mnt);
@@ -446,9 +446,9 @@ static int follow_mount(struct vfsmount **mnt, struct dentry **dentry)
                struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
                if (!mounted)
                        break;
+               mntput(*mnt);
                *mnt = mounted;
                dput(*dentry);
-               mntput(mounted->mnt_parent);
                *dentry = dget(mounted->mnt_root);
                res = 1;
        }
@@ -464,9 +464,9 @@ static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
 
        mounted = lookup_mnt(*mnt, *dentry);
        if (mounted) {
+               mntput(*mnt);
                *mnt = mounted;
                dput(*dentry);
-               mntput(mounted->mnt_parent);
                *dentry = dget(mounted->mnt_root);
                return 1;
        }
@@ -498,14 +498,16 @@ static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
                        dput(old);
                        break;
                }
+               spin_unlock(&dcache_lock);
+               spin_lock(&vfsmount_lock);
                parent = (*mnt)->mnt_parent;
                if (parent == *mnt) {
-                       spin_unlock(&dcache_lock);
+                       spin_unlock(&vfsmount_lock);
                        break;
                }
                mntget(parent);
                *dentry = dget((*mnt)->mnt_mountpoint);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&vfsmount_lock);
                dput(old);
                mntput(*mnt);
                *mnt = parent;