mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-22 16:58:55 +00:00
Fix two inconsistency issues between stat cache and cache file (#2152)
* Fix inconsistency between stat cache file and cache file We unlock stat cache file too early in FdEntity::Open(), and would truncate cache file and update stat cache file, so there's a window that stat cache doesn't reflect cache file status. Suggested-by: Takeshi Nakatani <ggtakec@gmail.com> Signed-off-by: Eryu Guan <eguan@linux.alibaba.com> * Mark pagelist as unloaded if cache file has been truncated If cache file size doesn't match object size, the cache file might be corrupted, so invalidate it and save new cache stat file. Suggested-by: Takeshi Nakatani <ggtakec@gmail.com> Signed-off-by: Eryu Guan <eguan@linux.alibaba.com> --------- Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
This commit is contained in:
parent
0d6b02090e
commit
6ca5a24a7f
@ -485,6 +485,8 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
|
||||
bool need_save_csf = false; // need to save(reset) cache stat file
|
||||
bool is_truncate = false; // need to truncate
|
||||
|
||||
CacheFileStat* pcfstat = NULL;
|
||||
|
||||
if(!cachepath.empty()){
|
||||
// using cache
|
||||
struct stat st;
|
||||
@ -498,12 +500,12 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
|
||||
}
|
||||
|
||||
// open cache and cache stat file, load page info.
|
||||
CacheFileStat cfstat(path.c_str());
|
||||
pcfstat = new CacheFileStat(path.c_str());
|
||||
|
||||
// try to open cache file
|
||||
if( -1 != (physical_fd = open(cachepath.c_str(), O_RDWR)) &&
|
||||
0 != (inode = FdEntity::GetInode(physical_fd)) &&
|
||||
pagelist.Serialize(cfstat, false, inode) )
|
||||
pagelist.Serialize(*pcfstat, false, inode) )
|
||||
{
|
||||
// succeed to open cache file and to load stats data
|
||||
memset(&st, 0, sizeof(struct stat));
|
||||
@ -517,13 +519,18 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
|
||||
if(-1 == size){
|
||||
if(st.st_size != pagelist.Size()){
|
||||
pagelist.Resize(st.st_size, false, true); // Areas with increased size are modified
|
||||
need_save_csf = true; // need to update page info
|
||||
need_save_csf = true; // need to update page info
|
||||
}
|
||||
size = st.st_size;
|
||||
}else{
|
||||
// First if the current cache file size and pagelist do not match, fix pagelist.
|
||||
if(st.st_size != pagelist.Size()){
|
||||
pagelist.Resize(st.st_size, false, true); // Areas with increased size are modified
|
||||
need_save_csf = true; // need to update page info
|
||||
}
|
||||
if(size != pagelist.Size()){
|
||||
pagelist.Resize(size, false, true); // Areas with increased size are modified
|
||||
need_save_csf = true; // need to update page info
|
||||
need_save_csf = true; // need to update page info
|
||||
}
|
||||
if(size != st.st_size){
|
||||
is_truncate = true;
|
||||
@ -631,12 +638,14 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
|
||||
}
|
||||
|
||||
// reset cache stat file
|
||||
if(need_save_csf){
|
||||
CacheFileStat cfstat(path.c_str());
|
||||
if(!pagelist.Serialize(cfstat, true, inode)){
|
||||
if(need_save_csf && pcfstat){
|
||||
if(!pagelist.Serialize(*pcfstat, true, inode)){
|
||||
S3FS_PRN_WARN("failed to save cache stat file(%s), but continue...", path.c_str());
|
||||
}
|
||||
}
|
||||
if(pcfstat){
|
||||
delete pcfstat;
|
||||
}
|
||||
|
||||
// set original headers and size in it.
|
||||
if(pmeta){
|
||||
|
Loading…
Reference in New Issue
Block a user