The need to store digital files, documents, pictures, images and other data continues to increase rapidly. In connection with the electronic storage of data, various systems have been devised for the rapid and secure storage of large amounts of data. Such systems may include a number of storage devices that are used in a coordinated fashion. In particular, data can be distributed across multiple storage devices such that data will not be irretrievably lost if one of the storage devices (or in some cases, more than one storage device) fails. An additional advantage that can be achieved by coordinating operation of a number of individual storage devices is improved data access and/or storage times. Examples of systems that can provide such advantages can be found in the various RAID (redundant array of independent disks) levels that have been developed.
Many data storage systems, such as RAID array systems, utilize one or more controllers. Such controllers typically provide a read cache and a write cache to improve the performance of the data storage system with respect to input/output (IO) operations. For example, in connection with write operations, a host can provide data for storage that is initially placed in the write cache of a data system controller. Once the data has been placed in the write cache, the controller indicates to the host that the write operation has been completed, even though the data has not yet been stored on a data storage device or devices. This frees the host to move on to other operations while the controller completes the relatively slow process of storing the data that has been placed in the write cache on the storage device or devices.
In many applications, the availability of data is a key concern. In particular, in many applications, users rely heavily on the data stored in the data storage system. In these types of applications, unavailability of data stored on the data storage system can result in significant loss of revenue and/or customer satisfaction. Employing a data storage system comprising a RAID array can enhance the availability of the stored data, since if a single disk drive fails, data may still be stored and retrieved from the system.
The operation of the data storage system controller (or storage controller) is typically determined through the execution of controller code. In connection with certain storage controllers, multiple copies of controller code can be maintained in storage controller memory. In normal operation, only the code labeled as the primary copy is executed. In order to upgrade code in a typical dual copy storage controller, the primary code that is being replaced is copied from a primary region in memory to a second region in memory. Then, the new, upgraded code is copied to the primary region, thus the new code becomes the primary code. This method of code upgrading works, but it is slow and not robust because it involves a number of time consuming steps and the movement of relatively large amounts of code. In particular, an internal copy of the code from one region to another is required. Because the controller code is typically the size of several megabytes even though the code is compressed, operations copying code from one region and programming it to another region can take many seconds to complete. Furthermore, where there are many pieces of programmable code to copy on the storage controller, it may take many minutes just to complete the copy portion of the upgrade process. The time required becomes even greater in storage controllers that contain more than two sets of controller code. For example, a three copy programmable component, with three regions being labeled as the latest (newest) region, medium region and old region, involves the copy from the medium region to the old region and then from the latest region to the medium region before programming the downloaded code to the latest region. In addition, such methods of code upgrading are error prone because each programmable code component copy operation is an additional step that is subject to failure. The likelihood of such failure increases proportionally with the number of programmable code components the storage controller has and the number of code copies the storage controller maintains. In addition, such methods of code upgrading lack flexibility, as the newly loaded code is always designated as the primary copy or the latest copy designated for execution. Furthermore, the older version of the controller code is always overwritten, leaving the newer copy as the back-up for the downloaded code. This can be undesirable where the newer version of the code has a serious problem. However, storage controllers have been incapable of overwriting any set of code other than the oldest code in connection with downloading upgraded code.