diff --git a/src/cache.cpp b/src/cache.cpp index 2bf850a..eed6954 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -220,7 +220,7 @@ void StatCache::Clear() S3FS_MALLOCTRIM(0); } -bool StatCache::GetStat(string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce) +bool StatCache::GetStat(const string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce) { bool is_delete_cache = false; string strpath = key; diff --git a/src/cache.h b/src/cache.h index 253cd13..8f57ba9 100644 --- a/src/cache.h +++ b/src/cache.h @@ -65,7 +65,7 @@ class StatCache ~StatCache(); void Clear(void); - bool GetStat(std::string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce); + bool GetStat(const std::string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce); // Truncate stat cache bool TruncateCache(void); @@ -93,19 +93,19 @@ class StatCache } // Get stat cache - bool GetStat(std::string& key, struct stat* pst, headers_t* meta, bool overcheck = true, bool* pisforce = NULL) { + bool GetStat(const std::string& key, struct stat* pst, headers_t* meta, bool overcheck = true, bool* pisforce = NULL) { return GetStat(key, pst, meta, overcheck, NULL, pisforce); } - bool GetStat(std::string& key, struct stat* pst, bool overcheck = true) { + bool GetStat(const std::string& key, struct stat* pst, bool overcheck = true) { return GetStat(key, pst, NULL, overcheck, NULL, NULL); } - bool GetStat(std::string& key, headers_t* meta, bool overcheck = true) { + bool GetStat(const std::string& key, headers_t* meta, bool overcheck = true) { return GetStat(key, NULL, meta, overcheck, NULL, NULL); } - bool HasStat(std::string& key, bool overcheck = true) { + bool HasStat(const std::string& key, bool overcheck = true) { return GetStat(key, NULL, NULL, overcheck, NULL, NULL); } - bool HasStat(std::string& key, const char* etag, bool overcheck = true) { + bool HasStat(const std::string& key, const char* etag, bool overcheck = true) { return GetStat(key, NULL, NULL, overcheck, etag, NULL); } diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 08c54f4..13e4a16 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -2143,7 +2143,13 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi) // clear stat for reading fresh stat. // (if object stat is changed, we refresh it. then s3fs gets always // stat when s3fs open the object). - StatCache::getStatCacheData()->DelStat(path); + if(StatCache::getStatCacheData()->HasStat(path)){ + // flush any dirty data so that subsequent stat gets correct size + if((result = s3fs_flush(_path, fi)) != 0){ + S3FS_PRN_ERR("could not flush(%s): result=%d", path, result); + } + StatCache::getStatCacheData()->DelStat(path); + } int mask = (O_RDONLY != (fi->flags & O_ACCMODE) ? W_OK : R_OK); if(0 != (result = check_parent_object_access(path, X_OK))){ diff --git a/test/integration-test-main.sh b/test/integration-test-main.sh index ce8aacf..3baeeb9 100755 --- a/test/integration-test-main.sh +++ b/test/integration-test-main.sh @@ -547,6 +547,15 @@ function test_concurrency { rm -f `seq 100` } +function test_open_second_fd { + describe "read from an open fd" + rm -f ${TEST_TEXT_FILE} + RESULT=$( (echo foo ; wc -c < ${TEST_TEXT_FILE} >&2) 2>& 1>${TEST_TEXT_FILE}) + if [ "$RESULT" -ne 4 ]; then + echo "size mismatch, expected: 4, was: ${RESULT}" + return 1 + fi +} function add_all_tests { add_tests test_append_file @@ -574,6 +583,7 @@ function add_all_tests { add_tests test_write_after_seek_ahead add_tests test_overwrite_existing_file_range add_tests test_concurrency + add_tests test_open_second_fd } init_suite