mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-22 16:58:55 +00:00
Do not create zero-byte object when creating file (#1640)
Previously s3fs created this object to store metadata and overwrote it when flushing. This prevented use with object stores which do not allow overwrites like HDS. Instead only create an in-memory representation which reduces the time to create small files. Fixes #1013.
This commit is contained in:
parent
3694786112
commit
771bbfeac5
@ -118,6 +118,12 @@ class FdEntity
|
||||
|
||||
bool ReserveDiskSpace(off_t size);
|
||||
bool PunchHole(off_t start = 0, size_t size = 0);
|
||||
|
||||
// Indicate that a new file's is dirty. This ensures that both metadata and data are synced during flush.
|
||||
void MarkDirtyNewFile() {
|
||||
pagelist.SetPageLoadedStatus(0, 1, PageList::PAGE_LOAD_MODIFIED);
|
||||
is_meta_pending = true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<std::string, class FdEntity*> fdent_map_t; // key=path, value=FdEntity*
|
||||
|
20
src/s3fs.cpp
20
src/s3fs.cpp
@ -970,20 +970,27 @@ static int s3fs_create(const char* _path, mode_t mode, struct fuse_file_info* fi
|
||||
}else if(0 != result){
|
||||
return result;
|
||||
}
|
||||
result = create_file_object(path, mode, pcxt->uid, pcxt->gid);
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
if(result != 0){
|
||||
return result;
|
||||
|
||||
time_t now = time(NULL);
|
||||
headers_t meta;
|
||||
meta["Content-Length"] = "0";
|
||||
meta["x-amz-meta-uid"] = str(pcxt->uid);
|
||||
meta["x-amz-meta-gid"] = str(pcxt->gid);
|
||||
meta["x-amz-meta-mode"] = str(mode);
|
||||
meta["x-amz-meta-atime"] = str(now);
|
||||
meta["x-amz-meta-mtime"] = str(now);
|
||||
meta["x-amz-meta-ctime"] = str(now);
|
||||
if(!StatCache::getStatCacheData()->AddStat(path, meta)){
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
AutoFdEntity autoent;
|
||||
FdEntity* ent;
|
||||
headers_t meta;
|
||||
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
||||
if(NULL == (ent = autoent.Open(path, &meta, 0, -1, false, true))){
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
return -EIO;
|
||||
}
|
||||
ent->MarkDirtyNewFile();
|
||||
autoent.Detach(); // KEEP fdentity open
|
||||
fi->fh = ent->GetFd();
|
||||
|
||||
@ -2016,6 +2023,7 @@ static int s3fs_utimens(const char* _path, const struct timespec ts[2])
|
||||
// then the meta is pending and accumulated to be put after the upload is complete.
|
||||
S3FS_PRN_INFO("meta pending until upload is complete");
|
||||
need_put_header = false;
|
||||
ent->SetHoldingMtime(ts[1]); // ts[1] is mtime
|
||||
|
||||
}else{
|
||||
S3FS_PRN_INFO("meta is not pending, but need to keep current mtime.");
|
||||
|
@ -24,6 +24,20 @@ set -o pipefail
|
||||
|
||||
source test-utils.sh
|
||||
|
||||
function test_create_empty_file {
|
||||
describe "Testing creating an empty file ..."
|
||||
|
||||
OBJECT_NAME="$(basename $PWD)/${TEST_TEXT_FILE}"
|
||||
|
||||
touch ${TEST_TEXT_FILE}
|
||||
|
||||
check_file_size "${TEST_TEXT_FILE}" 0
|
||||
|
||||
aws_cli s3api head-object --bucket "${TEST_BUCKET_1}" --key "${OBJECT_NAME}"
|
||||
|
||||
rm_test_file
|
||||
}
|
||||
|
||||
function test_append_file {
|
||||
describe "Testing append to file ..."
|
||||
TEST_INPUT="echo ${TEST_TEXT} to ${TEST_TEXT_FILE}"
|
||||
@ -1425,6 +1439,7 @@ function add_all_tests {
|
||||
if ! ps u $S3FS_PID | grep -q ensure_diskfree && ! uname | grep -q Darwin; then
|
||||
add_tests test_clean_up_cache
|
||||
fi
|
||||
add_tests test_create_empty_file
|
||||
add_tests test_append_file
|
||||
add_tests test_truncate_file
|
||||
add_tests test_truncate_upload
|
||||
|
Loading…
Reference in New Issue
Block a user