forked from mirrors/linux
		
	namei: teach lookup_slow() to skip revalidate
... and make mountpoint_last() use it. That makes all candidates for lookup with parent locked shared go through lookup_slow(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									e3c1392808
								
							
						
					
					
						commit
						949a852e46
					
				
					 2 changed files with 36 additions and 23 deletions
				
			
		
							
								
								
									
										50
									
								
								fs/namei.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								fs/namei.c
									
									
									
									
									
								
							|  | @ -1605,7 +1605,29 @@ static struct dentry *lookup_slow(const struct qstr *name, | ||||||
| { | { | ||||||
| 	struct dentry *dentry; | 	struct dentry *dentry; | ||||||
| 	inode_lock(dir->d_inode); | 	inode_lock(dir->d_inode); | ||||||
| 	dentry = __lookup_hash(name, dir, flags); | 	dentry = d_lookup(dir, name); | ||||||
|  | 	if (unlikely(dentry)) { | ||||||
|  | 		if ((dentry->d_flags & DCACHE_OP_REVALIDATE) && | ||||||
|  | 		    !(flags & LOOKUP_NO_REVAL)) { | ||||||
|  | 			int error = d_revalidate(dentry, flags); | ||||||
|  | 			if (unlikely(error <= 0)) { | ||||||
|  | 				if (!error) | ||||||
|  | 					d_invalidate(dentry); | ||||||
|  | 				dput(dentry); | ||||||
|  | 				dentry = ERR_PTR(error); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if (dentry) { | ||||||
|  | 			inode_unlock(dir->d_inode); | ||||||
|  | 			return dentry; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	dentry = d_alloc(dir, name); | ||||||
|  | 	if (unlikely(!dentry)) { | ||||||
|  | 		inode_unlock(dir->d_inode); | ||||||
|  | 		return ERR_PTR(-ENOMEM); | ||||||
|  | 	} | ||||||
|  | 	dentry = lookup_real(dir->d_inode, dentry, flags); | ||||||
| 	inode_unlock(dir->d_inode); | 	inode_unlock(dir->d_inode); | ||||||
| 	return dentry; | 	return dentry; | ||||||
| } | } | ||||||
|  | @ -2425,31 +2447,21 @@ mountpoint_last(struct nameidata *nd, struct path *path) | ||||||
| 		if (error) | 		if (error) | ||||||
| 			return error; | 			return error; | ||||||
| 		dentry = dget(nd->path.dentry); | 		dentry = dget(nd->path.dentry); | ||||||
| 		goto done; | 	} else { | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	inode_lock(dir->d_inode); |  | ||||||
| 		dentry = d_lookup(dir, &nd->last); | 		dentry = d_lookup(dir, &nd->last); | ||||||
| 		if (!dentry) { | 		if (!dentry) { | ||||||
| 			/*
 | 			/*
 | ||||||
| 		 * No cached dentry. Mounted dentries are pinned in the cache, | 			 * No cached dentry. Mounted dentries are pinned in the | ||||||
| 		 * so that means that this dentry is probably a symlink or the | 			 * cache, so that means that this dentry is probably | ||||||
| 		 * path doesn't actually point to a mounted dentry. | 			 * a symlink or the path doesn't actually point | ||||||
|  | 			 * to a mounted dentry. | ||||||
| 			 */ | 			 */ | ||||||
| 		dentry = d_alloc(dir, &nd->last); | 			dentry = lookup_slow(&nd->last, dir, | ||||||
| 		if (!dentry) { | 					     nd->flags | LOOKUP_NO_REVAL); | ||||||
| 			inode_unlock(dir->d_inode); | 			if (IS_ERR(dentry)) | ||||||
| 			return -ENOMEM; |  | ||||||
| 		} |  | ||||||
| 		dentry = lookup_real(dir->d_inode, dentry, nd->flags); |  | ||||||
| 		if (IS_ERR(dentry)) { |  | ||||||
| 			inode_unlock(dir->d_inode); |  | ||||||
| 				return PTR_ERR(dentry); | 				return PTR_ERR(dentry); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	inode_unlock(dir->d_inode); |  | ||||||
| 
 |  | ||||||
| done: |  | ||||||
| 	if (d_is_negative(dentry)) { | 	if (d_is_negative(dentry)) { | ||||||
| 		dput(dentry); | 		dput(dentry); | ||||||
| 		return -ENOENT; | 		return -ENOENT; | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; | ||||||
| #define LOOKUP_PARENT		0x0010 | #define LOOKUP_PARENT		0x0010 | ||||||
| #define LOOKUP_REVAL		0x0020 | #define LOOKUP_REVAL		0x0020 | ||||||
| #define LOOKUP_RCU		0x0040 | #define LOOKUP_RCU		0x0040 | ||||||
|  | #define LOOKUP_NO_REVAL		0x0080 | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Intent data |  * Intent data | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro