a storage area network has a first compute node 100 that has a link 102 to a first switch or hub 104 . the first switch or hub 104 also has a link 106 to a first storage node 108 , and a link 110 to a second storage node 112 . a path therefore exists from the first compute node 100 through the first switch 104 to each of the first storage node 108 and second storage node 112 . similarly , the network has a second compute node 120 that has a link 122 to the first switch or hub 104 and a link 124 to a second switch or hub 126 . the second switch or hub 126 also has a link 128 to the first storage node 108 , and a link 130 to the second storage node 112 . a path therefore exists from the second compute node 120 through the second switch 126 to each of the first storage node 108 and second storage node 112 . a dataset is mirrored , such that a first copy 131 of the dataset is maintained on the first storage node 108 , and a second copy 132 maintained on the second storage node 112 . this dataset is in use by the first compute node 100 , and may also be in use by other nodes of the san . at least one path exists through the network for communication between the first compute node 100 and the second compute node 120 . in this example network , a path exists from first compute node 100 , link 102 , switch 104 , link 172 to , second compute node 120 . the particular network configuration of fig1 is by way of example to illustrate the utility and operation of the invention and not by way of limitation . many other network configurations are possible that may benefit from the invention . some network configurations that may benefit from the invention may themselves result from failure or overload of network components . when compute node 100 reads from the dataset , it may read from either the first dataset copy 131 or the second dataset copy 132 . when compute node 100 writes to the dataset , it must write to both the first dataset copy 131 and the second dataset copy 132 if synchronization of the datasets is to be maintained . consider failure of link 106 between the first switch or hub 104 and the first storage node 108 . in this event , the path from first compute node 100 through switch 104 to first storage node 108 and the first dataset copy 131 will also fail . since the path from first compute node 100 through switch 104 to second storage node 112 and the second dataset copy 132 is still operational , first compute node 100 can continue to read the dataset by reading the second copy 132 . since the path to the first dataset copy 131 has failed , compute node 100 can not ordinarily write to first dataset copy 131 , which may result in loss of synchronization of the dataset copies . in many sans , the compute nodes , such as first compute node 100 and second compute node 120 , are in communication with each other . in the example of fig1 , first compute node 100 may communicate with second compute node 120 through first switch 104 by way of links 102 and 122 . in the example network configuration , first compute node 100 may also communicate with second compute node 120 through network hardware separate from the san , such as an ethernet or other local area network 136 . with only link 106 failed , second compute node 120 still has a path through links 124 and 128 , and switch 126 , to the first storage node 108 and the first dataset copy 131 . in a network embodying the present invention , when first compute node 100 can not reach first storage node 108 , second compute node 120 can reach first storage node 108 , and first compute node 100 can reach second compute node 120 ; the second compute node 120 performs surrogate write operations in behalf of first compute node 100 . this permits maintenance of synchronization between the first copy 131 and the second copy 132 of the dataset . surrogate read or write operations may also be performed to non - mirrored datasets , provided that a path exists from the compute node desiring the read or write to a compute node having a path to the destination device . each compute node maintains a list of paths to storage nodes . this list includes status of the paths . it is known that path status can change to failed should a problem occur with a link , switch , or other network device . when surrogate writes are enabled and a compute node desires to write a dataset 200 ( fig2 ), that node checks 202 the path status to the storage node on which the dataset is stored . if that path has a status of “ path ok ” 204 , a write is attempted 206 to the dataset on that node . if the write succeeds , all is well . if the write fails 208 for reasons that are likely to be a result of a failed path to the storage node , such as a fibre channel timeout error , the node looks for a path 210 to a second compute node , and verifies that that path has a status of “ path ok ”. if that path has status indicating it is failed , the node looks 212 and 214 for any other compute nodes to which it might have a good path . if no such path is found , the write is declared 215 to have failed . once a compute node is identified to which there is a good path , a query is sent 216 to that compute node asking if it has a valid path to the storage node on which the dataset is stored . if that query fails 218 for reasons that are likely to be a result of a failed path to the node , such as a fibre channel timeout error , the node looks 212 and 214 for any other compute nodes to which it might have a good path . if the second compute node reports that it has no “ ok ” path 220 to the target storage node , the node looks 212 and 214 for other compute nodes that might have a path to the target storage node . if the second compute node reports that it has an “ ok ” path to that target node , the node encapsulates 222 a write request into suitable frames and transmits those frames to the second compute node . the second compute node then relays that write request to the target node and relays any reply back to the compute node desirous of the write . if the write occurs correctly 224 , the compute node continues to process data . if the write is reported as having failed or timed out , the write is declared failed 215 and suitable error routines invoked . writes to a mirrored data set are handled similarly . when a write request occurs 300 , the source node checks its path status 302 to both storage nodes having copies of the dataset . if both paths have good status 304 , writes occur in the normal manner 306 . if either write fails 308 for reasons , such as timeout , that could be related to a bad path , a check 310 is made to determine if both failed or if only one failed . if both write attempts failed , a both - paths failed routine is invoked ( not shown ). if , when the path status was checked 302 to both storage nodes , one path was broken and the other was ok , a write is generated 312 to the storage node that can be reached . if that write fails for timeout or other reasons that could be related to a bad path , the both - paths failed routine is invoked ( not shown ). if that write succeeds , the source node checks 314 for an ok path to a compute node . if the compute node first tried has no valid path , the source node searches 316 and 318 for a compute node to which it has a valid path . if no compute node to which there is a valid path can be found , the mirror set is declared broken 320 ; such that when paths are restored an attempt will be made to re - synchronize the mirror set . once a valid path is found to a compute node , a query is made 322 of that compute node to determine if it has a valid path to the target storage node and to determine if that node supports surrogate writes . if that query results in a reply indicating that surrogate writes are not supported or that there is no valid path 326 , or the query times out or fails for other reasons indicative of a failed path 324 , the source node may continue to search 316 and 318 for another compute node that has a valid path and supports surrogate writes . if the compute node reports that it has a valid path and supports surrogate writes , the source node encapsulates a write request into suitable frames , and transmits 328 those frames to the compute node . that node then relays the write request to the target node , and relays any reply from the target node to the source node . any reply from the target node is inspected to determine 330 if the write succeeded . if the write was not successful , the mirror set is reported broken 320 . it is anticipated that the present invention can be implemented in driver software of a compute node , or alternatively can be implemented in firmware of an hba , such as a dual - port hba . a dual port host bus adapter ( hba ) ( fig4 ) typically has a port processor 400 , a memory system 402 for storing frames , a dma ( direct memory access ) transfer system 404 and other hardware for communicating with its host ( not shown ), and first 406 and second 408 serializer and deserializer hardware . each set of serializer and deserializer hardware is coupled to a network transmitter 410 and 412 , and to a network receiver 414 and 416 . a dual - port hba like that illustrated in fig4 implements the connection of second compute node 120 ( fig1 ) to links 122 and 124 . a second , similar , hba implements the connection of first compute node 100 to link 102 . each hba is capable of maintaining a mirror set under control of firmware located in its memory system 402 and running on its port processor 400 , and of implementing the method of requesting surrogate writes previously described . whenever the dual - port hba receives frames 500 ( fig5 ), the frames are inspected 502 to determine the frame type . if they are path query frames 504 from a source node , as sent in steps 322 ( fig3 ) or 216 ( fig2 ) as previously described , the status of any path to the target node is determined 506 , and checked 508 . if a valid path exists , a reply frame is constructed 510 by the port processor 400 indicating that surrogate writes are supported and that the path is ok , otherwise a frame is constructed 512 indicating that the path does not exist or is not ok . this constructed frame is sent 514 to the source node . if the frame was not a path query , the frame is checked 520 to see if it encapsulates a write request . if it does , the write request is de - encapsulated and forwarded 522 to the target node . if the frame does not encapsulate a write request , it is checked 526 to see if it is a response to a forwarded write request . if it is such a response , the write status is relayed 528 to the source node . while the invention has been particularly shown and described with reference to a preferred embodiment thereof , it will be understood by those skilled in the art that various other changes in the form and details may be made without departing from the spirit and scope of the invention .