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) */
 };
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to