/* * fs/dcache.c * * Complete reimplementation * (C) 1997 Thomas Schoebel-Theuer, * with heavy changes by Linus Torvalds */ /* * Notes on the allocation strategy: * * The dcache is a master of the icache - whenever a dcache entry * exists, the inode will always exist. "iput()" is done either when * the dcache entry is deleted or garbage collected. */ #include <linux/syscalls.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/fsnotify.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/hash.h>#include <linux/cache.h>#include <linux/export.h>#include <linux/mount.h>#include <linux/file.h>#include <asm/uaccess.h>#include <linux/security.h>#include <linux/seqlock.h>#include <linux/swap.h>#include <linux/bootmem.h>#include <linux/fs_struct.h>#include <linux/hardirq.h>#include <linux/bit_spinlock.h>#include <linux/rculist_bl.h>#include <linux/prefetch.h>#include <linux/ratelimit.h>#include "internal.h"#include "mount.h" /* * Usage: * dcache->d_inode->i_lock protects: * - i_dentry, d_alias, d_inode of aliases * dcache_hash_bucket lock protects: * - the dcache hash table * s_anon bl list spinlock protects: * - the s_anon list (see __d_drop) * dcache_lru_lock protects: * - the dcache lru lists and counters * d_lock protects: * - d_flags * - d_name * - d_lru * - d_count * - d_unhashed() * - d_parent and d_subdirs * - childrens' d_child and d_parent * - d_alias, d_inode * * Ordering: * dentry->d_inode->i_lock * dentry->d_lock * dcache_lru_lock * dcache_hash_bucket lock * s_anon lock * * If there is an ancestor relationship: * dentry->d_parent->...->d_parent->d_lock * ... * dentry->d_parent->d_lock * dentry->d_lock * * If no ancestor relationship: * if (dentry1 < dentry2) * dentry1->d_lock * dentry2->d_lock */int sysctl_vfs_cache_pressure __read_mostly = 100;EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); EXPORT_SYMBOL(rename_lock); static struct kmem_cache *dentry_cache __read_mostly; /* * This is the single most critical data structure when it comes * to the dcache: the hashtable for lookups. Somebody should try * to make this good - I've just made it work. * * This hash-function tries to avoid losing too many bits of hash * information, yet avoid using a prime hash-size or similar. */#define D_HASHBITS d_hash_shift#define D_HASHMASK d_hash_mask static unsigned int d_hash_mask __read_mostly;static unsigned int d_hash_shift __read_mostly; static struct hlist_bl_head *dentry_hashtable __read_mostly; static inline struct hlist_bl_head *d_hash(const struct dentry *parent, unsigned int hash){ hash += (unsigned long) parent / L1_CACHE_BYTES; hash = hash + (hash >> D_HASHBITS); return dentry_hashtable + (hash & D_HASHMASK);} /* Statistics gathering. */struct dentry_stat_t dentry_stat = { .age_limit = 45,}; static DEFINE_PER_CPU(unsigned int, nr_dentry); #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS)static int get_nr_dentry(void){ int i; int sum = 0; for_each_possible_cpu(i) sum += per_cpu(nr_dentry, i); return sum < 0 ? 0 : sum;} int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos){ dentry_stat.nr_dentry = get_nr_dentry(); return proc_dointvec(table, write, buffer, lenp, ppos);}#endif /* * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */#ifdef CONFIG_DCACHE_WORD_ACCESS #include <asm/word-at-a-time.h>/* * NOTE! 'cs' and 'scount' come from a dentry, so it has a * aligned allocation for this particular component. We don't * strictly need the load_unaligned_zeropad() safety, but it * doesn't hurt either. * * In contrast, 'ct' and 'tcount' can be from a pathname, and do * need the careful unaligned handling. */static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount){ unsigned long a,b,mask; for (;;) { a = *(unsigned long *)cs; b = load_unaligned_zeropad(ct); if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) return 1; cs += sizeof(unsigned long); ct += sizeof(unsigned long); tcount -= sizeof(unsigned long); if (!tcount) return 0; } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask));} #else static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount){ do { if (*cs != *ct) return 1; cs++; ct++; tcount--; } while (tcount); return 0;} #endif static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount){ const unsigned char *cs; /* * Be careful about RCU walk racing with rename: * use ACCESS_ONCE to fetch the name pointer. * * NOTE! Even if a rename will mean that the length * was not loaded atomically, we don't care. The * RCU walk will check the sequence count eventually, * and catch it. And we won't overrun the buffer, * because we're reading the name pointer atomically, * and a dentry name is guaranteed to be properly * terminated with a NUL byte. * * End result: even if 'len' is wrong, we'll exit * early because the data cannot match (there can * be no NUL in the ct/tcount data) */ cs = ACCESS_ONCE(dentry->d_name.name); smp_read_barrier_depends(); return dentry_string_cmp(cs, ct, tcount);} static void __d_free(struct rcu_head *head){ struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); WARN_ON(!list_empty(&dentry->d_alias)); if (dname_external(dentry)) kfree(dentry->d_name.name); kmem_cache_free(dentry_cache, dentry); } /* * no locks, please. */static void d_free(struct dentry *dentry){ BUG_ON(dentry->d_count); this_cpu_dec(nr_dentry); if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); /* if dentry was never visible to RCU, immediate free is OK */ if (!(dentry->d_flags & DCACHE_RCUACCESS)) __d_free(&dentry->d_u.d_rcu); else call_rcu(&dentry->d_u.d_rcu, __d_free);} /** * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups * @dentry: the target dentry * After this call, in-progress rcu-walk path lookup will fail. This * should be called after unhashing, and after changing d_inode (if * the dentry has not already been unhashed). */static inline void dentry_rcuwalk_barrier(struct dentry *dentry){ assert_spin_locked(&dentry->d_lock); /* Go through a barrier */ write_seqcount_barrier(&dentry->d_seq);} /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. Dentry has no refcount * and is unhashed. */static void dentry_iput(struct dentry * dentry) __releases(dentry->d_lock) __releases(dentry->d_inode->i_lock){ struct inode *inode = dentry->d_inode; if (inode) { dentry->d_inode = NULL; list_del_init(&dentry->d_alias); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); if (!inode->i_nlink) fsnotify_inoderemove(inode); if (dentry->d_op && dentry->d_op->d_iput) dentry->d_op->d_iput(dentry, inode); else iput(inode); } else { spin_unlock(&dentry->d_lock); }} /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. dentry remains in-use. */static void dentry_unlink_inode(struct dentry * dentry) __releases(dentry->d_lock) __releases(dentry->d_inode->i_lock){ struct inode *inode = dentry->d_inode; dentry->d_inode = NULL; list_del_init(&dentry->d_alias); dentry_rcuwalk_barrier(dentry); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); if (!inode->i_nlink) fsnotify_inoderemove(inode); if (dentry->d_op && dentry->d_op->d_iput) dentry->d_op->d_iput(dentry, inode); else iput(inode);} /* * dentry_lru_(add|del|prune|move_tail) must be called with d_lock held. */static void dentry_lru_add(struct dentry *dentry){ if (list_empty(&dentry->d_lru)) { spin_lock(&dcache_lru_lock); list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru); dentry->d_sb->s_nr_dentry_unused++; dentry_stat.nr_unused++; spin_unlock(&dcache_lru_lock); }} static void __dentry_lru_del(struct dentry *dentry){ list_del_init(&dentry->d_lru); dentry->d_flags &= ~DCACHE_SHRINK_LIST; dentry->d_sb->s_nr_dentry_unused--; dentry_stat.nr_unused--;} /* * Remove a dentry with references from the LRU. */static void dentry_lru_del(struct dentry *dentry){ if (!list_empty(&dentry->d_lru)) { spin_lock(&dcache_lru_lock); __dentry_lru_del(dentry); spin_unlock(&dcache_lru_lock); }} /* * Remove a dentry that is unreferenced and about to be pruned * (unhashed and destroyed) from the LRU, and inform the file system. * This wrapper should be called _prior_ to unhashing a victim dentry. */static void dentry_lru_prune(struct dentry *dentry){ if (!list_empty(&dentry->d_lru)) { if (dentry->d_flags & DCACHE_OP_PRUNE) dentry->d_op->d_prune(dentry); spin_lock(&dcache_lru_lock); __dentry_lru_del(dentry); spin_unlock(&dcache_lru_lock); }} static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list){ spin_lock(&dcache_lru_lock); if (list_empty(&dentry->d_lru)) { list_add_tail(&dentry->d_lru, list); dentry->d_sb->s_nr_dentry_unused++; dentry_stat.nr_unused++; } else { list_move_tail(&dentry->d_lru, list); } spin_unlock(&dcache_lru_lock);} /** * d_kill - kill dentry and return parent * @dentry: dentry to kill * @parent: parent dentry * * The dentry must already be unhashed and removed from the LRU. * * If this is the root of the dentry tree, return NULL. * * 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(dentry->d_inode->i_lock){ list_del(&dentry->d_u.d_child); /* * Inform try_to_ascend() that we are no longer attached to the * dentry tree */ dentry->d_flags |= DCACHE_DISCONNECTED; if (parent) spin_unlock(&parent->d_lock); dentry_iput(dentry); /* * dentry_iput drops the locks, at which point nobody (except * transient RCU lookups) can reach this dentry. */ d_free(dentry); return parent;} /* * Unhash a dentry without inserting an RCU walk barrier or checking that * dentry->d_lock is locked. The caller must take care of that, if * appropriate. */static void __d_shrink(struct dentry *dentry){ if (!d_unhashed(dentry)) { struct hlist_bl_head *b; if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) b = &dentry->d_sb->s_anon; else b = d_hash(dentry->d_parent, dentry->d_name.hash); hlist_bl_lock(b); __hlist_bl_del(&dentry->d_hash); dentry->d_hash.pprev = NULL; hlist_bl_unlock(b); }} /** * d_drop - drop a dentry * @dentry: dentry to drop * * d_drop() unhashes the entry from the parent dentry hashes, so that it won't * be found through a VFS lookup any more. Note that this is different from * deleting the dentry - d_delete will try to mark the dentry negative if * possible, giving a successful _negative_ lookup, while d_drop will * just make the cache lookup fail. * * d_drop() is used mainly for stuff that wants to invalidate a dentry for some * reason (NFS timeouts or autofs deletes). * * __d_drop requires dentry->d_lock. */void __d_drop(struct dentry *dentry){ if (!d_unhashed(dentry)) { __d_shrink(dentry); dentry_rcuwalk_barrier(dentry); }}EXPORT_SYMBOL(__d_drop); void d_drop(struct dentry *dentry){ spin_lock(&dentry->d_lock); __d_drop(dentry); spin_unlock(&dentry->d_lock);}EXPORT_SYMBOL(d_drop); /* * d_clear_need_lookup - drop a dentry from cache and clear the need lookup flag * @dentry: dentry to drop * * This is called when we do a lookup on a placeholder dentry that needed to be * looked up. The dentry should have been hashed in order for it to be found by * the lookup code, but now needs to be unhashed while we do the actual lookup * and clear the DCACHE_NEED_LOOKUP flag. */void d_clear_need_lookup(struct dentry *dentry){ spin_lock(&dentry->d_lock); __d_drop(dentry); dentry->d_flags &= ~DCACHE_NEED_LOOKUP; spin_unlock(&dentry->d_lock);}EXPORT_SYMBOL(d_clear_need_lookup); /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */static inline struct dentry *dentry_kill(struct dentry *dentry, int ref) __releases(dentry->d_lock){ struct inode *inode; struct dentry *parent; inode = dentry->d_inode; if (inode && !spin_trylock(&inode->i_lock)) {relock: spin_unlock(&dentry->d_lock); cpu_relax(); return dentry; /* try again with same dentry */ } if (IS_ROOT(dentry)) parent = NULL; else parent = dentry->d_parent; if (parent && !spin_trylock(&parent->d_lock)) { if (inode) spin_unlock(&inode->i_lock);Lines 1–500 of 3165. Load more
/* * fs/dcache.c * * Complete reimplementation * (C) 1997 Thomas Schoebel-Theuer, * with heavy changes by Linus Torvalds */ /* * Notes on the allocation strategy: * * The dcache is a master of the icache - whenever a dcache entry * exists, the inode will always exist. "iput()" is done either when * the dcache entry is deleted or garbage collected. */ #include <linux/syscalls.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/fsnotify.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/hash.h> #include <linux/cache.h> #include <linux/export.h> #include <linux/mount.h> #include <linux/file.h> #include <asm/uaccess.h> #include <linux/security.h> #include <linux/seqlock.h> #include <linux/swap.h> #include <linux/bootmem.h> #include <linux/fs_struct.h> #include <linux/hardirq.h> #include <linux/bit_spinlock.h> #include <linux/rculist_bl.h> #include <linux/prefetch.h> #include <linux/ratelimit.h> #include "internal.h" #include "mount.h" /* * Usage: * dcache->d_inode->i_lock protects: * - i_dentry, d_alias, d_inode of aliases * dcache_hash_bucket lock protects: * - the dcache hash table * s_anon bl list spinlock protects: * - the s_anon list (see __d_drop) * dcache_lru_lock protects: * - the dcache lru lists and counters * d_lock protects: * - d_flags * - d_name * - d_lru * - d_count * - d_unhashed() * - d_parent and d_subdirs * - childrens' d_child and d_parent * - d_alias, d_inode * * Ordering: * dentry->d_inode->i_lock * dentry->d_lock * dcache_lru_lock * dcache_hash_bucket lock * s_anon lock * * If there is an ancestor relationship: * dentry->d_parent->...->d_parent->d_lock * ... * dentry->d_parent->d_lock * dentry->d_lock * * If no ancestor relationship: * if (dentry1 < dentry2) * dentry1->d_lock * dentry2->d_lock */ int sysctl_vfs_cache_pressure __read_mostly = 100; EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock); __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); EXPORT_SYMBOL(rename_lock); static struct kmem_cache *dentry_cache __read_mostly; /* * This is the single most critical data structure when it comes * to the dcache: the hashtable for lookups. Somebody should try * to make this good - I've just made it work. * * This hash-function tries to avoid losing too many bits of hash * information, yet avoid using a prime hash-size or similar. */ #define D_HASHBITS d_hash_shift #define D_HASHMASK d_hash_mask static unsigned int d_hash_mask __read_mostly; static unsigned int d_hash_shift __read_mostly; static struct hlist_bl_head *dentry_hashtable __read_mostly; static inline struct hlist_bl_head *d_hash(const struct dentry *parent, unsigned int hash) { hash += (unsigned long) parent / L1_CACHE_BYTES; hash = hash + (hash >> D_HASHBITS); return dentry_hashtable + (hash & D_HASHMASK); } /* Statistics gathering. */ struct dentry_stat_t dentry_stat = { .age_limit = 45, }; static DEFINE_PER_CPU(unsigned int, nr_dentry); #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) static int get_nr_dentry(void) { int i; int sum = 0; for_each_possible_cpu(i) sum += per_cpu(nr_dentry, i); return sum < 0 ? 0 : sum; } int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { dentry_stat.nr_dentry = get_nr_dentry(); return proc_dointvec(table, write, buffer, lenp, ppos); } #endif /* * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */ #ifdef CONFIG_DCACHE_WORD_ACCESS #include <asm/word-at-a-time.h> /* * NOTE! 'cs' and 'scount' come from a dentry, so it has a * aligned allocation for this particular component. We don't * strictly need the load_unaligned_zeropad() safety, but it * doesn't hurt either. * * In contrast, 'ct' and 'tcount' can be from a pathname, and do * need the careful unaligned handling. */ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) { unsigned long a,b,mask; for (;;) { a = *(unsigned long *)cs; b = load_unaligned_zeropad(ct); if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) return 1; cs += sizeof(unsigned long); ct += sizeof(unsigned long); tcount -= sizeof(unsigned long); if (!tcount) return 0; } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask)); } #else static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) { do { if (*cs != *ct) return 1; cs++; ct++; tcount--; } while (tcount); return 0; } #endif static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount) { const unsigned char *cs; /* * Be careful about RCU walk racing with rename: * use ACCESS_ONCE to fetch the name pointer. * * NOTE! Even if a rename will mean that the length * was not loaded atomically, we don't care. The * RCU walk will check the sequence count eventually, * and catch it. And we won't overrun the buffer, * because we're reading the name pointer atomically, * and a dentry name is guaranteed to be properly * terminated with a NUL byte. * * End result: even if 'len' is wrong, we'll exit * early because the data cannot match (there can * be no NUL in the ct/tcount data) */ cs = ACCESS_ONCE(dentry->d_name.name); smp_read_barrier_depends(); return dentry_string_cmp(cs, ct, tcount); } static void __d_free(struct rcu_head *head) { struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); WARN_ON(!list_empty(&dentry->d_alias)); if (dname_external(dentry)) kfree(dentry->d_name.name); kmem_cache_free(dentry_cache, dentry); } /* * no locks, please. */ static void d_free(struct dentry *dentry) { BUG_ON(dentry->d_count); this_cpu_dec(nr_dentry); if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); /* if dentry was never visible to RCU, immediate free is OK */ if (!(dentry->d_flags & DCACHE_RCUACCESS)) __d_free(&dentry->d_u.d_rcu); else call_rcu(&dentry->d_u.d_rcu, __d_free); } /** * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups * @dentry: the target dentry * After this call, in-progress rcu-walk path lookup will fail. This * should be called after unhashing, and after changing d_inode (if * the dentry has not already been unhashed). */ static inline void dentry_rcuwalk_barrier(struct dentry *dentry) { assert_spin_locked(&dentry->d_lock); /* Go through a barrier */ write_seqcount_barrier(&dentry->d_seq); } /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. Dentry has no refcount * and is unhashed. */ static void dentry_iput(struct dentry * dentry) __releases(dentry->d_lock) __releases(dentry->d_inode->i_lock) { struct inode *inode = dentry->d_inode; if (inode) { dentry->d_inode = NULL; list_del_init(&dentry->d_alias); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); if (!inode->i_nlink) fsnotify_inoderemove(inode); if (dentry->d_op && dentry->d_op->d_iput) dentry->d_op->d_iput(dentry, inode); else iput(inode); } else { spin_unlock(&dentry->d_lock); } } /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. dentry remains in-use. */ static void dentry_unlink_inode(struct dentry * dentry) __releases(dentry->d_lock) __releases(dentry->d_inode->i_lock) { struct inode *inode = dentry->d_inode; dentry->d_inode = NULL; list_del_init(&dentry->d_alias); dentry_rcuwalk_barrier(dentry); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); if (!inode->i_nlink) fsnotify_inoderemove(inode); if (dentry->d_op && dentry->d_op->d_iput) dentry->d_op->d_iput(dentry, inode); else iput(inode); } /* * dentry_lru_(add|del|prune|move_tail) must be called with d_lock held. */ static void dentry_lru_add(struct dentry *dentry) { if (list_empty(&dentry->d_lru)) { spin_lock(&dcache_lru_lock); list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru); dentry->d_sb->s_nr_dentry_unused++; dentry_stat.nr_unused++; spin_unlock(&dcache_lru_lock); } } static void __dentry_lru_del(struct dentry *dentry) { list_del_init(&dentry->d_lru); dentry->d_flags &= ~DCACHE_SHRINK_LIST; dentry->d_sb->s_nr_dentry_unused--; dentry_stat.nr_unused--; } /* * Remove a dentry with references from the LRU. */ static void dentry_lru_del(struct dentry *dentry) { if (!list_empty(&dentry->d_lru)) { spin_lock(&dcache_lru_lock); __dentry_lru_del(dentry); spin_unlock(&dcache_lru_lock); } } /* * Remove a dentry that is unreferenced and about to be pruned * (unhashed and destroyed) from the LRU, and inform the file system. * This wrapper should be called _prior_ to unhashing a victim dentry. */ static void dentry_lru_prune(struct dentry *dentry) { if (!list_empty(&dentry->d_lru)) { if (dentry->d_flags & DCACHE_OP_PRUNE) dentry->d_op->d_prune(dentry); spin_lock(&dcache_lru_lock); __dentry_lru_del(dentry); spin_unlock(&dcache_lru_lock); } } static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list) { spin_lock(&dcache_lru_lock); if (list_empty(&dentry->d_lru)) { list_add_tail(&dentry->d_lru, list); dentry->d_sb->s_nr_dentry_unused++; dentry_stat.nr_unused++; } else { list_move_tail(&dentry->d_lru, list); } spin_unlock(&dcache_lru_lock); } /** * d_kill - kill dentry and return parent * @dentry: dentry to kill * @parent: parent dentry * * The dentry must already be unhashed and removed from the LRU. * * If this is the root of the dentry tree, return NULL. * * 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(dentry->d_inode->i_lock) { list_del(&dentry->d_u.d_child); /* * Inform try_to_ascend() that we are no longer attached to the * dentry tree */ dentry->d_flags |= DCACHE_DISCONNECTED; if (parent) spin_unlock(&parent->d_lock); dentry_iput(dentry); /* * dentry_iput drops the locks, at which point nobody (except * transient RCU lookups) can reach this dentry. */ d_free(dentry); return parent; } /* * Unhash a dentry without inserting an RCU walk barrier or checking that * dentry->d_lock is locked. The caller must take care of that, if * appropriate. */ static void __d_shrink(struct dentry *dentry) { if (!d_unhashed(dentry)) { struct hlist_bl_head *b; if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) b = &dentry->d_sb->s_anon; else b = d_hash(dentry->d_parent, dentry->d_name.hash); hlist_bl_lock(b); __hlist_bl_del(&dentry->d_hash); dentry->d_hash.pprev = NULL; hlist_bl_unlock(b); } } /** * d_drop - drop a dentry * @dentry: dentry to drop * * d_drop() unhashes the entry from the parent dentry hashes, so that it won't * be found through a VFS lookup any more. Note that this is different from * deleting the dentry - d_delete will try to mark the dentry negative if * possible, giving a successful _negative_ lookup, while d_drop will * just make the cache lookup fail. * * d_drop() is used mainly for stuff that wants to invalidate a dentry for some * reason (NFS timeouts or autofs deletes). * * __d_drop requires dentry->d_lock. */ void __d_drop(struct dentry *dentry) { if (!d_unhashed(dentry)) { __d_shrink(dentry); dentry_rcuwalk_barrier(dentry); } } EXPORT_SYMBOL(__d_drop); void d_drop(struct dentry *dentry) { spin_lock(&dentry->d_lock); __d_drop(dentry); spin_unlock(&dentry->d_lock); } EXPORT_SYMBOL(d_drop); /* * d_clear_need_lookup - drop a dentry from cache and clear the need lookup flag * @dentry: dentry to drop * * This is called when we do a lookup on a placeholder dentry that needed to be * looked up. The dentry should have been hashed in order for it to be found by * the lookup code, but now needs to be unhashed while we do the actual lookup * and clear the DCACHE_NEED_LOOKUP flag. */ void d_clear_need_lookup(struct dentry *dentry) { spin_lock(&dentry->d_lock); __d_drop(dentry); dentry->d_flags &= ~DCACHE_NEED_LOOKUP; spin_unlock(&dentry->d_lock); } EXPORT_SYMBOL(d_clear_need_lookup); /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */ static inline struct dentry *dentry_kill(struct dentry *dentry, int ref) __releases(dentry->d_lock) { struct inode *inode; struct dentry *parent; inode = dentry->d_inode; if (inode && !spin_trylock(&inode->i_lock)) { relock: spin_unlock(&dentry->d_lock); cpu_relax(); return dentry; /* try again with same dentry */ } if (IS_ROOT(dentry)) parent = NULL; else parent = dentry->d_parent; if (parent && !spin_trylock(&parent->d_lock)) { if (inode) spin_unlock(&inode->i_lock);