Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jan 2012 23:51:18 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r229248 - stable/9/sys/kern
Message-ID:  <201201012351.q01NpIW2038146@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Jan  1 23:51:18 2012
New Revision: 229248
URL: http://svn.freebsd.org/changeset/base/229248

Log:
  MFC r228306:
  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.

Modified:
  stable/9/sys/kern/sys_pipe.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/sys_pipe.c
==============================================================================
--- stable/9/sys/kern/sys_pipe.c	Sun Jan  1 23:49:11 2012	(r229247)
+++ stable/9/sys/kern/sys_pipe.c	Sun Jan  1 23:51:18 2012	(r229248)
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201012351.q01NpIW2038146>