diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-11 23:20:37 -0500 | 
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-26 02:46:07 -0500 | 
| commit | 4f522a247bc26d4ab5c8fc406ffffa8b3a77abe3 (patch) | |
| tree | ed3ca7fb7316f96e7aab23f9563523521bed3259 | |
| parent | 3592ac444017996f5a8ecf85856af0a8938e8fd1 (diff) | |
| download | olio-linux-3.10-4f522a247bc26d4ab5c8fc406ffffa8b3a77abe3.tar.xz olio-linux-3.10-4f522a247bc26d4ab5c8fc406ffffa8b3a77abe3.zip  | |
d_hash_and_lookup(): export, switch open-coded instances
* calling conventions change - ERR_PTR() is returned on ->d_hash() errors;
NULL is just for dcache miss now.
* exported, open-coded instances in ncpfs and cifs converted.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/cifs/readdir.c | 8 | ||||
| -rw-r--r-- | fs/dcache.c | 23 | ||||
| -rw-r--r-- | fs/ncpfs/dir.c | 10 | ||||
| -rw-r--r-- | fs/proc/base.c | 1 | 
4 files changed, 18 insertions, 24 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 7255b0c7aa7..df40cc5fd13 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -82,12 +82,10 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,  	cFYI(1, "%s: for %s", __func__, name->name); -	if (parent->d_op && parent->d_op->d_hash) -		parent->d_op->d_hash(parent, parent->d_inode, name); -	else -		name->hash = full_name_hash(name->name, name->len); +	dentry = d_hash_and_lookup(parent, name); +	if (unlikely(IS_ERR(dentry))) +		return; -	dentry = d_lookup(parent, name);  	if (dentry) {  		int err; diff --git a/fs/dcache.c b/fs/dcache.c index ada6123414a..ebab049826c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1672,7 +1672,6 @@ EXPORT_SYMBOL(d_splice_alias);  struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,  			struct qstr *name)  { -	int error;  	struct dentry *found;  	struct dentry *new; @@ -1681,10 +1680,12 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,  	 * if not go ahead and create it now.  	 */  	found = d_hash_and_lookup(dentry->d_parent, name); +	if (unlikely(IS_ERR(found))) +		goto err_out;  	if (!found) {  		new = d_alloc(dentry->d_parent, name);  		if (!new) { -			error = -ENOMEM; +			found = ERR_PTR(-ENOMEM);  			goto err_out;  		} @@ -1725,7 +1726,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,  err_out:  	iput(inode); -	return ERR_PTR(error); +	return found;  }  EXPORT_SYMBOL(d_add_ci); @@ -1997,12 +1998,10 @@ next:   * @dir: Directory to search in   * @name: qstr of name we wish to find   * - * On hash failure or on lookup failure NULL is returned. + * On lookup failure NULL is returned; on bad name - ERR_PTR(-error)   */  struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)  { -	struct dentry *dentry = NULL; -  	/*  	 * Check for a fs-specific hash function. Note that we must  	 * calculate the standard hash first, as the d_op->d_hash() @@ -2010,13 +2009,13 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)  	 */  	name->hash = full_name_hash(name->name, name->len);  	if (dir->d_flags & DCACHE_OP_HASH) { -		if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0) -			goto out; +		int err = dir->d_op->d_hash(dir, dir->d_inode, name); +		if (unlikely(err < 0)) +			return ERR_PTR(err);  	} -	dentry = d_lookup(dir, name); -out: -	return dentry; +	return d_lookup(dir, name);  } +EXPORT_SYMBOL(d_hash_and_lookup);  /**   * d_validate - verify dentry provided from insecure source (deprecated) @@ -2995,7 +2994,7 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)  	ino_t ino = 0;  	dentry = d_hash_and_lookup(dir, name); -	if (dentry) { +	if (!IS_ERR_OR_NULL(dentry)) {  		if (dentry->d_inode)  			ino = dentry->d_inode->i_ino;  		dput(dentry); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 4117e7b377b..81632609365 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -593,14 +593,10 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,  		return 1; /* I'm not sure */  	qname.name = __name; -	qname.hash = full_name_hash(qname.name, qname.len); - -	if (dentry->d_op && dentry->d_op->d_hash) -		if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0) -			goto end_advance; - -	newdent = d_lookup(dentry, &qname); +	newdent = d_hash_and_lookup(dentry, &qname); +	if (unlikely(IS_ERR(newdent))) +		goto end_advance;  	if (!newdent) {  		newdent = d_alloc(dentry, &qname);  		if (!newdent) diff --git a/fs/proc/base.c b/fs/proc/base.c index 760268d6cba..9d962555972 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2618,6 +2618,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)  	name.name = buf;  	name.len = snprintf(buf, sizeof(buf), "%d", pid); +	/* no ->d_hash() rejects on procfs */  	dentry = d_hash_and_lookup(mnt->mnt_root, &name);  	if (dentry) {  		shrink_dcache_parent(dentry);  |