Hi, this is actually a Ticket, the good new is that is already pre-analyzed
and probably also the cause has been found.
I hope this is the right place to put this

TITLE: Wrong ERROR_DISK_FULL writing a blob on Windows

DESCRIPTION:

    Having a sqlite database about 4.1 GB
    writing blobs in some table, for instance using a statement like
       INSERT INTO inodeCargo VALUES (1000, readfile ("ScreenShot.png"));

    an error ERROR_DISK_FULL can be through wrongly (under certain 
conditions)

    Windows 7 64-bit

REPRODUCIBLE:
    When the conditions are met, always reproducible


CAUSE :

    windows function WriteFile return error 112 (ERROR_DISK_FULL) when 
trying to write
    1024 bytes using a offset = 4294966272 = 0xFFFFFC00 = FFFFFFFF - 2023

    This was observed using the default mode (OVERLAPPED) although a 
test compiling
    the code with
       #define SQLITE_WIN32_NO_OVERLAPPED
    at the begining also failed.

PATCH:

    The patch (see sqlite3_modified.c) work in my case, but obviously cannot
    fix the mode NO_OVERLAPPED (it does not compile in this mode). Also 
all procedures
    using the buggy function (if this result to be the cause) should be 
reviewed.
    A more precise fix has to be developed by some expert in sqlite code.

ANALYSIS:

    A sqlite db used to store files came in the conditions described
    size of database file : 4.194.303 KB
    size of journal file : 8 KB
    size of the image (png file) : 4.417 KB

    SQL Query returning systematically ERROR_DISK_FULL:
       INSERT INTO inodeCargo VALUES (-24, 4522876, 0, readfile 
("ScreenShot320.png"));

    (hard disk of the test with about 1 TB free space)

    Since the case was 100% reproducible I could debug the problem using
    sqlite-amalgamation-3080803.zip (ver 3.8.8.3)
    I tried sqlite-amalgamation-201503091040.zip as well with the same
    result, so the problem was also not fixed in this pre-release.

    In debug session I found that the error came from

       static int winWrite (...

    and it is given in the line

       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){

    which is a call to a windows api function WriteFile

    adding the extra debug messages into a file (see sqlite3_modified.c 
function "static int winWrite")
    this was the output before the fail (ERROR_DISK_FULL)

...
WRITE file=00000030, buffer=00EDBE08, amount=1024, offset=4294965248, lock=4
OVERLAPPED offset=4294965248, OffsetHigh=0
WRITE file=00000030, buffer=00EDC2E0, amount=1024, offset=4294966272, lock=4
OVERLAPPED offset=4294966272, OffsetHigh=0

    Now note that

       4294966272 = 0xFFFFFC00
       and FFFFFFFF - FFFFFC00 = 3FF = 1023 !!!!! and we want to write 
1024 bytes!!!


That this is a Microsoft bug is only a guess for what I have seen 
debugging the code,
anyway if not I hope this analysis helps to find it the final cause of 
the problem and it could be fixed.

Regards
Alejandro





-------------- next part --------------

TITLE: Wrong ERROR_DISK_FULL writing a blob on Windows

DATE:  2015.03.15 
AUTHOR: Alejandro Xalabarder

DESCRIPTION:

   Having a sqlite database about 4.1 GB
   writing blobs in some table, for instance using a statement like
      INSERT INTO inodeCargo VALUES (1000, readfile ("ScreenShot.png"));

   an error ERROR_DISK_FULL can be through wrongly (under certain conditions)

   Windows 7 64-bit

REPRODUCIBLE:
   When the conditions are met, always reproducible

CAUSE :

   windows function WriteFile return error 112 (ERROR_DISK_FULL) when trying to 
write
   1024 bytes using a offset = 4294966272 = 0xFFFFFC00 = FFFFFFFF - 2023

   This was observed using the default mode (OVERLAPPED) although a test 
compiling
   the code with
      #define SQLITE_WIN32_NO_OVERLAPPED
   at the begining also fails.

PATCH:

   The patch (see sqlite3_modified.c) has worked in my case, but obviously 
cannot
   fix the mode NO_OVERLAPPED since is not compiled in this mode. Also all 
procedures
   using the buggy function, if this result to be the cause, should be reviewed.
   Therefore a more precise fix has to be developed by some expert in sqlite 
code.

ANALYSIS:

   A sqlite db used to store files came in the conditions described
   size of database file : 4.194.303 KB
   size of journal file : 8 KB
   size of the image (png file) : 4.417 KB

   SQL Query returning systematically ERROR_DISK_FULL:
      INSERT INTO inodeCargo VALUES (-24, 4522876, 0, readfile 
("ScreenShot320.png"));

   (hard disk of the test with about 1 TB free space)

   Since the case was 100% reproducible I could debug the problem using
   sqlite-amalgamation-3080803.zip (ver 3.8.8.3)
   I tried sqlite-amalgamation-201503091040.zip as well with the same
   result, so the problem was also not fixed in this pre-release.

   In debug session I found that the error came from

      static int winWrite (...

   and it is given in the line

      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){

   which is a call to a windows api function WriteFile

   adding the extra debug messages into a file (see sqlite3_modified.c function 
"static int winWrite")
   this was the output before the fail (ERROR_DISK_FULL)

...
WRITE file=00000030, buffer=00EDBE08, amount=1024, offset=4294965248, lock=4
OVERLAPPED offset=4294965248, OffsetHigh=0
WRITE file=00000030, buffer=00EDC2E0, amount=1024, offset=4294966272, lock=4
OVERLAPPED offset=4294966272, OffsetHigh=0

   Now note that

      4294966272 = 0xFFFFFC00
      and FFFFFFFF - FFFFFC00 = 3FF = 1023 !!!!! and we want to write 1024 
bytes!!!

Reply via email to