fs: dcache remove dcache_lock
authorNick Piggin <npiggin@kernel.dk>
Fri, 7 Jan 2011 06:49:38 +0000 (17:49 +1100)
committerNick Piggin <npiggin@kernel.dk>
Fri, 7 Jan 2011 06:50:23 +0000 (17:50 +1100)
dcache_lock no longer protects anything. remove it.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>
40 files changed:
Documentation/filesystems/Locking
Documentation/filesystems/dentry-locking.txt
Documentation/filesystems/porting
arch/powerpc/platforms/cell/spufs/inode.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/staging/pohmelfs/path_entry.c
drivers/staging/smbfs/cache.c
drivers/usb/core/inode.c
fs/9p/vfs_inode.c
fs/affs/amigaffs.c
fs/autofs4/autofs_i.h
fs/autofs4/expire.c
fs/autofs4/root.c
fs/autofs4/waitq.c
fs/ceph/dir.c
fs/ceph/inode.c
fs/cifs/inode.c
fs/coda/cache.c
fs/configfs/configfs_internal.h
fs/configfs/inode.c
fs/dcache.c
fs/exportfs/expfs.c
fs/libfs.c
fs/namei.c
fs/ncpfs/dir.c
fs/ncpfs/ncplib_kernel.h
fs/nfs/dir.c
fs/nfs/getroot.c
fs/nfs/namespace.c
fs/notify/fsnotify.c
fs/ocfs2/dcache.c
include/linux/dcache.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/fsnotify_backend.h
include/linux/namei.h
kernel/cgroup.c
mm/filemap.c
security/selinux/selinuxfs.c

index a15ee207b449242e84b38a2ff4d087636072504f..bdad6414dfa061f349ec4b8aba4d8a1f16428be9 100644 (file)
@@ -21,14 +21,14 @@ prototypes:
        char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
 
 locking rules:
-               dcache_lock     rename_lock     ->d_lock        may block
-d_revalidate:  no              no              no              yes
-d_hash         no              no              no              no
-d_compare:     no              yes             no              no 
-d_delete:      yes             no              yes             no
-d_release:     no              no              no              yes
-d_iput:                no              no              no              yes
-d_dname:       no              no              no              no
+               rename_lock     ->d_lock        may block
+d_revalidate:  no              no              yes
+d_hash         no              no              no
+d_compare:     yes             no              no
+d_delete:      no              yes             no
+d_release:     no              no              yes
+d_iput:                no              no              yes
+d_dname:       no              no              no
 
 --------------------------- inode_operations --------------------------- 
 prototypes:
index 79334ed5daa7fee4802c5f0a30bb58dde88dbbdc..30b6a40f5650f92c7a2d15dd670150e249cc1a52 100644 (file)
@@ -31,6 +31,7 @@ significant change is the way d_lookup traverses the hash chain, it
 doesn't acquire the dcache_lock for this and rely on RCU to ensure
 that the dentry has not been *freed*.
 
+dcache_lock no longer exists, dentry locking is explained in fs/dcache.c
 
 Dcache locking details
 ======================
@@ -50,14 +51,12 @@ Safe lock-free look-up of dcache hash table
 
 Dcache is a complex data structure with the hash table entries also
 linked together in other lists. In 2.4 kernel, dcache_lock protected
-all the lists. We applied RCU only on hash chain walking. The rest of
-the lists are still protected by dcache_lock.  Some of the important
-changes are :
+all the lists. RCU dentry hash walking works like this:
 
 1. The deletion from hash chain is done using hlist_del_rcu() macro
    which doesn't initialize next pointer of the deleted dentry and
    this allows us to walk safely lock-free while a deletion is
-   happening.
+   happening. This is a standard hlist_rcu iteration.
 
 2. Insertion of a dentry into the hash table is done using
    hlist_add_head_rcu() which take care of ordering the writes - the
@@ -66,19 +65,18 @@ changes are :
    which has since been replaced by hlist_for_each_entry_rcu(), while
    walking the hash chain. The only requirement is that all
    initialization to the dentry must be done before
-   hlist_add_head_rcu() since we don't have dcache_lock protection
-   while traversing the hash chain. This isn't different from the
-   existing code.
-
-3. The dentry looked up without holding dcache_lock by cannot be
-   returned for walking if it is unhashed. It then may have a NULL
-   d_inode or other bogosity since RCU doesn't protect the other
-   fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
-   indicate unhashed dentries and use this in conjunction with a
-   per-dentry lock (d_lock). Once looked up without the dcache_lock,
-   we acquire the per-dentry lock (d_lock) and check if the dentry is
-   unhashed. If so, the look-up is failed. If not, the reference count
-   of the dentry is increased and the dentry is returned.
+   hlist_add_head_rcu() since we don't have lock protection
+   while traversing the hash chain.
+
+3. The dentry looked up without holding locks cannot be returned for
+   walking if it is unhashed. It then may have a NULL d_inode or other
+   bogosity since RCU doesn't protect the other fields in the dentry. We
+   therefore use a flag DCACHE_UNHASHED to indicate unhashed dentries
+   and use this in conjunction with a per-dentry lock (d_lock). Once
+   looked up without locks, we acquire the per-dentry lock (d_lock) and
+   check if the dentry is unhashed. If so, the look-up is failed. If not,
+   the reference count of the dentry is increased and the dentry is
+   returned.
 
 4. Once a dentry is looked up, it must be ensured during the path walk
    for that component it doesn't go away. In pre-2.5.10 code, this was
@@ -86,10 +84,10 @@ changes are :
    In some sense, dcache_rcu path walking looks like the pre-2.5.10
    version.
 
-5. All dentry hash chain updates must take the dcache_lock as well as
-   the per-dentry lock in that order. dput() does this to ensure that
-   a dentry that has just been looked up in another CPU doesn't get
-   deleted before dget() can be done on it.
+5. All dentry hash chain updates must take the per-dentry lock (see
+   fs/dcache.c). This excludes dput() to ensure that a dentry that has
+   been looked up concurrently does not get deleted before dget() can
+   take a ref.
 
 6. There are several ways to do reference counting of RCU protected
    objects. One such example is in ipv4 route cache where deferred
index 9fd31940a8efe4ae11ef6ee75f15d80dc6ae523e..1eb76959d09680c01b75734c5a008698b6306e35 100644 (file)
@@ -216,7 +216,6 @@ had ->revalidate()) add calls in ->follow_link()/->readlink().
 ->d_parent changes are not protected by BKL anymore.  Read access is safe
 if at least one of the following is true:
        * filesystem has no cross-directory rename()
-       * dcache_lock is held
        * we know that parent had been locked (e.g. we are looking at
 ->d_parent of ->lookup() argument).
        * we are called from ->rename().
@@ -340,3 +339,10 @@ look at examples of other filesystems) for guidance.
        .d_hash() calling convention and locking rules are significantly
 changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
 look at examples of other filesystems) for guidance.
+
+---
+[mandatory]
+       dcache_lock is gone, replaced by fine grained locks. See fs/dcache.c
+for details of what locks to replace dcache_lock with in order to protect
+particular things. Most of the time, a filesystem only needs ->d_lock, which
+protects *all* the dcache state of a given dentry.
index 5aef1a7f5e4b4e5a8722afc614e6d612d9397c44..2662b50ea8d450fa7e4c74649c50e2b231989f17 100644 (file)
@@ -159,21 +159,18 @@ static void spufs_prune_dir(struct dentry *dir)
 
        mutex_lock(&dir->d_inode->i_mutex);
        list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
-               spin_lock(&dcache_lock);
                spin_lock(&dentry->d_lock);
                if (!(d_unhashed(dentry)) && dentry->d_inode) {
                        dget_locked_dlock(dentry);
                        __d_drop(dentry);
                        spin_unlock(&dentry->d_lock);
                        simple_unlink(dir->d_inode, dentry);
-                       /* XXX: what is dcache_lock protecting here? Other
+                       /* XXX: what was dcache_lock protecting here? Other
                         * filesystems (IB, configfs) release dcache_lock
                         * before unlink */
-                       spin_unlock(&dcache_lock);
                        dput(dentry);
                } else {
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                }
        }
        shrink_dcache_parent(dir);
index 18aee04a8411c337ca896ccb868af90e6a91c8b9..925e88227deda0aaeb055cbea8b29e534532d2df 100644 (file)
@@ -277,18 +277,14 @@ static int remove_file(struct dentry *parent, char *name)
                goto bail;
        }
 
-       spin_lock(&dcache_lock);
        spin_lock(&tmp->d_lock);
        if (!(d_unhashed(tmp) && tmp->d_inode)) {
                dget_locked_dlock(tmp);
                __d_drop(tmp);
                spin_unlock(&tmp->d_lock);
-               spin_unlock(&dcache_lock);
                simple_unlink(parent->d_inode, tmp);
-       } else {
+       } else
                spin_unlock(&tmp->d_lock);
-               spin_unlock(&dcache_lock);
-       }
 
        ret = 0;
 bail:
index fe4b242f009458564aab1900e6afd16781a6d226..49af4a6538ba7797e4a4cda7112062f1fa6c27f9 100644 (file)
@@ -453,17 +453,14 @@ static int remove_file(struct dentry *parent, char *name)
                goto bail;
        }
 
-       spin_lock(&dcache_lock);
        spin_lock(&tmp->d_lock);
        if (!(d_unhashed(tmp) && tmp->d_inode)) {
                dget_locked_dlock(tmp);
                __d_drop(tmp);
                spin_unlock(&tmp->d_lock);
-               spin_unlock(&dcache_lock);
                simple_unlink(parent->d_inode, tmp);
        } else {
                spin_unlock(&tmp->d_lock);
-               spin_unlock(&dcache_lock);
        }
 
        ret = 0;
index bbe42f42ca8f151385cc96457dc914129325cbe7..400a9fc386ad5a399770dd7bc92ce757de18c288 100644 (file)
@@ -101,7 +101,6 @@ rename_retry:
        d = first;
        seq = read_seqbegin(&rename_lock);
        rcu_read_lock();
-       spin_lock(&dcache_lock);
 
        if (!IS_ROOT(d) && d_unhashed(d))
                len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
@@ -110,7 +109,6 @@ rename_retry:
                len += d->d_name.len + 1; /* Plus slash */
                d = d->d_parent;
        }
-       spin_unlock(&dcache_lock);
        rcu_read_unlock();
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
index 920434b6c071fd0d573e9fe0a196c07a94daea94..75dfd403fb90390f2900c01c31822aefbba95f95 100644 (file)
@@ -62,7 +62,6 @@ smb_invalidate_dircache_entries(struct dentry *parent)
        struct list_head *next;
        struct dentry *dentry;
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
@@ -72,7 +71,6 @@ smb_invalidate_dircache_entries(struct dentry *parent)
                next = next->next;
        }
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /*
@@ -98,7 +96,6 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
        }
 
        /* If a pointer is invalid, we search the dentry. */
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
@@ -115,7 +112,6 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
        dent = NULL;
 out_unlock:
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
        return dent;
 }
 
index 89a0e8366585c7dd01c9ba6bc23ba942bd2bd460..1b125c224dcf8d4d73f5a094edb6f4417c8e88e4 100644 (file)
@@ -343,7 +343,6 @@ static int usbfs_empty (struct dentry *dentry)
 {
        struct list_head *list;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        list_for_each(list, &dentry->d_subdirs) {
                struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
@@ -352,13 +351,11 @@ static int usbfs_empty (struct dentry *dentry)
                if (usbfs_positive(de)) {
                        spin_unlock(&de->d_lock);
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                        return 0;
                }
                spin_unlock(&de->d_lock);
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
        return 1;
 }
 
index 47dfd5d29a6b9c42eb350b890b31677c52cd15d7..1073bca8488cca98c0a3a898638308218c256b86 100644 (file)
@@ -270,13 +270,11 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
 {
        struct dentry *dentry;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        /* Directory should have only one entry. */
        BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
        dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        return dentry;
 }
 
index 2321cc92d44faa5c5f5243e2620c2e7e3c784ac7..600101a21ba2d5b3ddd710203c5949e6c9c20aeb 100644 (file)
@@ -128,7 +128,6 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
        void *data = dentry->d_fsdata;
        struct list_head *head, *next;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        head = &inode->i_dentry;
        next = head->next;
@@ -141,7 +140,6 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
                next = next->next;
        }
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 }
 
 
index 9d2ae9b30d9f0781cc646e884db6953416843a8b..0fffe1c24cecf354b620cafcbffc002a6318093c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/auto_fs4.h>
 #include <linux/auto_dev-ioctl.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/list.h>
 
 /* This is the range of ioctl() numbers we claim as ours */
@@ -60,6 +61,8 @@ do {                                                  \
                current->pid, __func__, ##args);        \
 } while (0)
 
+extern spinlock_t autofs4_lock;
+
 /* Unified info structure.  This is pointed to by both the dentry and
    inode structures.  Each file in the filesystem has an instance of this
    structure.  It holds a reference to the dentry, so dentries are never
index 968c1434af62ed815c69809411fc750498c2dc42..2f7951d67d163b04dbde25a4274bddba48d30cac 100644 (file)
@@ -102,7 +102,7 @@ static struct dentry *get_next_positive_dentry(struct dentry *prev,
        if (prev == NULL)
                return dget(prev);
 
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
 relock:
        p = prev;
        spin_lock(&p->d_lock);
@@ -114,7 +114,7 @@ again:
 
                        if (p == root) {
                                spin_unlock(&p->d_lock);
-                               spin_unlock(&dcache_lock);
+                               spin_unlock(&autofs4_lock);
                                dput(prev);
                                return NULL;
                        }
@@ -144,7 +144,7 @@ again:
        dget_dlock(ret);
        spin_unlock(&ret->d_lock);
        spin_unlock(&p->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        dput(prev);
 
@@ -408,13 +408,13 @@ found:
        ino->flags |= AUTOFS_INF_EXPIRING;
        init_completion(&ino->expire_complete);
        spin_unlock(&sbi->fs_lock);
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&expired->d_parent->d_lock);
        spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
        list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
        spin_unlock(&expired->d_lock);
        spin_unlock(&expired->d_parent->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
        return expired;
 }
 
index 7a9ed6b8829149b179b54c4ab32741418e115b6d..10ca68a96dc7ad90d8da92060bdf006d3a663051 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "autofs_i.h"
 
+DEFINE_SPINLOCK(autofs4_lock);
+
 static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
 static int autofs4_dir_unlink(struct inode *,struct dentry *);
 static int autofs4_dir_rmdir(struct inode *,struct dentry *);
@@ -142,15 +144,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
         * autofs file system so just let the libfs routines handle
         * it.
         */
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&dentry->d_lock);
        if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                return -ENOENT;
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
 out:
        return dcache_dir_open(inode, file);
@@ -255,11 +257,11 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
        /* We trigger a mount for almost all flags */
        lookup_type = autofs4_need_mount(nd->flags);
        spin_lock(&sbi->fs_lock);
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&dentry->d_lock);
        if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                spin_unlock(&sbi->fs_lock);
                goto follow;
        }
@@ -272,7 +274,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
        if (ino->flags & AUTOFS_INF_PENDING ||
            (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                spin_unlock(&sbi->fs_lock);
 
                status = try_to_fill_dentry(dentry, nd->flags);
@@ -282,7 +284,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
                goto follow;
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
        spin_unlock(&sbi->fs_lock);
 follow:
        /*
@@ -353,14 +355,14 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
                return 0;
 
        /* Check for a non-mountpoint directory with no contents */
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&dentry->d_lock);
        if (S_ISDIR(dentry->d_inode->i_mode) &&
            !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
                DPRINTK("dentry=%p %.*s, emptydir",
                         dentry, dentry->d_name.len, dentry->d_name.name);
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
 
                /* The daemon never causes a mount to trigger */
                if (oz_mode)
@@ -377,7 +379,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
                return status;
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        return 1;
 }
@@ -432,7 +434,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
        const unsigned char *str = name->name;
        struct list_head *p, *head;
 
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&sbi->lookup_lock);
        head = &sbi->active_list;
        list_for_each(p, head) {
@@ -465,14 +467,14 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
                        dget_dlock(active);
                        spin_unlock(&active->d_lock);
                        spin_unlock(&sbi->lookup_lock);
-                       spin_unlock(&dcache_lock);
+                       spin_unlock(&autofs4_lock);
                        return active;
                }
 next:
                spin_unlock(&active->d_lock);
        }
        spin_unlock(&sbi->lookup_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        return NULL;
 }
@@ -487,7 +489,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
        const unsigned char *str = name->name;
        struct list_head *p, *head;
 
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&sbi->lookup_lock);
        head = &sbi->expiring_list;
        list_for_each(p, head) {
@@ -520,14 +522,14 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
                        dget_dlock(expiring);
                        spin_unlock(&expiring->d_lock);
                        spin_unlock(&sbi->lookup_lock);
-                       spin_unlock(&dcache_lock);
+                       spin_unlock(&autofs4_lock);
                        return expiring;
                }
 next:
                spin_unlock(&expiring->d_lock);
        }
        spin_unlock(&sbi->lookup_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        return NULL;
 }
@@ -763,12 +765,12 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
 
        dir->i_mtime = CURRENT_TIME;
 
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        autofs4_add_expiring(dentry);
        spin_lock(&dentry->d_lock);
        __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        return 0;
 }
@@ -785,20 +787,20 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (!autofs4_oz_mode(sbi))
                return -EACCES;
 
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        spin_lock(&sbi->lookup_lock);
        spin_lock(&dentry->d_lock);
        if (!list_empty(&dentry->d_subdirs)) {
                spin_unlock(&dentry->d_lock);
                spin_unlock(&sbi->lookup_lock);
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                return -ENOTEMPTY;
        }
        __autofs4_add_expiring(dentry);
        spin_unlock(&sbi->lookup_lock);
        __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
 
        if (atomic_dec_and_test(&ino->count)) {
                p_ino = autofs4_dentry_ino(dentry->d_parent);
index 4be8f778a4189872a6956be82d57c19ff2ba9e83..c5f8459c905e6453206c585df1eedb65a89dfef1 100644 (file)
@@ -194,14 +194,15 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
 rename_retry:
        buf = *name;
        len = 0;
+
        seq = read_seqbegin(&rename_lock);
        rcu_read_lock();
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
                len += tmp->d_name.len + 1;
 
        if (!len || --len > NAME_MAX) {
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                rcu_read_unlock();
                if (read_seqretry(&rename_lock, seq))
                        goto rename_retry;
@@ -217,7 +218,7 @@ rename_retry:
                p -= tmp->d_name.len;
                strncpy(p, tmp->d_name.name, tmp->d_name.len);
        }
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
        rcu_read_unlock();
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
index 2c924e8d85fec0a4c1a3926e60a6bf632d250a33..58abc3da6111c517fdcb725ce8f2b4fce4a32db3 100644 (file)
@@ -112,7 +112,6 @@ static int __dcache_readdir(struct file *filp,
        dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,
             last);
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
 
        /* start at beginning? */
@@ -156,7 +155,6 @@ more:
        dget_dlock(dentry);
        spin_unlock(&dentry->d_lock);
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
 
        dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
             dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
@@ -182,21 +180,19 @@ more:
 
        filp->f_pos++;
 
-       /* make sure a dentry wasn't dropped while we didn't have dcache_lock */
+       /* make sure a dentry wasn't dropped while we didn't have parent lock */
        if (!ceph_i_test(dir, CEPH_I_COMPLETE)) {
                dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
                err = -EAGAIN;
                goto out;
        }
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        p = p->prev;    /* advance to next dentry */
        goto more;
 
 out_unlock:
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
 out:
        if (last)
                dput(last);
index 2c694447336686daef9ca33a4173891a615fd84b..2a48cafc174b912f2f032b013b50af1d55d10a3c 100644 (file)
@@ -841,7 +841,6 @@ static void ceph_set_dentry_offset(struct dentry *dn)
        di->offset = ceph_inode(inode)->i_max_offset++;
        spin_unlock(&inode->i_lock);
 
-       spin_lock(&dcache_lock);
        spin_lock(&dir->d_lock);
        spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
        list_move(&dn->d_u.d_child, &dir->d_subdirs);
@@ -849,7 +848,6 @@ static void ceph_set_dentry_offset(struct dentry *dn)
             dn->d_u.d_child.prev, dn->d_u.d_child.next);
        spin_unlock(&dn->d_lock);
        spin_unlock(&dir->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /*
@@ -1233,13 +1231,11 @@ retry_lookup:
                        goto retry_lookup;
                } else {
                        /* reorder parent's d_subdirs */
-                       spin_lock(&dcache_lock);
                        spin_lock(&parent->d_lock);
                        spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
                        list_move(&dn->d_u.d_child, &parent->d_subdirs);
                        spin_unlock(&dn->d_lock);
                        spin_unlock(&parent->d_lock);
-                       spin_unlock(&dcache_lock);
                }
 
                di = dn->d_fsdata;
index 003698365ecea56833a86319aaa5dca94351d87b..99b9a2cc14b7c93f6e60658c7fceabb1788eb961 100644 (file)
@@ -809,17 +809,14 @@ inode_has_hashed_dentries(struct inode *inode)
 {
        struct dentry *dentry;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
                if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
                        spin_unlock(&dcache_inode_lock);
-                       spin_unlock(&dcache_lock);
                        return true;
                }
        }
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        return false;
 }
 
index 859393fca2b7a28681de298652d6bac5f5a994c1..5525e1c660fd55057825fedd7ebe175dae6fe55a 100644 (file)
@@ -93,7 +93,6 @@ static void coda_flag_children(struct dentry *parent, int flag)
        struct list_head *child;
        struct dentry *de;
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        list_for_each(child, &parent->d_subdirs)
        {
@@ -104,7 +103,6 @@ static void coda_flag_children(struct dentry *parent, int flag)
                coda_flag_inode(de->d_inode, flag);
        }
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
        return; 
 }
 
index e58b4c30e216fa2df3c6028c4cb788e09551ac5b..026cf68553a41bc4539e7846c5d2098b15479ae9 100644 (file)
@@ -120,7 +120,6 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
 {
        struct config_item * item = NULL;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        if (!d_unhashed(dentry)) {
                struct configfs_dirent * sd = dentry->d_fsdata;
@@ -131,7 +130,6 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
                        item = config_item_get(sd->s_element);
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 
        return item;
 }
index 79b37765d8ff1e0dc01de172a8e45ef7954267f0..fb3a55fff82a7a00125061557ca71f0174d1e887 100644 (file)
@@ -250,18 +250,14 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
        struct dentry * dentry = sd->s_dentry;
 
        if (dentry) {
-               spin_lock(&dcache_lock);
                spin_lock(&dentry->d_lock);
                if (!(d_unhashed(dentry) && dentry->d_inode)) {
                        dget_locked_dlock(dentry);
                        __d_drop(dentry);
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                        simple_unlink(parent->d_inode, dentry);
-               } else {
+               } else
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
-               }
        }
 }
 
index a9bc4ecc21e161b8ab2b7dad70b515282ab52a3b..0dbae053b6649a1401d0606a665d9505384ea6a6 100644 (file)
  *   - d_alias, d_inode
  *
  * Ordering:
- * dcache_lock
- *   dcache_inode_lock
- *     dentry->d_lock
- *       dcache_lru_lock
- *       dcache_hash_lock
+ * dcache_inode_lock
+ *   dentry->d_lock
+ *     dcache_lru_lock
+ *     dcache_hash_lock
  *
  * If there is an ancestor relationship:
  * dentry->d_parent->...->d_parent->d_lock
@@ -77,12 +76,10 @@ EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock);
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock);
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);
-__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
 __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
 
 EXPORT_SYMBOL(rename_lock);
 EXPORT_SYMBOL(dcache_inode_lock);
-EXPORT_SYMBOL(dcache_lock);
 
 static struct kmem_cache *dentry_cache __read_mostly;
 
@@ -139,7 +136,7 @@ static void __d_free(struct rcu_head *head)
 }
 
 /*
- * no dcache_lock, please.
+ * no locks, please.
  */
 static void d_free(struct dentry *dentry)
 {
@@ -162,7 +159,6 @@ static void d_free(struct dentry *dentry)
 static void dentry_iput(struct dentry * dentry)
        __releases(dentry->d_lock)
        __releases(dcache_inode_lock)
-       __releases(dcache_lock)
 {
        struct inode *inode = dentry->d_inode;
        if (inode) {
@@ -170,7 +166,6 @@ static void dentry_iput(struct dentry * dentry)
                list_del_init(&dentry->d_alias);
                spin_unlock(&dentry->d_lock);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
                if (!inode->i_nlink)
                        fsnotify_inoderemove(inode);
                if (dentry->d_op && dentry->d_op->d_iput)
@@ -180,7 +175,6 @@ static void dentry_iput(struct dentry * dentry)
        } else {
                spin_unlock(&dentry->d_lock);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
        }
 }
 
@@ -235,14 +229,13 @@ static void dentry_lru_move_tail(struct dentry *dentry)
  *
  * If this is the root of the dentry tree, return NULL.
  *
- * dcache_lock and d_lock and d_parent->d_lock must be held by caller, and
- * are dropped by d_kill.
+ * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by
+ * d_kill.
  */
 static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
        __releases(dentry->d_lock)
        __releases(parent->d_lock)
        __releases(dcache_inode_lock)
-       __releases(dcache_lock)
 {
        dentry->d_parent = NULL;
        list_del(&dentry->d_u.d_child);
@@ -285,11 +278,9 @@ EXPORT_SYMBOL(__d_drop);
 
 void d_drop(struct dentry *dentry)
 {
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 }
 EXPORT_SYMBOL(d_drop);
 
@@ -337,21 +328,10 @@ repeat:
        else
                parent = dentry->d_parent;
        if (dentry->d_count == 1) {
-               if (!spin_trylock(&dcache_lock)) {
-                       /*
-                        * Something of a livelock possibility we could avoid
-                        * by taking dcache_lock and trying again, but we
-                        * want to reduce dcache_lock anyway so this will
-                        * get improved.
-                        */
-drop1:
-                       spin_unlock(&dentry->d_lock);
-                       goto repeat;
-               }
                if (!spin_trylock(&dcache_inode_lock)) {
 drop2:
-                       spin_unlock(&dcache_lock);
-                       goto drop1;
+                       spin_unlock(&dentry->d_lock);
+                       goto repeat;
                }
                if (parent && !spin_trylock(&parent->d_lock)) {
                        spin_unlock(&dcache_inode_lock);
@@ -363,7 +343,6 @@ drop2:
                spin_unlock(&dentry->d_lock);
                if (parent)
                        spin_unlock(&parent->d_lock);
-               spin_unlock(&dcache_lock);
                return;
        }
 
@@ -387,7 +366,6 @@ drop2:
        if (parent)
                spin_unlock(&parent->d_lock);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        return;
 
 unhash_it:
@@ -418,11 +396,9 @@ int d_invalidate(struct dentry * dentry)
        /*
         * If it's already been dropped, return OK.
         */
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        if (d_unhashed(dentry)) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
                return 0;
        }
        /*
@@ -431,9 +407,7 @@ int d_invalidate(struct dentry * dentry)
         */
        if (!list_empty(&dentry->d_subdirs)) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
                shrink_dcache_parent(dentry);
-               spin_lock(&dcache_lock);
                spin_lock(&dentry->d_lock);
        }
 
@@ -450,19 +424,17 @@ int d_invalidate(struct dentry * dentry)
        if (dentry->d_count > 1) {
                if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                        return -EBUSY;
                }
        }
 
        __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
        return 0;
 }
 EXPORT_SYMBOL(d_invalidate);
 
-/* This must be called with dcache_lock and d_lock held */
+/* This must be called with d_lock held */
 static inline struct dentry * __dget_locked_dlock(struct dentry *dentry)
 {
        dentry->d_count++;
@@ -470,7 +442,7 @@ static inline struct dentry * __dget_locked_dlock(struct dentry *dentry)
        return dentry;
 }
 
-/* This should be called _only_ with dcache_lock held */
+/* This must be called with d_lock held */
 static inline struct dentry * __dget_locked(struct dentry *dentry)
 {
        spin_lock(&dentry->d_lock);
@@ -575,11 +547,9 @@ struct dentry *d_find_alias(struct inode *inode)
        struct dentry *de = NULL;
 
        if (!list_empty(&inode->i_dentry)) {
-               spin_lock(&dcache_lock);
                spin_lock(&dcache_inode_lock);
                de = __d_find_alias(inode, 0);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
        }
        return de;
 }
@@ -593,7 +563,6 @@ void d_prune_aliases(struct inode *inode)
 {
        struct dentry *dentry;
 restart:
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
                spin_lock(&dentry->d_lock);
@@ -602,14 +571,12 @@ restart:
                        __d_drop(dentry);
                        spin_unlock(&dentry->d_lock);
                        spin_unlock(&dcache_inode_lock);
-                       spin_unlock(&dcache_lock);
                        dput(dentry);
                        goto restart;
                }
                spin_unlock(&dentry->d_lock);
        }
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 }
 EXPORT_SYMBOL(d_prune_aliases);
 
@@ -625,17 +592,14 @@ static void prune_one_dentry(struct dentry *dentry, struct dentry *parent)
        __releases(dentry->d_lock)
        __releases(parent->d_lock)
        __releases(dcache_inode_lock)
-       __releases(dcache_lock)
 {
        __d_drop(dentry);
        dentry = d_kill(dentry, parent);
 
        /*
-        * Prune ancestors.  Locking is simpler than in dput(),
-        * because dcache_lock needs to be taken anyway.
+        * Prune ancestors.
         */
        while (dentry) {
-               spin_lock(&dcache_lock);
                spin_lock(&dcache_inode_lock);
 again:
                spin_lock(&dentry->d_lock);
@@ -653,7 +617,6 @@ again:
                                spin_unlock(&parent->d_lock);
                        spin_unlock(&dentry->d_lock);
                        spin_unlock(&dcache_inode_lock);
-                       spin_unlock(&dcache_lock);
                        return;
                }
 
@@ -702,8 +665,7 @@ relock:
                spin_unlock(&dcache_lru_lock);
 
                prune_one_dentry(dentry, parent);
-               /* dcache_lock, dcache_inode_lock and dentry->d_lock dropped */
-               spin_lock(&dcache_lock);
+               /* dcache_inode_lock and dentry->d_lock dropped */
                spin_lock(&dcache_inode_lock);
                spin_lock(&dcache_lru_lock);
        }
@@ -725,7 +687,6 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags)
        LIST_HEAD(tmp);
        int cnt = *count;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
 relock:
        spin_lock(&dcache_lru_lock);
@@ -766,7 +727,6 @@ relock:
                list_splice(&referenced, &sb->s_dentry_lru);
        spin_unlock(&dcache_lru_lock);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /**
@@ -788,7 +748,6 @@ static void prune_dcache(int count)
 
        if (unused == 0 || count == 0)
                return;
-       spin_lock(&dcache_lock);
        if (count >= unused)
                prune_ratio = 1;
        else
@@ -825,11 +784,9 @@ static void prune_dcache(int count)
                if (down_read_trylock(&sb->s_umount)) {
                        if ((sb->s_root != NULL) &&
                            (!list_empty(&sb->s_dentry_lru))) {
-                               spin_unlock(&dcache_lock);
                                __shrink_dcache_sb(sb, &w_count,
                                                DCACHE_REFERENCED);
                                pruned -= w_count;
-                               spin_lock(&dcache_lock);
                        }
                        up_read(&sb->s_umount);
                }
@@ -845,7 +802,6 @@ static void prune_dcache(int count)
        if (p)
                __put_super(p);
        spin_unlock(&sb_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /**
@@ -859,7 +815,6 @@ void shrink_dcache_sb(struct super_block *sb)
 {
        LIST_HEAD(tmp);
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        spin_lock(&dcache_lru_lock);
        while (!list_empty(&sb->s_dentry_lru)) {
@@ -868,7 +823,6 @@ void shrink_dcache_sb(struct super_block *sb)
        }
        spin_unlock(&dcache_lru_lock);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 }
 EXPORT_SYMBOL(shrink_dcache_sb);
 
@@ -885,12 +839,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
        BUG_ON(!IS_ROOT(dentry));
 
        /* detach this root from the system */
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        dentry_lru_del(dentry);
        __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 
        for (;;) {
                /* descend to the first leaf in the current subtree */
@@ -899,7 +851,6 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 
                        /* this is a branch with children - detach all of them
                         * from the system in one go */
-                       spin_lock(&dcache_lock);
                        spin_lock(&dentry->d_lock);
                        list_for_each_entry(loop, &dentry->d_subdirs,
                                            d_u.d_child) {
@@ -910,7 +861,6 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                                spin_unlock(&loop->d_lock);
                        }
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
 
                        /* move to the first child */
                        dentry = list_entry(dentry->d_subdirs.next,
@@ -977,8 +927,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 
 /*
  * destroy the dentries attached to a superblock on unmounting
- * - we don't need to use dentry->d_lock, and only need dcache_lock when
- *   removing the dentry from the system lists and hashes because:
+ * - we don't need to use dentry->d_lock because:
  *   - the superblock is detached from all mountings and open files, so the
  *     dentry trees will not be rearranged by the VFS
  *   - s_umount is write-locked, so the memory pressure shrinker will ignore
@@ -1029,7 +978,6 @@ rename_retry:
        this_parent = parent;
        seq = read_seqbegin(&rename_lock);
 
-       spin_lock(&dcache_lock);
        if (d_mountpoint(parent))
                goto positive;
        spin_lock(&this_parent->d_lock);
@@ -1075,7 +1023,6 @@ resume:
                if (this_parent != child->d_parent ||
                                read_seqretry(&rename_lock, seq)) {
                        spin_unlock(&this_parent->d_lock);
-                       spin_unlock(&dcache_lock);
                        rcu_read_unlock();
                        goto rename_retry;
                }
@@ -1084,12 +1031,10 @@ resume:
                goto resume;
        }
        spin_unlock(&this_parent->d_lock);
-       spin_unlock(&dcache_lock);
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
        return 0; /* No mount points found in tree */
 positive:
-       spin_unlock(&dcache_lock);
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
        return 1;
@@ -1121,7 +1066,6 @@ rename_retry:
        this_parent = parent;
        seq = read_seqbegin(&rename_lock);
 
-       spin_lock(&dcache_lock);
        spin_lock(&this_parent->d_lock);
 repeat:
        next = this_parent->d_subdirs.next;
@@ -1185,7 +1129,6 @@ resume:
                if (this_parent != child->d_parent ||
                                read_seqretry(&rename_lock, seq)) {
                        spin_unlock(&this_parent->d_lock);
-                       spin_unlock(&dcache_lock);
                        rcu_read_unlock();
                        goto rename_retry;
                }
@@ -1195,7 +1138,6 @@ resume:
        }
 out:
        spin_unlock(&this_parent->d_lock);
-       spin_unlock(&dcache_lock);
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
        return found;
@@ -1297,7 +1239,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
        INIT_LIST_HEAD(&dentry->d_u.d_child);
 
        if (parent) {
-               spin_lock(&dcache_lock);
                spin_lock(&parent->d_lock);
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
                dentry->d_parent = dget_dlock(parent);
@@ -1305,7 +1246,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
                list_add(&dentry->d_u.d_child, &parent->d_subdirs);
                spin_unlock(&dentry->d_lock);
                spin_unlock(&parent->d_lock);
-               spin_unlock(&dcache_lock);
        }
 
        this_cpu_inc(nr_dentry);
@@ -1325,7 +1265,6 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name)
 }
 EXPORT_SYMBOL(d_alloc_name);
 
-/* the caller must hold dcache_lock */
 static void __d_instantiate(struct dentry *dentry, struct inode *inode)
 {
        spin_lock(&dentry->d_lock);
@@ -1354,11 +1293,9 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
 void d_instantiate(struct dentry *entry, struct inode * inode)
 {
        BUG_ON(!list_empty(&entry->d_alias));
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        __d_instantiate(entry, inode);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        security_d_instantiate(entry, inode);
 }
 EXPORT_SYMBOL(d_instantiate);
@@ -1422,11 +1359,9 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
 
        BUG_ON(!list_empty(&entry->d_alias));
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        result = __d_instantiate_unique(entry, inode);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 
        if (!result) {
                security_d_instantiate(entry, inode);
@@ -1515,12 +1450,11 @@ struct dentry *d_obtain_alias(struct inode *inode)
        }
        tmp->d_parent = tmp; /* make sure dput doesn't croak */
 
-       spin_lock(&dcache_lock);
+
        spin_lock(&dcache_inode_lock);
        res = __d_find_alias(inode, 0);
        if (res) {
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
                dput(tmp);
                goto out_iput;
        }
@@ -1538,7 +1472,6 @@ struct dentry *d_obtain_alias(struct inode *inode)
        spin_unlock(&tmp->d_lock);
        spin_unlock(&dcache_inode_lock);
 
-       spin_unlock(&dcache_lock);
        return tmp;
 
  out_iput:
@@ -1568,21 +1501,18 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
        struct dentry *new = NULL;
 
        if (inode && S_ISDIR(inode->i_mode)) {
-               spin_lock(&dcache_lock);
                spin_lock(&dcache_inode_lock);
                new = __d_find_alias(inode, 1);
                if (new) {
                        BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
                        spin_unlock(&dcache_inode_lock);
-                       spin_unlock(&dcache_lock);
                        security_d_instantiate(new, inode);
                        d_move(new, dentry);
                        iput(inode);
                } else {
-                       /* already taking dcache_lock, so d_add() by hand */
+                       /* already taking dcache_inode_lock, so d_add() by hand */
                        __d_instantiate(dentry, inode);
                        spin_unlock(&dcache_inode_lock);
-                       spin_unlock(&dcache_lock);
                        security_d_instantiate(dentry, inode);
                        d_rehash(dentry);
                }
@@ -1655,12 +1585,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
         * Negative dentry: instantiate it unless the inode is a directory and
         * already has a dentry.
         */
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
                __d_instantiate(found, inode);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
                security_d_instantiate(found, inode);
                return found;
        }
@@ -1672,7 +1600,6 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
        new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
        dget_locked(new);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        security_d_instantiate(found, inode);
        d_move(new, found);
        iput(inode);
@@ -1843,7 +1770,6 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
 {
        struct dentry *child;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dparent->d_lock);
        list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
                if (dentry == child) {
@@ -1851,12 +1777,10 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
                        __dget_locked_dlock(dentry);
                        spin_unlock(&dentry->d_lock);
                        spin_unlock(&dparent->d_lock);
-                       spin_unlock(&dcache_lock);
                        return 1;
                }
        }
        spin_unlock(&dparent->d_lock);
-       spin_unlock(&dcache_lock);
 
        return 0;
 }
@@ -1889,7 +1813,6 @@ void d_delete(struct dentry * dentry)
        /*
         * Are we the only user?
         */
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        spin_lock(&dentry->d_lock);
        isdir = S_ISDIR(dentry->d_inode->i_mode);
@@ -1905,7 +1828,6 @@ void d_delete(struct dentry * dentry)
 
        spin_unlock(&dentry->d_lock);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 
        fsnotify_nameremove(dentry, isdir);
 }
@@ -1932,13 +1854,11 @@ static void _d_rehash(struct dentry * entry)
  
 void d_rehash(struct dentry * entry)
 {
-       spin_lock(&dcache_lock);
        spin_lock(&entry->d_lock);
        spin_lock(&dcache_hash_lock);
        _d_rehash(entry);
        spin_unlock(&dcache_hash_lock);
        spin_unlock(&entry->d_lock);
-       spin_unlock(&dcache_lock);
 }
 EXPORT_SYMBOL(d_rehash);
 
@@ -1961,11 +1881,9 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
        BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
        BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */
 
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        memcpy((unsigned char *)dentry->d_name.name, name->name, name->len);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 }
 EXPORT_SYMBOL(dentry_update_name_case);
 
@@ -2058,14 +1976,14 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry,
  * The hash value has to match the hash queue that the dentry is on..
  */
 /*
- * d_move_locked - move a dentry
+ * d_move - move a dentry
  * @dentry: entry to move
  * @target: new dentry
  *
  * Update the dcache to reflect the move of a file name. Negative
  * dcache entries should not be moved in this way.
  */
-static void d_move_locked(struct dentry * dentry, struct dentry * target)
+void d_move(struct dentry * dentry, struct dentry * target)
 {
        if (!dentry->d_inode)
                printk(KERN_WARNING "VFS: moving negative dcache entry\n");
@@ -2114,22 +2032,6 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target)
        spin_unlock(&dentry->d_lock);
        write_sequnlock(&rename_lock);
 }
-
-/**
- * d_move - move a dentry
- * @dentry: entry to move
- * @target: new dentry
- *
- * Update the dcache to reflect the move of a file name. Negative
- * dcache entries should not be moved in this way.
- */
-
-void d_move(struct dentry * dentry, struct dentry * target)
-{
-       spin_lock(&dcache_lock);
-       d_move_locked(dentry, target);
-       spin_unlock(&dcache_lock);
-}
 EXPORT_SYMBOL(d_move);
 
 /**
@@ -2155,13 +2057,12 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
  * This helper attempts to cope with remotely renamed directories
  *
  * It assumes that the caller is already holding
- * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ * dentry->d_parent->d_inode->i_mutex and the dcache_inode_lock
  *
  * Note: If ever the locking in lock_rename() changes, then please
  * remember to update this too...
  */
 static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
-       __releases(dcache_lock)
        __releases(dcache_inode_lock)
 {
        struct mutex *m1 = NULL, *m2 = NULL;
@@ -2185,11 +2086,10 @@ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
                goto out_err;
        m2 = &alias->d_parent->d_inode->i_mutex;
 out_unalias:
-       d_move_locked(alias, dentry);
+       d_move(alias, dentry);
        ret = alias;
 out_err:
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        if (m2)
                mutex_unlock(m2);
        if (m1)
@@ -2249,7 +2149,6 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 
        BUG_ON(!d_unhashed(dentry));
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
 
        if (!inode) {
@@ -2295,7 +2194,6 @@ found:
        spin_unlock(&dcache_hash_lock);
        spin_unlock(&actual->d_lock);
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 out_nolock:
        if (actual == dentry) {
                security_d_instantiate(dentry, inode);
@@ -2307,7 +2205,6 @@ out_nolock:
 
 shouldnt_be_hashed:
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
        BUG();
 }
 EXPORT_SYMBOL_GPL(d_materialise_unique);
@@ -2421,11 +2318,9 @@ char *__d_path(const struct path *path, struct path *root,
        int error;
 
        prepend(&res, &buflen, "\0", 1);
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        error = prepend_path(path, root, &res, &buflen);
        write_sequnlock(&rename_lock);
-       spin_unlock(&dcache_lock);
 
        if (error)
                return ERR_PTR(error);
@@ -2487,14 +2382,12 @@ char *d_path(const struct path *path, char *buf, int buflen)
                return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        get_fs_root(current->fs, &root);
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        tmp = root;
        error = path_with_deleted(path, &tmp, &res, &buflen);
        if (error)
                res = ERR_PTR(error);
        write_sequnlock(&rename_lock);
-       spin_unlock(&dcache_lock);
        path_put(&root);
        return res;
 }
@@ -2520,14 +2413,12 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
                return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        get_fs_root(current->fs, &root);
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        tmp = root;
        error = path_with_deleted(path, &tmp, &res, &buflen);
        if (!error && !path_equal(&tmp, &root))
                error = prepend_unreachable(&res, &buflen);
        write_sequnlock(&rename_lock);
-       spin_unlock(&dcache_lock);
        path_put(&root);
        if (error)
                res =  ERR_PTR(error);
@@ -2594,11 +2485,9 @@ char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
 {
        char *retval;
 
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        retval = __dentry_path(dentry, buf, buflen);
        write_sequnlock(&rename_lock);
-       spin_unlock(&dcache_lock);
 
        return retval;
 }
@@ -2609,7 +2498,6 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
        char *p = NULL;
        char *retval;
 
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        if (d_unlinked(dentry)) {
                p = buf + buflen;
@@ -2619,12 +2507,10 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
        }
        retval = __dentry_path(dentry, buf, buflen);
        write_sequnlock(&rename_lock);
-       spin_unlock(&dcache_lock);
        if (!IS_ERR(retval) && p)
                *p = '/';       /* restore '/' overriden with '\0' */
        return retval;
 Elong:
-       spin_unlock(&dcache_lock);
        return ERR_PTR(-ENAMETOOLONG);
 }
 
@@ -2658,7 +2544,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
        get_fs_root_and_pwd(current->fs, &root, &pwd);
 
        error = -ENOENT;
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        if (!d_unlinked(pwd.dentry)) {
                unsigned long len;
@@ -2669,7 +2554,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                prepend(&cwd, &buflen, "\0", 1);
                error = prepend_path(&pwd, &tmp, &cwd, &buflen);
                write_sequnlock(&rename_lock);
-               spin_unlock(&dcache_lock);
 
                if (error)
                        goto out;
@@ -2690,7 +2574,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                }
        } else {
                write_sequnlock(&rename_lock);
-               spin_unlock(&dcache_lock);
        }
 
 out:
@@ -2776,7 +2659,6 @@ void d_genocide(struct dentry *root)
 rename_retry:
        this_parent = root;
        seq = read_seqbegin(&rename_lock);
-       spin_lock(&dcache_lock);
        spin_lock(&this_parent->d_lock);
 repeat:
        next = this_parent->d_subdirs.next;
@@ -2823,7 +2705,6 @@ resume:
                if (this_parent != child->d_parent ||
                                read_seqretry(&rename_lock, seq)) {
                        spin_unlock(&this_parent->d_lock);
-                       spin_unlock(&dcache_lock);
                        rcu_read_unlock();
                        goto rename_retry;
                }
@@ -2832,7 +2713,6 @@ resume:
                goto resume;
        }
        spin_unlock(&this_parent->d_lock);
-       spin_unlock(&dcache_lock);
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
 }
index 84b8c460a781df3c33ff043f8c2ca65915deb525..53a5c08fb63c71ed3881c132652df891fbf1a234 100644 (file)
@@ -47,24 +47,20 @@ find_acceptable_alias(struct dentry *result,
        if (acceptable(context, result))
                return result;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
                dget_locked(dentry);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
                if (toput)
                        dput(toput);
                if (dentry != result && acceptable(context, dentry)) {
                        dput(result);
                        return dentry;
                }
-               spin_lock(&dcache_lock);
                spin_lock(&dcache_inode_lock);
                toput = dentry;
        }
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 
        if (toput)
                dput(toput);
index cc4794914b52273edeaa0f29f0ca559d8f279559..28b36663c44e45d6599ab03825ff357476f1f0c2 100644 (file)
@@ -100,7 +100,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
                        struct dentry *cursor = file->private_data;
                        loff_t n = file->f_pos - 2;
 
-                       spin_lock(&dcache_lock);
                        spin_lock(&dentry->d_lock);
                        /* d_lock not required for cursor */
                        list_del(&cursor->d_u.d_child);
@@ -116,7 +115,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
                        }
                        list_add_tail(&cursor->d_u.d_child, p);
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                }
        }
        mutex_unlock(&dentry->d_inode->i_mutex);
@@ -159,7 +157,6 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        i++;
                        /* fallthrough */
                default:
-                       spin_lock(&dcache_lock);
                        spin_lock(&dentry->d_lock);
                        if (filp->f_pos == 2)
                                list_move(q, &dentry->d_subdirs);
@@ -175,13 +172,11 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 
                                spin_unlock(&next->d_lock);
                                spin_unlock(&dentry->d_lock);
-                               spin_unlock(&dcache_lock);
                                if (filldir(dirent, next->d_name.name, 
                                            next->d_name.len, filp->f_pos, 
                                            next->d_inode->i_ino, 
                                            dt_type(next->d_inode)) < 0)
                                        return 0;
-                               spin_lock(&dcache_lock);
                                spin_lock(&dentry->d_lock);
                                spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
                                /* next is still alive */
@@ -191,7 +186,6 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
                                filp->f_pos++;
                        }
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
        }
        return 0;
 }
@@ -285,7 +279,6 @@ int simple_empty(struct dentry *dentry)
        struct dentry *child;
        int ret = 0;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
                spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
@@ -298,7 +291,6 @@ int simple_empty(struct dentry *dentry)
        ret = 1;
 out:
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
        return ret;
 }
 
index cbfa5fb3107220addaefb2f5e5dab66dcf8b9531..5642bc2be4182bfa3f9ab9027fe04acf4eb501f5 100644 (file)
@@ -612,8 +612,8 @@ int follow_up(struct path *path)
        return 1;
 }
 
-/* no need for dcache_lock, as serialization is taken care in
- * namespace.c
+/*
+ * serialization is taken care of in namespace.c
  */
 static int __follow_mount(struct path *path)
 {
@@ -645,9 +645,6 @@ static void follow_mount(struct path *path)
        }
 }
 
-/* no need for dcache_lock, as serialization is taken care in
- * namespace.c
- */
 int follow_down(struct path *path)
 {
        struct vfsmount *mounted;
@@ -2131,12 +2128,10 @@ void dentry_unhash(struct dentry *dentry)
 {
        dget(dentry);
        shrink_dcache_parent(dentry);
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        if (dentry->d_count == 2)
                __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 int vfs_rmdir(struct inode *dir, struct dentry *dentry)
index 102278ed38bd01715c674254c3b35e91abf5e00e..de15c533311cd9b6674c5989d24602e1fce83065 100644 (file)
@@ -391,7 +391,6 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
        }
 
        /* If a pointer is invalid, we search the dentry. */
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
@@ -402,13 +401,11 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
                        else
                                dent = NULL;
                        spin_unlock(&parent->d_lock);
-                       spin_unlock(&dcache_lock);
                        goto out;
                }
                next = next->next;
        }
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
        return NULL;
 
 out:
index c4b718ff9a6b5951af141fbfa980d25f0743c9a6..1220df75ff228dfc275a2d1470be4273fa85c54b 100644 (file)
@@ -193,7 +193,6 @@ ncp_renew_dentries(struct dentry *parent)
        struct list_head *next;
        struct dentry *dentry;
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
@@ -207,7 +206,6 @@ ncp_renew_dentries(struct dentry *parent)
                next = next->next;
        }
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 static inline void
@@ -217,7 +215,6 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
        struct list_head *next;
        struct dentry *dentry;
 
-       spin_lock(&dcache_lock);
        spin_lock(&parent->d_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
@@ -227,7 +224,6 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
                next = next->next;
        }
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 struct ncp_cache_head {
index 12de824edb5c7a0369fd47d5a7147324dca6d0ba..eb77471b8823d474ff1def428242978bf076bbfd 100644 (file)
@@ -1718,11 +1718,9 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
        dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
                dir->i_ino, dentry->d_name.name);
 
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        if (dentry->d_count > 1) {
                spin_unlock(&dentry->d_lock);
-               spin_unlock(&dcache_lock);
                /* Start asynchronous writeout of the inode */
                write_inode_now(dentry->d_inode, 0);
                error = nfs_sillyrename(dir, dentry);
@@ -1733,7 +1731,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
                need_rehash = 1;
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
        error = nfs_safe_remove(dentry);
        if (!error || error == -ENOENT) {
                nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
index 850f67d5f0ac71a2439bec749d65513141a28f22..b3e36c3430de827ae3f054825fa9f8d1137607db 100644 (file)
@@ -63,13 +63,11 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
                 * This again causes shrink_dcache_for_umount_subtree() to
                 * Oops, since the test for IS_ROOT() will fail.
                 */
-               spin_lock(&dcache_lock);
                spin_lock(&dcache_inode_lock);
                spin_lock(&sb->s_root->d_lock);
                list_del_init(&sb->s_root->d_alias);
                spin_unlock(&sb->s_root->d_lock);
                spin_unlock(&dcache_inode_lock);
-               spin_unlock(&dcache_lock);
        }
        return 0;
 }
index 78c0ebb0b07c93b40bdbcc07cf9744a3860f9bd6..74aaf3963c101ab1775e1efd3f544d0ac310273c 100644 (file)
@@ -60,7 +60,6 @@ rename_retry:
 
        seq = read_seqbegin(&rename_lock);
        rcu_read_lock();
-       spin_lock(&dcache_lock);
        while (!IS_ROOT(dentry) && dentry != droot) {
                namelen = dentry->d_name.len;
                buflen -= namelen + 1;
@@ -71,7 +70,6 @@ rename_retry:
                *--end = '/';
                dentry = dentry->d_parent;
        }
-       spin_unlock(&dcache_lock);
        rcu_read_unlock();
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
@@ -91,7 +89,6 @@ rename_retry:
        memcpy(end, base, namelen);
        return end;
 Elong_unlock:
-       spin_unlock(&dcache_lock);
        rcu_read_unlock();
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
index ae769fc9b66c9c0e639f0f2fe7f1af9115eb2619..9be6ec1f36d838facd3647c16574ef3c75f97508 100644 (file)
@@ -59,7 +59,6 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
        /* determine if the children should tell inode about their events */
        watched = fsnotify_inode_watches_children(inode);
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        /* run all of the dentries associated with this inode.  Since this is a
         * directory, there damn well better only be one item on this list */
@@ -84,7 +83,6 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
                spin_unlock(&alias->d_lock);
        }
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /* Notify this dentry's parent about a child's events. */
index c31b5c647ac78e0761813cfcd5a4a9c53973842d..b7de749bdd1253b6b0f612d5bcacf4b9d2e0b8a3 100644 (file)
@@ -169,7 +169,6 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
        struct list_head *p;
        struct dentry *dentry = NULL;
 
-       spin_lock(&dcache_lock);
        spin_lock(&dcache_inode_lock);
        list_for_each(p, &inode->i_dentry) {
                dentry = list_entry(p, struct dentry, d_alias);
@@ -189,7 +188,6 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
        }
 
        spin_unlock(&dcache_inode_lock);
-       spin_unlock(&dcache_lock);
 
        return dentry;
 }
index c963ebada922a938739697ab1b8cda797570bf7b..a2ceb94b0e3812c254ce009d1b7878f6effa31bd 100644 (file)
@@ -183,7 +183,6 @@ struct dentry_operations {
 #define DCACHE_GENOCIDE                0x0200
 
 extern spinlock_t dcache_inode_lock;
-extern spinlock_t dcache_lock;
 extern seqlock_t rename_lock;
 
 static inline int dname_external(struct dentry *dentry)
@@ -296,8 +295,8 @@ extern char *dentry_path(struct dentry *, char *, int);
  *     destroyed when it has references. dget() should never be
  *     called for dentries with zero reference counter. For these cases
  *     (preferably none, functions in dcache.c are sufficient for normal
- *     needs and they take necessary precautions) you should hold dcache_lock
- *     and call dget_locked() instead of dget().
+ *     needs and they take necessary precautions) you should hold d_lock
+ *     and call dget_dlock() instead of dget().
  */
 static inline struct dentry *dget_dlock(struct dentry *dentry)
 {
index 090f0eacde296ec52a06fe5eb1b13c07808b7ada..296cf2fde945f2871fbd830233a38b39b0a2fe27 100644 (file)
@@ -1378,7 +1378,7 @@ struct super_block {
 #else
        struct list_head        s_files;
 #endif
-       /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
+       /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */
        struct list_head        s_dentry_lru;   /* unused dentry lru */
        int                     s_nr_dentry_unused;     /* # of dentry on lru */
 
@@ -2446,6 +2446,10 @@ static inline ino_t parent_ino(struct dentry *dentry)
 {
        ino_t res;
 
+       /*
+        * Don't strictly need d_lock here? If the parent ino could change
+        * then surely we'd have a deeper race in the caller?
+        */
        spin_lock(&dentry->d_lock);
        res = dentry->d_parent->d_inode->i_ino;
        spin_unlock(&dentry->d_lock);
index b10bcdeaef768b2b0b123c4a6c862b3f5f6c0694..2a53f10712b36097b648e4a61cb6323e5a42de84 100644 (file)
@@ -17,7 +17,6 @@
 
 /*
  * fsnotify_d_instantiate - instantiate a dentry for inode
- * Called with dcache_lock held.
  */
 static inline void fsnotify_d_instantiate(struct dentry *dentry,
                                          struct inode *inode)
@@ -62,7 +61,6 @@ static inline int fsnotify_perm(struct file *file, int mask)
 
 /*
  * fsnotify_d_move - dentry has been moved
- * Called with dcache_lock and dentry->d_lock held.
  */
 static inline void fsnotify_d_move(struct dentry *dentry)
 {
index 7380763595d30accb255728f45682550cc540d63..69ad89b504895431265cbb106b53cc8be543089b 100644 (file)
@@ -329,9 +329,15 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
 {
        struct dentry *parent;
 
-       assert_spin_locked(&dcache_lock);
        assert_spin_locked(&dentry->d_lock);
 
+       /*
+        * Serialisation of setting PARENT_WATCHED on the dentries is provided
+        * by d_lock. If inotify_inode_watched changes after we have taken
+        * d_lock, the following __fsnotify_update_child_dentry_flags call will
+        * find our entry, so it will spin until we complete here, and update
+        * us with the new state.
+        */
        parent = dentry->d_parent;
        if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
                dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
@@ -341,15 +347,12 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
 
 /*
  * fsnotify_d_instantiate - instantiate a dentry for inode
- * Called with dcache_lock held.
  */
 static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
 {
        if (!inode)
                return;
 
-       assert_spin_locked(&dcache_lock);
-
        spin_lock(&dentry->d_lock);
        __fsnotify_update_dcache_flags(dentry);
        spin_unlock(&dentry->d_lock);
index 05b441d9364202ff09ccaa4db7ca28044db30290..aec730b539358407847b756fcf9aaa9ed61e1fcc 100644 (file)
@@ -41,7 +41,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
  *  - require a directory
  *  - ending slashes ok even for nonexistent files
  *  - internal "there are more path components" flag
- *  - locked when lookup done with dcache_lock held
  *  - dentry cache is untrusted; force a real lookup
  */
 #define LOOKUP_FOLLOW           1
index 7b4705b51d4a13839476113ff3e6e7b0ce6b8ddd..1864cb6a6a59f7de3ce86ec52dcaa15896cb7e97 100644 (file)
@@ -876,7 +876,6 @@ static void cgroup_clear_directory(struct dentry *dentry)
        struct list_head *node;
 
        BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
-       spin_lock(&dcache_lock);
        spin_lock(&dentry->d_lock);
        node = dentry->d_subdirs.next;
        while (node != &dentry->d_subdirs) {
@@ -891,18 +890,15 @@ static void cgroup_clear_directory(struct dentry *dentry)
                        dget_locked_dlock(d);
                        spin_unlock(&d->d_lock);
                        spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
                        d_delete(d);
                        simple_unlink(dentry->d_inode, d);
                        dput(d);
-                       spin_lock(&dcache_lock);
                        spin_lock(&dentry->d_lock);
                } else
                        spin_unlock(&d->d_lock);
                node = dentry->d_subdirs.next;
        }
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 /*
@@ -914,14 +910,12 @@ static void cgroup_d_remove_dir(struct dentry *dentry)
 
        cgroup_clear_directory(dentry);
 
-       spin_lock(&dcache_lock);
        parent = dentry->d_parent;
        spin_lock(&parent->d_lock);
        spin_lock(&dentry->d_lock);
        list_del_init(&dentry->d_u.d_child);
        spin_unlock(&dentry->d_lock);
        spin_unlock(&parent->d_lock);
-       spin_unlock(&dcache_lock);
        remove_dir(dentry);
 }
 
index 6b9aee20f2426b88024a25749402fc5ca1ff7a0a..ca389394fa2a1d563097c06d34881ac0e8e42559 100644 (file)
  *    ->inode_lock             (zap_pte_range->set_page_dirty)
  *    ->private_lock           (zap_pte_range->__set_page_dirty_buffers)
  *
- *  ->task->proc_lock
- *    ->dcache_lock            (proc_pid_lookup)
- *
  *  (code doesn't rely on that order, so you could switch it around)
  *  ->tasklist_lock             (memory_failure, collect_procs_ao)
  *    ->i_mmap_lock
index 017ec096446ea1825c60cf1aff5bd36fecbcb823..2285d693f296e404354949622688dd2fb0e57886 100644 (file)
@@ -1145,7 +1145,6 @@ static void sel_remove_entries(struct dentry *de)
 {
        struct list_head *node;
 
-       spin_lock(&dcache_lock);
        spin_lock(&de->d_lock);
        node = de->d_subdirs.next;
        while (node != &de->d_subdirs) {
@@ -1158,11 +1157,9 @@ static void sel_remove_entries(struct dentry *de)
                        dget_locked_dlock(d);
                        spin_unlock(&de->d_lock);
                        spin_unlock(&d->d_lock);
-                       spin_unlock(&dcache_lock);
                        d_delete(d);
                        simple_unlink(de->d_inode, d);
                        dput(d);
-                       spin_lock(&dcache_lock);
                        spin_lock(&de->d_lock);
                } else
                        spin_unlock(&d->d_lock);
@@ -1170,7 +1167,6 @@ static void sel_remove_entries(struct dentry *de)
        }
 
        spin_unlock(&de->d_lock);
-       spin_unlock(&dcache_lock);
 }
 
 #define BOOL_DIR_NAME "booleans"