Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Oct 2011 16:56:06 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226042 - in head/sys: kern sys
Message-ID:  <201110051656.p95Gu6Cw020744@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Oct  5 16:56:06 2011
New Revision: 226042
URL: http://svn.freebsd.org/changeset/base/226042

Log:
  Supply unique (st_dev, st_ino) value pair for the fstat(2) done on the pipes.
  
  Reviewed by:	jhb, Peter Jeremy <peterjeremy acm org>
  MFC after:	2 weeks

Modified:
  head/sys/kern/sys_pipe.c
  head/sys/sys/pipe.h

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c	Wed Oct  5 16:50:15 2011	(r226041)
+++ head/sys/kern/sys_pipe.c	Wed Oct  5 16:56:06 2011	(r226042)
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/conf.h>
 #include <sys/fcntl.h>
 #include <sys/file.h>
 #include <sys/filedesc.h>
@@ -224,6 +225,8 @@ static int	pipe_zone_init(void *mem, int
 static void	pipe_zone_fini(void *mem, int size);
 
 static uma_zone_t pipe_zone;
+static struct unrhdr *pipeino_unr;
+static dev_t pipedev_ino;
 
 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, pipeinit, NULL);
 
@@ -235,6 +238,10 @@ pipeinit(void *dummy __unused)
 	    pipe_zone_ctor, NULL, pipe_zone_init, pipe_zone_fini,
 	    UMA_ALIGN_PTR, 0);
 	KASSERT(pipe_zone != NULL, ("pipe_zone not initialized"));
+	pipeino_unr = new_unrhdr(1, INT32_MAX, NULL);
+	KASSERT(pipeino_unr != NULL, ("pipe fake inodes not initialized"));
+	pipedev_ino = devfs_alloc_cdp_inode();
+	KASSERT(pipedev_ino > 0, ("pipe dev inode not initialized"));
 }
 
 static int
@@ -562,6 +569,12 @@ 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;
+	}
 	return (error);
 }
 
@@ -1408,9 +1421,10 @@ pipe_stat(fp, ub, active_cred, td)
 	ub->st_ctim = pipe->pipe_ctime;
 	ub->st_uid = fp->f_cred->cr_uid;
 	ub->st_gid = fp->f_cred->cr_gid;
+	ub->st_dev = pipedev_ino;
+	ub->st_ino = pipe->pipe_ino;
 	/*
-	 * Left as 0: st_dev, st_ino, st_nlink, st_rdev, st_flags, st_gen.
-	 * XXX (st_dev, st_ino) should be unique.
+	 * Left as 0: st_nlink, st_rdev, st_flags, st_gen.
 	 */
 	return (0);
 }
@@ -1463,6 +1477,7 @@ pipeclose(cpipe)
 {
 	struct pipepair *pp;
 	struct pipe *ppipe;
+	ino_t ino;
 
 	KASSERT(cpipe != NULL, ("pipeclose: cpipe == NULL"));
 
@@ -1521,6 +1536,12 @@ pipeclose(cpipe)
 	knlist_destroy(&cpipe->pipe_sel.si_note);
 
 	/*
+	 * Postpone the destroy of the fake inode number allocated for
+	 * our end, until pipe mtx is unlocked.
+	 */
+	ino = cpipe->pipe_ino;
+
+	/*
 	 * If both endpoints are now closed, release the memory for the
 	 * pipe pair.  If not, unlock.
 	 */
@@ -1532,6 +1553,9 @@ pipeclose(cpipe)
 		uma_zfree(pipe_zone, cpipe->pipe_pair);
 	} else
 		PIPE_UNLOCK(cpipe);
+
+	if (ino > 0)
+		free_unr(pipeino_unr, cpipe->pipe_ino);
 }
 
 /*ARGSUSED*/

Modified: head/sys/sys/pipe.h
==============================================================================
--- head/sys/sys/pipe.h	Wed Oct  5 16:50:15 2011	(r226041)
+++ head/sys/sys/pipe.h	Wed Oct  5 16:56:06 2011	(r226042)
@@ -112,6 +112,7 @@ struct pipe {
 	u_int	pipe_state;		/* pipe status info */
 	int	pipe_busy;		/* busy flag, mostly to handle rundown sanely */
 	int	pipe_present;		/* still present? */
+	ino_t	pipe_ino;		/* fake inode for stat(2) */
 };
 
 /*



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