svn commit: r228306 - head/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Tue Dec 6 11:24:04 UTC 2011
Author: kib
Date: Tue Dec 6 11:24:03 2011
New Revision: 228306
URL: http://svn.freebsd.org/changeset/base/228306
Log:
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
Modified:
head/sys/kern/sys_pipe.c
Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c Tue Dec 6 09:12:11 2011 (r228305)
+++ head/sys/kern/sys_pipe.c Tue Dec 6 11:24:03 2011 (r228306)
@@ -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;
+#endif
+ pipe = fp->f_data;
PIPE_LOCK(pipe);
+#ifdef MAC
error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
- PIPE_UNLOCK(pipe);
- if (error)
+ 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;
More information about the svn-src-head
mailing list