svn commit: r324812 - stable/11/sys/net
Andriy Voskoboinyk
avos at FreeBSD.org
Sat Oct 21 10:21:35 UTC 2017
Author: avos
Date: Sat Oct 21 10:21:34 2017
New Revision: 324812
URL: https://svnweb.freebsd.org/changeset/base/324812
Log:
MFC r324672:
ifnet(9): split ifc_alloc_unit() (should simplify code flow)
Allocate smallest unit number from pool via ifc_alloc_unit_next()
and exact unit number (if available) via ifc_alloc_unit_specific().
While here, address possible deadlock (mentioned in PR).
PR: 217401
Differential Revision: https://reviews.freebsd.org/D12551
Modified:
stable/11/sys/net/if_clone.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/net/if_clone.c
==============================================================================
--- stable/11/sys/net/if_clone.c Sat Oct 21 07:23:45 2017 (r324811)
+++ stable/11/sys/net/if_clone.c Sat Oct 21 10:21:34 2017 (r324812)
@@ -595,44 +595,56 @@ ifc_name2unit(const char *name, int *unit)
return (0);
}
-int
-ifc_alloc_unit(struct if_clone *ifc, int *unit)
+static int
+ifc_alloc_unit_specific(struct if_clone *ifc, int *unit)
{
char name[IFNAMSIZ];
- int wildcard;
- wildcard = (*unit < 0);
-retry:
if (*unit > ifc->ifc_maxunit)
return (ENOSPC);
- if (*unit < 0) {
- *unit = alloc_unr(ifc->ifc_unrhdr);
- if (*unit == -1)
- return (ENOSPC);
- } else {
- *unit = alloc_unr_specific(ifc->ifc_unrhdr, *unit);
- if (*unit == -1) {
- if (wildcard) {
- (*unit)++;
- goto retry;
- } else
- return (EEXIST);
- }
- }
+ if (alloc_unr_specific(ifc->ifc_unrhdr, *unit) == -1)
+ return (EEXIST);
+
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, *unit);
if (ifunit(name) != NULL) {
free_unr(ifc->ifc_unrhdr, *unit);
- if (wildcard) {
- (*unit)++;
- goto retry;
- } else
- return (EEXIST);
+ return (EEXIST);
}
IF_CLONE_ADDREF(ifc);
return (0);
+}
+
+static int
+ifc_alloc_unit_next(struct if_clone *ifc, int *unit)
+{
+ int error;
+
+ *unit = alloc_unr(ifc->ifc_unrhdr);
+ if (*unit == -1)
+ return (ENOSPC);
+
+ free_unr(ifc->ifc_unrhdr, *unit);
+ for (;;) {
+ error = ifc_alloc_unit_specific(ifc, unit);
+ if (error != EEXIST)
+ break;
+
+ (*unit)++;
+ }
+
+ return (error);
+}
+
+int
+ifc_alloc_unit(struct if_clone *ifc, int *unit)
+{
+ if (*unit < 0)
+ return (ifc_alloc_unit_next(ifc, unit));
+ else
+ return (ifc_alloc_unit_specific(ifc, unit));
}
void
More information about the svn-src-all
mailing list