Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Sep 2012 17:46:23 +0200
From:      =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To:        hackers@freebsd.org
Subject:   fdgrowtable() cleanup
Message-ID:  <86wqzr8hbk.fsf@ds4.des.no>

next in thread | raw e-mail | index | archive | help
The patch below my signature improves the legibility of fdgrowtable(),
and adds comments explaining the hairier bits.  The only functional
change is that the code no longer overwrites the old fileflags array
when the old table is placed on the freelist; instead, it uses the space
actually set aside for that purpose.

(I assume that the old behavior was harmless, since it has persisted for
decades, but it was certainly confusing.)

The slightly repetitive nature of the new code is intentional.

DES
--=20
Dag-Erling Sm=C3=B8rgrav - des@des.no

Index: sys/kern/kern_descrip.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/kern/kern_descrip.c	(revision 240654)
+++ sys/kern/kern_descrip.c	(working copy)
@@ -148,11 +148,6 @@
 #define	NDSLOTS(x)	(((x) + NDENTRIES - 1) / NDENTRIES)
=20
 /*
- * Storage required per open file descriptor.
- */
-#define OFILESIZE (sizeof(struct file *) + sizeof(char))
-
-/*
  * Storage to hold unused ofiles that need to be reclaimed.
  */
 struct freetable {
@@ -1436,7 +1431,7 @@
 	struct freetable *fo;
 	struct file **ntable;
 	struct file **otable;
-	char *nfileflags;
+	char *nfileflags, *ofileflags;
 	int nnfiles, onfiles;
 	NDSLOTTYPE *nmap;
=20
@@ -1447,33 +1442,46 @@
=20
 	/* compute the size of the new table */
 	onfiles =3D fdp->fd_nfiles;
+	otable =3D fdp->fd_ofiles;
+	ofileflags =3D fdp->fd_ofileflags;
 	nnfiles =3D NDSLOTS(nfd) * NDENTRIES; /* round up */
 	if (nnfiles <=3D onfiles)
 		/* the table is already large enough */
 		return;
=20
-	/* allocate a new table and (if required) new bitmaps */
-	ntable =3D malloc((nnfiles * OFILESIZE) + sizeof(struct freetable),
+	/*
+	 * Allocate a new table.  We need enough space for a) the file
+	 * entries themselves, b) the file flags, and c) the struct
+	 * freetable we will use when we decommission the table and place
+	 * it on the freelist.
+	 */
+	ntable =3D malloc(nnfiles * sizeof(*ntable) +
+	    nnfiles * sizeof(*nfileflags) +
+	    sizeof(struct freetable),
 	    M_FILEDESC, M_ZERO | M_WAITOK);
 	nfileflags =3D (char *)&ntable[nnfiles];
+
+	/* allocate new bitmaps if necessary */
 	if (NDSLOTS(nnfiles) > NDSLOTS(onfiles))
 		nmap =3D malloc(NDSLOTS(nnfiles) * NDSLOTSIZE,
 		    M_FILEDESC, M_ZERO | M_WAITOK);
 	else
 		nmap =3D NULL;
=20
-	bcopy(fdp->fd_ofiles, ntable, onfiles * sizeof(*ntable));
-	bcopy(fdp->fd_ofileflags, nfileflags, onfiles);
-	otable =3D fdp->fd_ofiles;
+	/* copy the old data over and point at the new tables */
+	bcopy(otable, ntable, onfiles * sizeof(*otable));
+	bcopy(ofileflags, nfileflags, onfiles * sizeof(*ofileflags));
 	fdp->fd_ofileflags =3D nfileflags;
 	fdp->fd_ofiles =3D ntable;
+
 	/*
 	 * We must preserve ofiles until the process exits because we can't
 	 * be certain that no threads have references to the old table via
 	 * _fget().
 	 */
 	if (onfiles > NDFILE) {
-		fo =3D (struct freetable *)&otable[onfiles];
+		fo =3D (struct freetable *)(char *)otable +
+		    onfiles * sizeof(*otable) + onfiles * sizeof(*ofileflags);
 		fdp0 =3D (struct filedesc0 *)fdp;
 		fo->ft_table =3D otable;
 		SLIST_INSERT_HEAD(&fdp0->fd_free, fo, ft_next);



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