[PATCH] don't insert pipe dentries into dentry_hashtable.
We currently insert pipe dentries into the global dentry hashtable.  This
is suboptimal because there is currently no way these entries can be used
for a lookup().  (/proc/xxx/fd/xxx uses a different mechanism).  Inserting
them in dentry hashtable slows dcache lookups.
To let __dpath() still work correctly (ie not adding a " (deleted)") after
dentry name, we do :
 - Right after d_alloc(), pretend they are hashed by clearing the
   DCACHE_UNHASHED bit.
 - Call d_instantiate() instead of d_add() : dentry is not inserted in
   hash table.
__dpath() & friends work as intended during dentry lifetime.
 - At dismantle time, once dput() must clear the dentry, setting again
   DCACHE_UNHASHED bit inside the custom d_delete() function provided by
   pipe code, so that dput() can just kill_it.
This patch, combined with (avoid RCU for never hashed dentries) reduced
time of { pipe(p); close(p[0]); close(p[1]);} on my UP machine (1.6GHz
Pentium-M) from 3.23 us to 2.86 us (But this patch does not depend on other
patches, only bench results)
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Acked-by: David Miller <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
			
			
This commit is contained in:
		
							parent
							
								
									1c69d921ed
								
							
						
					
					
						commit
						d18de5a272
					
				
							
								
								
									
										22
									
								
								fs/pipe.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								fs/pipe.c
									
									
									
									
									
								
							| @ -830,7 +830,14 @@ void free_pipe_info(struct inode *inode) | ||||
| static struct vfsmount *pipe_mnt __read_mostly; | ||||
| static int pipefs_delete_dentry(struct dentry *dentry) | ||||
| { | ||||
| 	return 1; | ||||
| 	/*
 | ||||
| 	 * At creation time, we pretended this dentry was hashed | ||||
| 	 * (by clearing DCACHE_UNHASHED bit in d_flags) | ||||
| 	 * At delete time, we restore the truth : not hashed. | ||||
| 	 * (so that dput() can proceed correctly) | ||||
| 	 */ | ||||
| 	dentry->d_flags |= DCACHE_UNHASHED; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct dentry_operations pipefs_dentry_operations = { | ||||
| @ -891,17 +898,22 @@ struct file *create_write_pipe(void) | ||||
| 	if (!inode) | ||||
| 		goto err_file; | ||||
| 
 | ||||
| 	sprintf(name, "[%lu]", inode->i_ino); | ||||
| 	this.len = sprintf(name, "[%lu]", inode->i_ino); | ||||
| 	this.name = name; | ||||
| 	this.len = strlen(name); | ||||
| 	this.hash = inode->i_ino; /* will go */ | ||||
| 	this.hash = 0; | ||||
| 	err = -ENOMEM; | ||||
| 	dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | ||||
| 	if (!dentry) | ||||
| 		goto err_inode; | ||||
| 
 | ||||
| 	dentry->d_op = &pipefs_dentry_operations; | ||||
| 	d_add(dentry, inode); | ||||
| 	/*
 | ||||
| 	 * We dont want to publish this dentry into global dentry hash table. | ||||
| 	 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED | ||||
| 	 * This permits a working /proc/$pid/fd/XXX on pipes | ||||
| 	 */ | ||||
| 	dentry->d_flags &= ~DCACHE_UNHASHED; | ||||
| 	d_instantiate(dentry, inode); | ||||
| 	f->f_vfsmnt = mntget(pipe_mnt); | ||||
| 	f->f_dentry = dentry; | ||||
| 	f->f_mapping = inode->i_mapping; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user