3165 lines · 80.2 KB · C
RawDownload
/* * 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.