mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-22 08:48:55 +00:00
Fixed a bug when reading a reduced file without flushing (#2133)
This commit is contained in:
parent
2cd7c94653
commit
a25cb9e07a
2
.gitignore
vendored
2
.gitignore
vendored
@ -42,6 +42,7 @@ config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.scan
|
||||
configure.ac~
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
@ -86,6 +87,7 @@ test/junk_data
|
||||
test/s3proxy-*
|
||||
test/write_multiblock
|
||||
test/mknod_test
|
||||
test/truncate_read_file
|
||||
|
||||
#
|
||||
# Windows ports
|
||||
|
@ -456,7 +456,13 @@ bool PageList::Resize(off_t size, bool is_loaded, bool is_modified)
|
||||
off_t total = Size();
|
||||
|
||||
if(0 == total){
|
||||
// [NOTE]
|
||||
// The is_shrink flag remains unchanged in this function.
|
||||
//
|
||||
bool backup_is_shrink = is_shrink;
|
||||
|
||||
Init(size, is_loaded, is_modified);
|
||||
is_shrink = backup_is_shrink;
|
||||
|
||||
}else if(total < size){
|
||||
// add new area
|
||||
|
@ -245,7 +245,7 @@ gid_t get_gid(const headers_t& meta)
|
||||
|
||||
blkcnt_t get_blocks(off_t size)
|
||||
{
|
||||
return size / 512 + 1;
|
||||
return (size / 512) + (0 == (size % 512) ? 0 : 1);
|
||||
}
|
||||
|
||||
time_t cvtIAMExpireStringToTime(const char* s)
|
||||
|
19
src/s3fs.cpp
19
src/s3fs.cpp
@ -2682,19 +2682,32 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
|
||||
return result;
|
||||
}
|
||||
|
||||
AutoFdEntity autoent;
|
||||
FdEntity* ent;
|
||||
headers_t meta;
|
||||
|
||||
if((unsigned int)fi->flags & O_TRUNC){
|
||||
if(0 != st.st_size){
|
||||
st.st_size = 0;
|
||||
needs_flush = true;
|
||||
}
|
||||
}else{
|
||||
// [NOTE]
|
||||
// If the file has already been opened and edited, the file size in
|
||||
// the edited state is given priority.
|
||||
// This prevents the file size from being reset to its original size
|
||||
// if you keep the file open, shrink its size, and then read the file
|
||||
// from another process while it has not yet been flushed.
|
||||
//
|
||||
if(NULL != (ent = autoent.OpenExistFdEntity(path)) && ent->IsModified()){
|
||||
// sets the file size being edited.
|
||||
ent->GetSize(st.st_size);
|
||||
}
|
||||
}
|
||||
if(!S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)){
|
||||
st.st_mtime = -1;
|
||||
}
|
||||
|
||||
AutoFdEntity autoent;
|
||||
FdEntity* ent;
|
||||
headers_t meta;
|
||||
if(0 != (result = get_object_attribute(path, NULL, &meta, true, NULL, true))){ // no truncate cache
|
||||
return result;
|
||||
}
|
||||
|
@ -32,11 +32,13 @@ testdir = test
|
||||
noinst_PROGRAMS = \
|
||||
junk_data \
|
||||
write_multiblock \
|
||||
mknod_test
|
||||
mknod_test \
|
||||
truncate_read_file
|
||||
|
||||
junk_data_SOURCES = junk_data.c
|
||||
write_multiblock_SOURCES = write_multiblock.cc
|
||||
mknod_test_SOURCES = mknod_test.c
|
||||
junk_data_SOURCES = junk_data.c
|
||||
write_multiblock_SOURCES = write_multiblock.cc
|
||||
mknod_test_SOURCES = mknod_test.c
|
||||
truncate_read_file_SOURCES = truncate_read_file.c
|
||||
|
||||
#
|
||||
# Local variables:
|
||||
|
@ -112,6 +112,28 @@ function test_truncate_shrink_file {
|
||||
rm_test_file "${BIG_TRUNCATE_TEST_FILE}"
|
||||
}
|
||||
|
||||
function test_truncate_shrink_read_file {
|
||||
describe "Testing truncate(shrink) and read file ..."
|
||||
|
||||
# Initiate file size is 1024, and shrink file size is 512
|
||||
local init_size=1024
|
||||
local shrink_size=512
|
||||
|
||||
# create file
|
||||
dd if=/dev/urandom of="${TEST_TEXT_FILE}" bs="${init_size}" count=1
|
||||
|
||||
# truncate(shrink) file and read it before flusing
|
||||
../../truncate_read_file "${TEST_TEXT_FILE}" "${shrink_size}"
|
||||
|
||||
# check file size
|
||||
check_file_size "${TEST_TEXT_FILE}" "${shrink_size}"
|
||||
|
||||
# Truncate the file to 1024 length
|
||||
local t_size=1024
|
||||
|
||||
rm_test_file
|
||||
}
|
||||
|
||||
function test_mv_file {
|
||||
describe "Testing mv file function ..."
|
||||
# if the rename file exists, delete it
|
||||
@ -2610,6 +2632,7 @@ function add_all_tests {
|
||||
add_tests test_truncate_upload
|
||||
add_tests test_truncate_empty_file
|
||||
add_tests test_truncate_shrink_file
|
||||
add_tests test_truncate_shrink_read_file
|
||||
add_tests test_mv_file
|
||||
add_tests test_mv_to_exist_file
|
||||
add_tests test_mv_empty_directory
|
||||
|
81
test/truncate_read_file.c
Normal file
81
test/truncate_read_file.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* s3fs - FUSE-based file system backed by Amazon S3
|
||||
*
|
||||
* Copyright(C) 2021 Andrew Gaul <andrew@gaul.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// [NOTE]
|
||||
// This is a program used for file size inspection.
|
||||
// File size checking should be done by the caller of this program.
|
||||
// This program truncates the file and reads the file in another process
|
||||
// between truncate and flush(close file).
|
||||
//
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc != 3){
|
||||
fprintf(stderr, "[ERROR] Wrong paraemters\n");
|
||||
fprintf(stdout, "[Usage] truncate_read_file <file path> <truncate size(bytes)>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const char* filepath = argv[1];
|
||||
off_t size = (off_t)strtoull(argv[2], NULL, 10);
|
||||
int fd;
|
||||
|
||||
// open file
|
||||
if(-1 == (fd = open(filepath, O_RDWR))){
|
||||
fprintf(stderr, "[ERROR] Could not open file(%s)\n", filepath);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// truncate
|
||||
if(0 != ftruncate(fd, size)){
|
||||
fprintf(stderr, "[ERROR] Could not truncate file(%s) to %lld byte.\n", filepath, (long long)size);
|
||||
close(fd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// run sub-process for reading file(cat)
|
||||
char szCommand[1024];
|
||||
sprintf(szCommand, "cat %s >/dev/null 2>&1", filepath);
|
||||
if(0 != system(szCommand)){
|
||||
fprintf(stderr, "[ERROR] Failed to run sub-process(cat).\n");
|
||||
close(fd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// close file(flush)
|
||||
close(fd);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: expandtab sw=4 ts=4 fdm=marker
|
||||
* vim<600: expandtab sw=4 ts=4
|
||||
*/
|
Loading…
Reference in New Issue
Block a user