AnsweredAssumed Answered

_io_part_mgr_write fails on large sector

Question asked by Adrian Rockall on May 31, 2017
Latest reply on Apr 3, 2018 by Adrian Rockall

I am using KSDK 1.3.0 with MQX on the MK66 processor.

Problem 1:

I have found a problem where after a period of time of writing data to an SD card it would become unavailable. It would mount but any read / write / list would fail. I have tracked this down to a problem with the _io_part_mgr_write function. It calls lseek, which returns the selected sector as a int64_t value, but puts the result into a int32_t variable and then checks if the result is greater than or equal to 0 before writing the data. The problem is when the returned sector number is greater than a int32_t can hold it wraps around to be a negative number so the check fails, even though the seek was successful.

I have now changed the call to put the result back in to the location variable then check that. I can now continue to use cards that had previously become "corrupted".

Snippet from _io_part_mgr_write in part_mgr.c

// Adria Rockall:- return is a sector so put into location which is a int64_t else we get overflow
//    result = lseek(pm_struct_ptr->DEV_FILE_PTR, location, SEEK_SET);
    location = lseek(pm_struct_ptr->DEV_FILE_PTR, location, SEEK_SET);
    if (location >= 0)
    {
        result = write(pm_struct_ptr->DEV_FILE_PTR, data_ptr, num);
    }
else // Adrian Rockall:- return -1 if the seek fails
{
  errno = MFS_ERROR_SEEK;
  if (error)
  {
   *error = MFS_ERROR_SEEK;
  }
  result = -1;
}

 

Problem 2:

It appears the function has also been updated at some point to take a pointer to an error variable to pass back the error code. However the function itself still puts the error codes in the global errno variable at not in the passed in variable. As the calling function does not initialise the variable that it passes in and copies the value to errno if a failure is detected it results in a completely random error code being reported back to the calling functions. I have now changed the declarations of the error variables in all the calling functions to ensure they are initialised to 0, plus added code, like that shown in lines 11 to 14 above, to all places where errno is set.

 

Hope this helps anyone having this problem.

Adrian.

Outcomes