diff options
Diffstat (limited to 'linden/indra/llvfs/llvfs.cpp')
-rw-r--r-- | linden/indra/llvfs/llvfs.cpp | 90 |
1 files changed, 69 insertions, 21 deletions
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp index dd5854c..a05d1b9 100644 --- a/linden/indra/llvfs/llvfs.cpp +++ b/linden/indra/llvfs/llvfs.cpp | |||
@@ -35,6 +35,10 @@ | |||
35 | #include <map> | 35 | #include <map> |
36 | #if LL_WINDOWS | 36 | #if LL_WINDOWS |
37 | #include <share.h> | 37 | #include <share.h> |
38 | #elif LL_SOLARIS | ||
39 | #include <sys/types.h> | ||
40 | #include <unistd.h> | ||
41 | #include <fcntl.h> | ||
38 | #else | 42 | #else |
39 | #include <sys/file.h> | 43 | #include <sys/file.h> |
40 | #endif | 44 | #endif |
@@ -379,13 +383,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r | |||
379 | ) | 383 | ) |
380 | { | 384 | { |
381 | U8 *buffer = new U8[fbuf.st_size]; | 385 | U8 *buffer = new U8[fbuf.st_size]; |
382 | fread(buffer, fbuf.st_size, 1, mIndexFP); | 386 | size_t nread = fread(buffer, 1, fbuf.st_size, mIndexFP); |
383 | 387 | ||
384 | U8 *tmp_ptr = buffer; | 388 | U8 *tmp_ptr = buffer; |
385 | 389 | ||
386 | std::vector<LLVFSFileBlock*> files_by_loc; | 390 | std::vector<LLVFSFileBlock*> files_by_loc; |
387 | 391 | ||
388 | while (tmp_ptr < buffer + fbuf.st_size) | 392 | while (tmp_ptr < buffer + nread) |
389 | { | 393 | { |
390 | LLVFSFileBlock *block = new LLVFSFileBlock(); | 394 | LLVFSFileBlock *block = new LLVFSFileBlock(); |
391 | 395 | ||
@@ -881,12 +885,18 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type | |||
881 | // move the file into the new block | 885 | // move the file into the new block |
882 | U8 *buffer = new U8[block->mSize]; | 886 | U8 *buffer = new U8[block->mSize]; |
883 | fseek(mDataFP, block->mLocation, SEEK_SET); | 887 | fseek(mDataFP, block->mLocation, SEEK_SET); |
884 | fread(buffer, block->mSize, 1, mDataFP); | 888 | if (fread(buffer, block->mSize, 1, mDataFP) == 1) |
885 | fseek(mDataFP, free_block->mLocation, SEEK_SET); | 889 | { |
886 | fwrite(buffer, block->mSize, 1, mDataFP); | 890 | fseek(mDataFP, free_block->mLocation, SEEK_SET); |
887 | // fflush(mDataFP); | 891 | if (fwrite(buffer, block->mSize, 1, mDataFP) != 1) |
888 | 892 | { | |
889 | delete[] buffer; | 893 | llwarns << "Short write" << llendl; |
894 | } | ||
895 | |||
896 | delete[] buffer; | ||
897 | } else { | ||
898 | llwarns << "Short read" << llendl; | ||
899 | } | ||
890 | } | 900 | } |
891 | } | 901 | } |
892 | 902 | ||
@@ -1486,7 +1496,7 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove) | |||
1486 | } | 1496 | } |
1487 | 1497 | ||
1488 | BOOL set_index_to_end = FALSE; | 1498 | BOOL set_index_to_end = FALSE; |
1489 | S32 seek_pos = block->mIndexLocation; | 1499 | long seek_pos = block->mIndexLocation; |
1490 | 1500 | ||
1491 | if (-1 == seek_pos) | 1501 | if (-1 == seek_pos) |
1492 | { | 1502 | { |
@@ -1534,7 +1544,11 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove) | |||
1534 | fseek(mIndexFP, seek_pos, SEEK_SET); | 1544 | fseek(mIndexFP, seek_pos, SEEK_SET); |
1535 | } | 1545 | } |
1536 | 1546 | ||
1537 | fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); | 1547 | if (fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1) |
1548 | { | ||
1549 | llwarns << "Short write" << llendl; | ||
1550 | } | ||
1551 | |||
1538 | // fflush(mIndexFP); | 1552 | // fflush(mIndexFP); |
1539 | 1553 | ||
1540 | lockData(); | 1554 | lockData(); |
@@ -1663,18 +1677,24 @@ void LLVFS::pokeFiles() | |||
1663 | // only write data if we actually read 4 bytes | 1677 | // only write data if we actually read 4 bytes |
1664 | // otherwise we're writing garbage and screwing up the file | 1678 | // otherwise we're writing garbage and screwing up the file |
1665 | fseek(mDataFP, 0, SEEK_SET); | 1679 | fseek(mDataFP, 0, SEEK_SET); |
1666 | if (fread(&word, 1, 4, mDataFP) == 4) | 1680 | if (fread(&word, sizeof(word), 1, mDataFP) == 1) |
1667 | { | 1681 | { |
1668 | fseek(mDataFP, 0, SEEK_SET); | 1682 | fseek(mDataFP, 0, SEEK_SET); |
1669 | fwrite(&word, 1, 4, mDataFP); | 1683 | if (fwrite(&word, sizeof(word), 1, mDataFP) != 1) |
1684 | { | ||
1685 | llwarns << "Could not write to data file" << llendl; | ||
1686 | } | ||
1670 | fflush(mDataFP); | 1687 | fflush(mDataFP); |
1671 | } | 1688 | } |
1672 | 1689 | ||
1673 | fseek(mIndexFP, 0, SEEK_SET); | 1690 | fseek(mIndexFP, 0, SEEK_SET); |
1674 | if (fread(&word, 1, 4, mIndexFP) == 4) | 1691 | if (fread(&word, sizeof(word), 1, mIndexFP) == 1) |
1675 | { | 1692 | { |
1676 | fseek(mIndexFP, 0, SEEK_SET); | 1693 | fseek(mIndexFP, 0, SEEK_SET); |
1677 | fwrite(&word, 1, 4, mIndexFP); | 1694 | if (fwrite(&word, sizeof(word), 1, mIndexFP) != 1) |
1695 | { | ||
1696 | llwarns << "Could not write to index file" << llendl; | ||
1697 | } | ||
1678 | fflush(mIndexFP); | 1698 | fflush(mIndexFP); |
1679 | } | 1699 | } |
1680 | } | 1700 | } |
@@ -1709,21 +1729,26 @@ void LLVFS::audit() | |||
1709 | fflush(mIndexFP); | 1729 | fflush(mIndexFP); |
1710 | 1730 | ||
1711 | fseek(mIndexFP, 0, SEEK_END); | 1731 | fseek(mIndexFP, 0, SEEK_END); |
1712 | S32 index_size = ftell(mIndexFP); | 1732 | long index_size = ftell(mIndexFP); |
1713 | fseek(mIndexFP, 0, SEEK_SET); | 1733 | fseek(mIndexFP, 0, SEEK_SET); |
1714 | 1734 | ||
1735 | BOOL vfs_corrupt = FALSE; | ||
1736 | |||
1715 | U8 *buffer = new U8[index_size]; | 1737 | U8 *buffer = new U8[index_size]; |
1716 | fread(buffer, index_size, 1, mIndexFP); | 1738 | |
1739 | if (fread(buffer, 1, index_size, mIndexFP) != index_size) | ||
1740 | { | ||
1741 | llwarns << "Index truncated" << llendl; | ||
1742 | vfs_corrupt = TRUE; | ||
1743 | } | ||
1717 | 1744 | ||
1718 | U8 *tmp_ptr = buffer; | 1745 | U8 *tmp_ptr = buffer; |
1719 | 1746 | ||
1720 | std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files; | 1747 | std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files; |
1721 | U32 cur_time = (U32)time(NULL); | 1748 | U32 cur_time = (U32)time(NULL); |
1722 | 1749 | ||
1723 | BOOL vfs_corrupt = FALSE; | ||
1724 | |||
1725 | std::vector<LLVFSFileBlock*> audit_blocks; | 1750 | std::vector<LLVFSFileBlock*> audit_blocks; |
1726 | while (tmp_ptr < buffer + index_size) | 1751 | while (!vfs_corrupt && tmp_ptr < buffer + index_size) |
1727 | { | 1752 | { |
1728 | LLVFSFileBlock *block = new LLVFSFileBlock(); | 1753 | LLVFSFileBlock *block = new LLVFSFileBlock(); |
1729 | audit_blocks.push_back(block); | 1754 | audit_blocks.push_back(block); |
@@ -1803,7 +1828,11 @@ void LLVFS::audit() | |||
1803 | llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl; | 1828 | llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl; |
1804 | fseek(mIndexFP, block->mIndexLocation, SEEK_SET); | 1829 | fseek(mIndexFP, block->mIndexLocation, SEEK_SET); |
1805 | U8 buf[LLVFSFileBlock::SERIAL_SIZE]; | 1830 | U8 buf[LLVFSFileBlock::SERIAL_SIZE]; |
1806 | fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); | 1831 | if (fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1) |
1832 | { | ||
1833 | llwarns << "VFile " << block->mFileID | ||
1834 | << " gave short read" << llendl; | ||
1835 | } | ||
1807 | 1836 | ||
1808 | LLVFSFileBlock disk_block; | 1837 | LLVFSFileBlock disk_block; |
1809 | disk_block.deserialize(buf, block->mIndexLocation); | 1838 | disk_block.deserialize(buf, block->mIndexLocation); |
@@ -2116,6 +2145,12 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) | |||
2116 | int fd; | 2145 | int fd; |
2117 | 2146 | ||
2118 | // first test the lock in a non-destructive way | 2147 | // first test the lock in a non-destructive way |
2148 | #if LL_SOLARIS | ||
2149 | struct flock fl; | ||
2150 | fl.l_whence = SEEK_SET; | ||
2151 | fl.l_start = 0; | ||
2152 | fl.l_len = 1; | ||
2153 | #else // !LL_SOLARIS | ||
2119 | if (strstr(mode, "w")) | 2154 | if (strstr(mode, "w")) |
2120 | { | 2155 | { |
2121 | fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ | 2156 | fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ |
@@ -2131,13 +2166,19 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) | |||
2131 | fclose(fp); | 2166 | fclose(fp); |
2132 | } | 2167 | } |
2133 | } | 2168 | } |
2169 | #endif // !LL_SOLARIS | ||
2134 | 2170 | ||
2135 | // now actually open the file for use | 2171 | // now actually open the file for use |
2136 | fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */ | 2172 | fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */ |
2137 | if (fp) | 2173 | if (fp) |
2138 | { | 2174 | { |
2139 | fd = fileno(fp); | 2175 | fd = fileno(fp); |
2176 | #if LL_SOLARIS | ||
2177 | fl.l_type = read_lock ? F_RDLCK : F_WRLCK; | ||
2178 | if (fcntl(fd, F_SETLK, &fl) == -1) | ||
2179 | #else | ||
2140 | if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1) | 2180 | if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1) |
2181 | #endif | ||
2141 | { | 2182 | { |
2142 | fclose(fp); | 2183 | fclose(fp); |
2143 | fp = NULL; | 2184 | fp = NULL; |
@@ -2165,7 +2206,14 @@ void LLVFS::unlockAndClose(FILE *fp) | |||
2165 | flock(fd, LOCK_UN); | 2206 | flock(fd, LOCK_UN); |
2166 | #endif | 2207 | #endif |
2167 | */ | 2208 | */ |
2168 | 2209 | #if LL_SOLARIS | |
2210 | struct flock fl; | ||
2211 | fl.l_whence = SEEK_SET; | ||
2212 | fl.l_start = 0; | ||
2213 | fl.l_len = 1; | ||
2214 | fl.l_type = F_UNLCK; | ||
2215 | fcntl(fileno(fp), F_SETLK, &fl); | ||
2216 | #endif | ||
2169 | fclose(fp); | 2217 | fclose(fp); |
2170 | } | 2218 | } |
2171 | } | 2219 | } |