I checked the current version of SD, it is now OK to open two files.
However, one issue I can see in your code, is that you open your two files, and then further down you check "if ( datafile ) ", and then proceed to write into the two files. This code would rely on the conventional assumption that if you had actually failed to open datafile, the value of the File object or pointer or handle or whatever it actually is, would be null and the if ( datafile ) would fail.
The specific problem in your case, is that for some unknown reason, datafile could be good and gpsfile could be bad. For this reason, it would be better to write
if ( datafile )
{ // write stuff to datafile
}
if ( gpsfile )
{ // write stuff to gpsfile
}
The other problem, is where you are getting the values out of the gps object when the various isUpdated() accessor functions are true. What happens when you have received a new GPS string, and all of the parameters are updated ? What will happen, is that you will get your first variables, and then all the else if's after that won't get checked, so the velocity and time and stuff won't get updated. That is probably not the functionality that you intended.