From 48be9abd5b0caf0a915d6f5bc22d431f3e09a81c Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 7 Jan 2013 10:34:43 +1100
Subject: [PATCH 2/3] platform-intel - cache 'intel_devices' for a few
 seconds.

find_intel_devices() has take a little while to run as it scans
some directory tree, and the result isn't likely to change
often.
So cache the value and only discard it after 5 seconds.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 platform-intel.c |   23 ++++++++++++-----------
 platform-intel.h |    1 -
 super-intel.c    |   29 +++++------------------------
 3 files changed, 17 insertions(+), 36 deletions(-)

--- mdadm-3.2.6.orig/platform-intel.c
+++ mdadm-3.2.6/platform-intel.c
@@ -36,7 +36,7 @@ static int devpath_to_ll(const char *dev
 
 static __u16 devpath_to_vendor(const char *dev_path);
 
-void free_sys_dev(struct sys_dev **list)
+static void free_sys_dev(struct sys_dev **list)
 {
 	while (*list) {
 		struct sys_dev *next = (*list)->next;
@@ -127,6 +127,7 @@ struct sys_dev *find_driver_devices(cons
 
 
 static struct sys_dev *intel_devices=NULL;
+static time_t valid_time = 0;
 
 static enum sys_dev_type device_type_by_id(__u16 device_id)
 {
@@ -183,6 +184,12 @@ struct sys_dev *find_intel_devices(void)
 {
 	struct sys_dev *ahci, *isci;
 
+	if (valid_time > time(0) - 10)
+		return intel_devices;
+
+	if (intel_devices)
+		free_sys_dev(&intel_devices);
+
 	isci = find_driver_devices("pci", "isci");
 	ahci = find_driver_devices("pci", "ahci");
 
@@ -194,7 +201,9 @@ struct sys_dev *find_intel_devices(void)
 			elem = elem->next;
 		elem->next = isci;
 	}
-	return ahci;
+	intel_devices = ahci;
+	valid_time = time(0);
+	return intel_devices;
 }
 
 /*
@@ -305,11 +314,7 @@ static const struct imsm_orom *find_imsm
 	    check_env("IMSM_TEST_SCU_EFI"))
 		return NULL;
 
-
-	if (intel_devices != NULL)
-		free_sys_dev(&intel_devices);
-
-	intel_devices = find_intel_devices();
+	find_intel_devices();
 
 	if (intel_devices == NULL)
 		return NULL;
@@ -326,10 +331,6 @@ static const struct imsm_orom *find_imsm
 	scan_adapter_roms(scan);
 	probe_roms_exit();
 
-	if (intel_devices != NULL)
-		free_sys_dev(&intel_devices);
-	intel_devices = NULL;
-
 	if (populated_orom[hba_id])
 		return &imsm_orom[hba_id];
 	return NULL;
--- mdadm-3.2.6.orig/platform-intel.h
+++ mdadm-3.2.6/platform-intel.h
@@ -202,7 +202,6 @@ static inline char *guid_str(char *buf,
 char *diskfd_to_devpath(int fd);
 struct sys_dev *find_driver_devices(const char *bus, const char *driver);
 struct sys_dev *find_intel_devices(void);
-void free_sys_dev(struct sys_dev **list);
 const struct imsm_orom *find_imsm_capability(enum sys_dev_type hba_id);
 const struct imsm_orom *find_imsm_orom(void);
 int disk_attached_to_hba(int fd, const char *hba_path);
--- mdadm-3.2.6.orig/super-intel.c
+++ mdadm-3.2.6/super-intel.c
@@ -567,7 +567,7 @@ static int attach_hba_to_super(struct in
 
 static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
 {
-	struct sys_dev *list, *elem, *prev;
+	struct sys_dev *list, *elem;
 	char *disk_path;
 
 	if ((list = find_intel_devices()) == NULL)
@@ -578,27 +578,15 @@ static struct sys_dev* find_disk_attache
 	else
 		disk_path = diskfd_to_devpath(fd);
 
-	if (!disk_path) {
-		free_sys_dev(&list);
+	if (!disk_path)
 		return 0;
-	}
 
-	for (prev = NULL, elem = list; elem; prev = elem, elem = elem->next) {
-		if (path_attached_to_hba(disk_path, elem->path)) {
-			if (prev == NULL)
-				list = list->next;
-			else
-				prev->next = elem->next;
-			elem->next = NULL;
-			if (disk_path != devname)
-				free(disk_path);
-			free_sys_dev(&list);
+	for (elem = list; elem; elem = elem->next)
+		if (path_attached_to_hba(disk_path, elem->path))
 			return elem;
-		}
-	}
+
 	if (disk_path != devname)
 		free(disk_path);
-	free_sys_dev(&list);
 
 	return NULL;
 }
@@ -1826,7 +1814,6 @@ static int detail_platform_imsm(int verb
 				break;
 			}
 		}
-		free_sys_dev(&list);
 		return result;
 	}
 
@@ -1835,7 +1822,6 @@ static int detail_platform_imsm(int verb
 		if (verbose)
 			fprintf(stderr, Name ": no active Intel(R) RAID "
 				"controller found.\n");
-		free_sys_dev(&list);
 		return 2;
 	} else if (verbose)
 		print_found_intel_controllers(list);
@@ -1864,7 +1850,6 @@ static int detail_platform_imsm(int verb
 		}
 	}
 
-	free_sys_dev(&list);
 	return result;
 }
 #endif
@@ -3794,11 +3779,9 @@ static int find_intel_hba_capability(int
 				"    Mixing devices attached to multiple controllers "
 				"is not allowed.\n");
 		}
-		free_sys_dev(&hba_name);
 		return 2;
 	}
 	super->orom = find_imsm_capability(hba_name->type);
-	free_sys_dev(&hba_name);
 	if (!super->orom)
 		return 3;
 	return 0;
@@ -9494,8 +9477,6 @@ static const char *imsm_get_disk_control
 		dprintf("path: %s hba: %s attached: %s\n",
 			path, (hba) ? hba->path : "NULL", drv);
 		free(path);
-		if (hba)
-			free_sys_dev(&hba);
 	}
 	return drv;
 }
