Most users of pipe(2) do not call fstat(2) on the returned pipe descriptors.

Optimize for the case, by lazily allocating the pipe inode number at the
fstat(2) time. If alloc_unr(9) returns failure, do not fail fstat(2), since
uses of inode numbers are even rare then fstat(2), but provide zero inode
forever. Note that alloc_unr() failure is unlikely due to total number
of pipes in the system limited by the number of file descriptors.

Based on the submission by:	gianni
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2011-12-06 11:24:03 +00:00
parent 2266ba7b12
commit 93c26de0ad
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=228306

View File

@ -569,12 +569,7 @@ pipe_create(pipe, backing)
/* If we're not backing this pipe, no need to do anything. */
error = 0;
}
if (error == 0) {
pipe->pipe_ino = alloc_unr(pipeino_unr);
if (pipe->pipe_ino == -1)
/* pipeclose will clear allocated kva */
error = ENOMEM;
}
pipe->pipe_ino = -1;
return (error);
}
@ -1398,16 +1393,40 @@ pipe_stat(fp, ub, active_cred, td)
struct ucred *active_cred;
struct thread *td;
{
struct pipe *pipe = fp->f_data;
struct pipe *pipe;
int new_unr;
#ifdef MAC
int error;
PIPE_LOCK(pipe);
error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
PIPE_UNLOCK(pipe);
if (error)
return (error);
#endif
pipe = fp->f_data;
PIPE_LOCK(pipe);
#ifdef MAC
error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
if (error) {
PIPE_UNLOCK(pipe);
return (error);
}
#endif
/*
* Lazily allocate an inode number for the pipe. Most pipe
* users do not call fstat(2) on the pipe, which means that
* postponing the inode allocation until it is must be
* returned to userland is useful. If alloc_unr failed,
* assign st_ino zero instead of returning an error.
* Special pipe_ino values:
* -1 - not yet initialized;
* 0 - alloc_unr failed, return 0 as st_ino forever.
*/
if (pipe->pipe_ino == (ino_t)-1) {
new_unr = alloc_unr(pipeino_unr);
if (new_unr != -1)
pipe->pipe_ino = new_unr;
else
pipe->pipe_ino = 0;
}
PIPE_UNLOCK(pipe);
bzero(ub, sizeof(*ub));
ub->st_mode = S_IFIFO;
ub->st_blksize = PAGE_SIZE;