Refactored single type requests to use through ThreadPoolMan
This commit is contained in:
committed by
Andrew Gaul
parent
a680d3e138
commit
efc23316e9
@ -40,13 +40,35 @@
|
||||
#include "s3fs_logger.h"
|
||||
#include "s3fs_util.h"
|
||||
#include "curl.h"
|
||||
#include "curl_util.h"
|
||||
#include "s3fs_cred.h"
|
||||
#include "threadpoolman.h"
|
||||
#include "s3fs_threadreqs.h"
|
||||
|
||||
//------------------------------------------------
|
||||
// Symbols
|
||||
//------------------------------------------------
|
||||
static constexpr int MAX_MULTIPART_CNT = 10 * 1000; // S3 multipart max count
|
||||
|
||||
//------------------------------------------------
|
||||
// Structure of parameters to pass to thread
|
||||
//------------------------------------------------
|
||||
//
|
||||
// Multipart Upload Request parameter structure for Thread Pool.
|
||||
//
|
||||
// ([TODO] This is a temporary structure is moved when S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
struct multipart_upload_req_thparam
|
||||
{
|
||||
std::string path;
|
||||
std::string upload_id;
|
||||
int fd = -1;
|
||||
off_t start = 0;
|
||||
off_t size = 0;
|
||||
etagpair* petagpair = nullptr;
|
||||
int result = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
// FdEntity class variables
|
||||
//------------------------------------------------
|
||||
@ -106,6 +128,25 @@ ino_t FdEntity::GetInode(int fd)
|
||||
return st.st_ino;
|
||||
}
|
||||
|
||||
//
|
||||
// Worker function for multipart upload request
|
||||
//
|
||||
// ([TODO] This is a temporary structure is moved when S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
void* FdEntity::MultipartUploadThreadWorker(void* arg)
|
||||
{
|
||||
auto* pthparam = static_cast<multipart_upload_req_thparam*>(arg);
|
||||
if(!pthparam){
|
||||
return reinterpret_cast<void*>(-EIO);
|
||||
}
|
||||
S3FS_PRN_INFO3("Multipart Upload Request [path=%s][upload id=%s][fd=%d][start=%lld][size=%lld][etagpair=%p]", pthparam->path.c_str(), pthparam->upload_id.c_str(), pthparam->fd, static_cast<long long>(pthparam->start), static_cast<long long>(pthparam->size), pthparam->petagpair);
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
pthparam->result = s3fscurl.MultipartUploadRequest(pthparam->upload_id, pthparam->path.c_str(), pthparam->fd, pthparam->start, pthparam->size, pthparam->petagpair);
|
||||
|
||||
return reinterpret_cast<void*>(pthparam->result);
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// FdEntity methods
|
||||
//------------------------------------------------
|
||||
@ -1039,8 +1080,7 @@ int FdEntity::Load(off_t start, off_t size, bool is_modified_flag)
|
||||
}else{
|
||||
// single request
|
||||
if(0 < need_load_size){
|
||||
S3fsCurl s3fscurl;
|
||||
result = s3fscurl.GetObjectRequest(path.c_str(), physical_fd, iter->offset, need_load_size);
|
||||
result = get_object_request(path, physical_fd, iter->offset, need_load_size);
|
||||
}else{
|
||||
result = 0;
|
||||
}
|
||||
@ -1164,8 +1204,7 @@ int FdEntity::NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start, off_t si
|
||||
|
||||
// single area get request
|
||||
if(0 < need_load_size){
|
||||
S3fsCurl s3fscurl;
|
||||
if(0 != (result = s3fscurl.GetObjectRequest(path.c_str(), tmpfd, offset, oneread))){
|
||||
if(0 != (result = get_object_request(path, tmpfd, offset, oneread))){
|
||||
S3FS_PRN_ERR("failed to get object(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(offset), static_cast<long long int>(oneread), tmpfd);
|
||||
break;
|
||||
}
|
||||
@ -1180,9 +1219,9 @@ int FdEntity::NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start, off_t si
|
||||
}else{
|
||||
// already loaded area
|
||||
}
|
||||
// single area upload by multipart post
|
||||
if(0 != (result = NoCacheMultipartPost(pseudo_obj, upload_fd, offset, oneread))){
|
||||
S3FS_PRN_ERR("failed to multipart post(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(offset), static_cast<long long int>(oneread), upload_fd);
|
||||
// single area upload by multipart upload
|
||||
if(0 != (result = NoCacheMultipartUploadRequest(pseudo_obj, upload_fd, offset, oneread))){
|
||||
S3FS_PRN_ERR("failed to multipart upload(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(offset), static_cast<long long int>(oneread), upload_fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1222,11 +1261,43 @@ int FdEntity::NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start, off_t si
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Common method that calls S3fsCurl::PreMultipartUploadRequest via pre_multipart_upload_request
|
||||
//
|
||||
// [NOTE]
|
||||
// If the request is successful, initialize upload_id.
|
||||
//
|
||||
int FdEntity::PreMultipartUploadRequest(PseudoFdInfo* pseudo_obj)
|
||||
{
|
||||
if(!pseudo_obj){
|
||||
S3FS_PRN_ERR("Internal error, pseudo fd object pointer is null.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// get upload_id
|
||||
std::string upload_id;
|
||||
int result;
|
||||
if(0 != (result = pre_multipart_upload_request(path, orgmeta, upload_id))){
|
||||
return result;
|
||||
}
|
||||
|
||||
// reset upload_id
|
||||
if(!pseudo_obj->InitialUploadInfo(upload_id)){
|
||||
S3FS_PRN_ERR("failed to initialize upload id(%s)", upload_id.c_str());
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// Clear the dirty flag, because the meta data is updated.
|
||||
pending_status = pending_status_t::NO_UPDATE_PENDING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [NOTE]
|
||||
// At no disk space for caching object.
|
||||
// This method is starting multipart uploading.
|
||||
//
|
||||
int FdEntity::NoCachePreMultipartPost(PseudoFdInfo* pseudo_obj)
|
||||
int FdEntity::NoCachePreMultipartUploadRequest(PseudoFdInfo* pseudo_obj)
|
||||
{
|
||||
if(!pseudo_obj){
|
||||
S3FS_PRN_ERR("Internal error, pseudo fd object pointer is null.");
|
||||
@ -1236,21 +1307,11 @@ int FdEntity::NoCachePreMultipartPost(PseudoFdInfo* pseudo_obj)
|
||||
// initialize multipart upload values
|
||||
pseudo_obj->ClearUploadInfo(true);
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
std::string upload_id;
|
||||
int result;
|
||||
if(0 != (result = s3fscurl.PreMultipartPostRequest(path.c_str(), orgmeta, upload_id))){
|
||||
int result;
|
||||
if(0 != (result = PreMultipartUploadRequest(pseudo_obj))){
|
||||
return result;
|
||||
}
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
|
||||
// Clear the dirty flag, because the meta data is updated.
|
||||
pending_status = pending_status_t::NO_UPDATE_PENDING;
|
||||
|
||||
// reset upload_id
|
||||
if(!pseudo_obj->InitialUploadInfo(upload_id)){
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1258,55 +1319,74 @@ int FdEntity::NoCachePreMultipartPost(PseudoFdInfo* pseudo_obj)
|
||||
// At no disk space for caching object.
|
||||
// This method is uploading one part of multipart.
|
||||
//
|
||||
int FdEntity::NoCacheMultipartPost(PseudoFdInfo* pseudo_obj, int tgfd, off_t start, off_t size)
|
||||
// ([TODO] This is a temporary modification till S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
int FdEntity::NoCacheMultipartUploadRequest(PseudoFdInfo* pseudo_obj, int tgfd, off_t start, off_t size)
|
||||
{
|
||||
if(-1 == tgfd || !pseudo_obj || !pseudo_obj->IsUploading()){
|
||||
S3FS_PRN_ERR("Need to initialize for multipart post.");
|
||||
S3FS_PRN_ERR("Need to initialize for multipart upload.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// parameter for thread worker
|
||||
multipart_upload_req_thparam thargs;
|
||||
thargs.path = path;
|
||||
thargs.upload_id.clear();
|
||||
thargs.fd = tgfd;
|
||||
thargs.start = start;
|
||||
thargs.size = size;
|
||||
thargs.petagpair = nullptr;
|
||||
thargs.result = 0;
|
||||
|
||||
// get upload id
|
||||
std::string upload_id;
|
||||
if(!pseudo_obj->GetUploadId(upload_id)){
|
||||
if(!pseudo_obj->GetUploadId(thargs.upload_id)){
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// append new part and get it's etag string pointer
|
||||
etagpair* petagpair = nullptr;
|
||||
if(!pseudo_obj->AppendUploadPart(start, size, false, &petagpair)){
|
||||
if(!pseudo_obj->AppendUploadPart(start, size, false, &(thargs.petagpair))){
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
return s3fscurl.MultipartUploadRequest(upload_id, path.c_str(), tgfd, start, size, petagpair);
|
||||
// make parameter for thread pool
|
||||
thpoolman_param ppoolparam;
|
||||
ppoolparam.args = &thargs;
|
||||
ppoolparam.psem = nullptr; // case await
|
||||
ppoolparam.pfunc = FdEntity::MultipartUploadThreadWorker;
|
||||
|
||||
// send request by thread
|
||||
if(!ThreadPoolMan::AwaitInstruct(ppoolparam)){
|
||||
S3FS_PRN_ERR("failed to setup Get Object Request Thread Worker");
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != thargs.result){
|
||||
S3FS_PRN_ERR("Multipart Upload Request(path=%s, upload_id=%s, fd=%d, start=%lld, size=%lld) returns with error(%d)", path.c_str(), thargs.upload_id.c_str(), tgfd, static_cast<long long int>(start), static_cast<long long int>(size), thargs.result);
|
||||
return thargs.result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [NOTE]
|
||||
// At no disk space for caching object.
|
||||
// This method is finishing multipart uploading.
|
||||
//
|
||||
int FdEntity::NoCacheCompleteMultipartPost(PseudoFdInfo* pseudo_obj)
|
||||
int FdEntity::NoCacheMultipartUploadComplete(PseudoFdInfo* pseudo_obj)
|
||||
{
|
||||
etaglist_t etaglist;
|
||||
if(!pseudo_obj || !pseudo_obj->IsUploading() || !pseudo_obj->GetEtaglist(etaglist)){
|
||||
S3FS_PRN_ERR("There is no upload id or etag list.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// get upload id
|
||||
// get upload id and etag list
|
||||
std::string upload_id;
|
||||
if(!pseudo_obj->GetUploadId(upload_id)){
|
||||
etaglist_t parts;
|
||||
if(!pseudo_obj->GetUploadId(upload_id) || !pseudo_obj->GetEtaglist(parts)){
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
int result = s3fscurl.CompleteMultipartPostRequest(path.c_str(), upload_id, etaglist);
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
if(0 != result){
|
||||
S3fsCurl s3fscurl_abort(true);
|
||||
int result2 = s3fscurl.AbortMultipartUpload(path.c_str(), upload_id);
|
||||
s3fscurl_abort.DestroyCurlHandle();
|
||||
if(0 != result2){
|
||||
int result;
|
||||
if(0 != (result = complete_multipart_upload_request(path, upload_id, parts))){
|
||||
S3FS_PRN_ERR("failed to complete multipart upload by errno(%d)", result);
|
||||
untreated_list.ClearAll();
|
||||
pseudo_obj->ClearUploadInfo(); // clear multipart upload info
|
||||
|
||||
int result2;
|
||||
if(0 != (result2 = abort_multipart_upload_request(path, upload_id))){
|
||||
S3FS_PRN_ERR("failed to abort multipart upload by errno(%d)", result2);
|
||||
}
|
||||
return result;
|
||||
@ -1398,6 +1478,9 @@ int FdEntity::RowFlushHasLock(int fd, const char* tpath, bool force_sync)
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// ([TODO] This is a temporary modification till S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
int FdEntity::RowFlushNoMultipart(const PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
{
|
||||
S3FS_PRN_INFO3("[tpath=%s][path=%s][pseudo_fd=%d][physical_fd=%d]", SAFESTRPTR(tpath), path.c_str(), (pseudo_obj ? pseudo_obj->GetPseudoFd() : -1), physical_fd);
|
||||
@ -1411,23 +1494,20 @@ int FdEntity::RowFlushNoMultipart(const PseudoFdInfo* pseudo_obj, const char* tp
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
int result;
|
||||
std::string tmppath = path;
|
||||
headers_t tmporgmeta = orgmeta;
|
||||
|
||||
// If there is no loading all of the area, loading all area.
|
||||
off_t restsize = pagelist.GetTotalUnloadedPageSize();
|
||||
if(0 < restsize){
|
||||
// check disk space
|
||||
if(!ReserveDiskSpace(restsize)){
|
||||
// no enough disk space
|
||||
S3FS_PRN_WARN("Not enough local storage to flush: [path=%s][pseudo_fd=%d][physical_fd=%d]", path.c_str(), pseudo_obj->GetPseudoFd(), physical_fd);
|
||||
S3FS_PRN_WARN("Not enough local storage to flush: [path=%s][pseudo_fd=%d][physical_fd=%d]", (tpath ? tpath : path.c_str()), pseudo_obj->GetPseudoFd(), physical_fd);
|
||||
return -ENOSPC; // No space left on device
|
||||
}
|
||||
}
|
||||
FdManager::FreeReservedDiskSpace(restsize);
|
||||
|
||||
// Always load all uninitialized area
|
||||
int result;
|
||||
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
|
||||
S3FS_PRN_ERR("failed to upload all area(errno=%d)", result);
|
||||
return result;
|
||||
@ -1445,21 +1525,45 @@ int FdEntity::RowFlushNoMultipart(const PseudoFdInfo* pseudo_obj, const char* tp
|
||||
S3FS_PRN_ERR("fstat is failed by errno(%d), but continue...", errno);
|
||||
}
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
result = s3fscurl.PutRequest(tpath ? tpath : tmppath.c_str(), tmporgmeta, physical_fd);
|
||||
// parameter for thread worker
|
||||
put_req_thparam thargs;
|
||||
thargs.path = tpath ? tpath : path;
|
||||
thargs.meta = orgmeta; // copy
|
||||
thargs.fd = physical_fd;
|
||||
thargs.ahbe = true;
|
||||
thargs.result = 0;
|
||||
|
||||
// make parameter for thread pool
|
||||
thpoolman_param ppoolparam;
|
||||
ppoolparam.args = &thargs;
|
||||
ppoolparam.psem = nullptr; // case await
|
||||
ppoolparam.pfunc = put_req_threadworker;
|
||||
|
||||
// send request by thread
|
||||
if(!ThreadPoolMan::AwaitInstruct(ppoolparam)){
|
||||
S3FS_PRN_ERR("failed to setup Put Request for Thread Worker");
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != thargs.result){
|
||||
// continue...
|
||||
S3FS_PRN_DBG("Put Request(%s) returns with errno(%d)", thargs.path.c_str(), thargs.result);
|
||||
}
|
||||
|
||||
// reset uploaded file size
|
||||
size_orgmeta = st.st_size;
|
||||
|
||||
untreated_list.ClearAll();
|
||||
|
||||
if(0 == result){
|
||||
if(0 == thargs.result){
|
||||
pagelist.ClearAllModified();
|
||||
}
|
||||
|
||||
return result;
|
||||
return thargs.result;
|
||||
}
|
||||
|
||||
//
|
||||
// ([TODO] This is a temporary modification till S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
{
|
||||
S3FS_PRN_INFO3("[tpath=%s][path=%s][pseudo_fd=%d][physical_fd=%d]", SAFESTRPTR(tpath), path.c_str(), (pseudo_obj ? pseudo_obj->GetPseudoFd() : -1), physical_fd);
|
||||
@ -1479,7 +1583,7 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
// Check rest size and free disk space
|
||||
if(0 < restsize && !ReserveDiskSpace(restsize)){
|
||||
// no enough disk space
|
||||
if(0 != (result = NoCachePreMultipartPost(pseudo_obj))){
|
||||
if(0 != (result = NoCachePreMultipartUploadRequest(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to switch multipart uploading with no cache(errno=%d)", result);
|
||||
return result;
|
||||
}
|
||||
@ -1518,8 +1622,31 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
|
||||
}else{
|
||||
// normal uploading (too small part size)
|
||||
S3fsCurl s3fscurl(true);
|
||||
result = s3fscurl.PutRequest(tpath ? tpath : tmppath.c_str(), tmporgmeta, physical_fd);
|
||||
|
||||
// parameter for thread worker
|
||||
put_req_thparam thargs;
|
||||
thargs.path = tpath ? tpath : tmppath;
|
||||
thargs.meta = tmporgmeta; // copy
|
||||
thargs.fd = physical_fd;
|
||||
thargs.ahbe = true;
|
||||
thargs.result = 0;
|
||||
|
||||
// make parameter for thread pool
|
||||
thpoolman_param ppoolparam;
|
||||
ppoolparam.args = &thargs;
|
||||
ppoolparam.psem = nullptr; // case await
|
||||
ppoolparam.pfunc = put_req_threadworker;
|
||||
|
||||
// send request by thread
|
||||
if(!ThreadPoolMan::AwaitInstruct(ppoolparam)){
|
||||
S3FS_PRN_ERR("failed to setup Put Request for Thread Worker");
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != thargs.result){
|
||||
// continue...
|
||||
S3FS_PRN_DBG("Put Request(%s) returns with errno(%d)", (tpath ? tpath : tmppath.c_str()), thargs.result);
|
||||
}
|
||||
result = thargs.result;
|
||||
}
|
||||
|
||||
// reset uploaded file size
|
||||
@ -1534,15 +1661,15 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
off_t untreated_start = 0;
|
||||
off_t untreated_size = 0;
|
||||
if(untreated_list.GetLastUpdatedPart(untreated_start, untreated_size, S3fsCurl::GetMultipartSize(), 0) && 0 < untreated_size){
|
||||
if(0 != (result = NoCacheMultipartPost(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart post(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadRequest(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart upload(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
return result;
|
||||
}
|
||||
untreated_list.ClearParts(untreated_start, untreated_size);
|
||||
}
|
||||
// complete multipart uploading.
|
||||
if(0 != (result = NoCacheCompleteMultipartPost(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to complete(finish) multipart post for file(physical_fd=%d).", physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadComplete(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to complete(finish) multipart upload for file(physical_fd=%d).", physical_fd);
|
||||
return result;
|
||||
}
|
||||
// truncate file to zero
|
||||
@ -1563,6 +1690,9 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// ([TODO] This is a temporary modification till S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
{
|
||||
S3FS_PRN_INFO3("[tpath=%s][path=%s][pseudo_fd=%d][physical_fd=%d]", SAFESTRPTR(tpath), path.c_str(), (pseudo_obj ? pseudo_obj->GetPseudoFd() : -1), physical_fd);
|
||||
@ -1582,7 +1712,7 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
// Check rest size and free disk space
|
||||
if(0 < restsize && !ReserveDiskSpace(restsize)){
|
||||
// no enough disk space
|
||||
if(0 != (result = NoCachePreMultipartPost(pseudo_obj))){
|
||||
if(0 != (result = NoCachePreMultipartUploadRequest(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to switch multipart uploading with no cache(errno=%d)", result);
|
||||
return result;
|
||||
}
|
||||
@ -1642,8 +1772,30 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
return result;
|
||||
}
|
||||
|
||||
S3fsCurl s3fscurl(true);
|
||||
result = s3fscurl.PutRequest(tpath ? tpath : tmppath.c_str(), tmporgmeta, physical_fd);
|
||||
// parameter for thread worker
|
||||
put_req_thparam thargs;
|
||||
thargs.path = tpath ? tpath : tmppath;
|
||||
thargs.meta = tmporgmeta; // copy
|
||||
thargs.fd = physical_fd;
|
||||
thargs.ahbe = true;
|
||||
thargs.result = 0;
|
||||
|
||||
// make parameter for thread pool
|
||||
thpoolman_param ppoolparam;
|
||||
ppoolparam.args = &thargs;
|
||||
ppoolparam.psem = nullptr; // case await
|
||||
ppoolparam.pfunc = put_req_threadworker;
|
||||
|
||||
// send request by thread
|
||||
if(!ThreadPoolMan::AwaitInstruct(ppoolparam)){
|
||||
S3FS_PRN_ERR("failed to setup Put Request for Thread Worker");
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != thargs.result){
|
||||
// continue...
|
||||
S3FS_PRN_DBG("Put Request(%s) returns with errno(%d)", (tpath ? tpath : tmppath.c_str()), thargs.result);
|
||||
}
|
||||
result = thargs.result;
|
||||
}
|
||||
|
||||
// reset uploaded file size
|
||||
@ -1658,15 +1810,15 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
off_t untreated_start = 0;
|
||||
off_t untreated_size = 0;
|
||||
if(untreated_list.GetLastUpdatedPart(untreated_start, untreated_size, S3fsCurl::GetMultipartSize(), 0) && 0 < untreated_size){
|
||||
if(0 != (result = NoCacheMultipartPost(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart post(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadRequest(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart upload(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
return result;
|
||||
}
|
||||
untreated_list.ClearParts(untreated_start, untreated_size);
|
||||
}
|
||||
// complete multipart uploading.
|
||||
if(0 != (result = NoCacheCompleteMultipartPost(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to complete(finish) multipart post for file(physical_fd=%d).", physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadComplete(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to complete(finish) multipart upload for file(physical_fd=%d).", physical_fd);
|
||||
return result;
|
||||
}
|
||||
// truncate file to zero
|
||||
@ -1687,6 +1839,9 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// ([TODO] This is a temporary modification till S3fsMultiCurl is deprecated.)
|
||||
//
|
||||
int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
|
||||
{
|
||||
S3FS_PRN_INFO3("[tpath=%s][path=%s][pseudo_fd=%d][physical_fd=%d][mix_upload=%s]", SAFESTRPTR(tpath), path.c_str(), (pseudo_obj ? pseudo_obj->GetPseudoFd() : -1), physical_fd, (FdEntity::mixmultipart ? "true" : "false"));
|
||||
@ -1713,9 +1868,30 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
|
||||
return result;
|
||||
}
|
||||
|
||||
headers_t tmporgmeta = orgmeta;
|
||||
S3fsCurl s3fscurl(true);
|
||||
result = s3fscurl.PutRequest(path.c_str(), tmporgmeta, physical_fd);
|
||||
// parameter for thread worker
|
||||
put_req_thparam thargs;
|
||||
thargs.path = path;
|
||||
thargs.meta = orgmeta; // copy
|
||||
thargs.fd = physical_fd;
|
||||
thargs.ahbe = true;
|
||||
thargs.result = 0;
|
||||
|
||||
// make parameter for thread pool
|
||||
thpoolman_param ppoolparam;
|
||||
ppoolparam.args = &thargs;
|
||||
ppoolparam.psem = nullptr; // case await
|
||||
ppoolparam.pfunc = put_req_threadworker;
|
||||
|
||||
// send request by thread
|
||||
if(!ThreadPoolMan::AwaitInstruct(ppoolparam)){
|
||||
S3FS_PRN_ERR("failed to setup Put Request for Thread Worker");
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != thargs.result){
|
||||
// continue...
|
||||
S3FS_PRN_DBG("Put Request(%s) returns with errno(%d)", path.c_str(), thargs.result);
|
||||
}
|
||||
result = thargs.result;
|
||||
|
||||
// reset uploaded file size
|
||||
size_orgmeta = st.st_size;
|
||||
@ -1785,19 +1961,9 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
|
||||
//
|
||||
// Multipart uploading hasn't started yet, so start it.
|
||||
//
|
||||
S3fsCurl s3fscurl(true);
|
||||
std::string upload_id;
|
||||
if(0 != (result = s3fscurl.PreMultipartPostRequest(path.c_str(), orgmeta, upload_id))){
|
||||
S3FS_PRN_ERR("failed to setup multipart upload(create upload id) by errno(%d)", result);
|
||||
if(0 != (result = PreMultipartUploadRequest(pseudo_obj))){
|
||||
return result;
|
||||
}
|
||||
if(!pseudo_obj->InitialUploadInfo(upload_id)){
|
||||
S3FS_PRN_ERR("failed to setup multipart upload(set upload id to object)");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// Clear the dirty flag, because the meta data is updated.
|
||||
pending_status = pending_status_t::NO_UPDATE_PENDING;
|
||||
}
|
||||
|
||||
//
|
||||
@ -1851,30 +2017,26 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
|
||||
// Complete uploading
|
||||
//
|
||||
std::string upload_id;
|
||||
etaglist_t etaglist;
|
||||
if(!pseudo_obj->GetUploadId(upload_id) || !pseudo_obj->GetEtaglist(etaglist)){
|
||||
etaglist_t parts;
|
||||
if(!pseudo_obj->GetUploadId(upload_id) || !pseudo_obj->GetEtaglist(parts)){
|
||||
S3FS_PRN_ERR("There is no upload id or etag list.");
|
||||
untreated_list.ClearAll();
|
||||
pseudo_obj->ClearUploadInfo(); // clear multipart upload info
|
||||
return -EIO;
|
||||
}else{
|
||||
S3fsCurl s3fscurl(true);
|
||||
result = s3fscurl.CompleteMultipartPostRequest(path.c_str(), upload_id, etaglist);
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
if(0 != result){
|
||||
if(0 != (result = complete_multipart_upload_request(path, upload_id, parts))){
|
||||
S3FS_PRN_ERR("failed to complete multipart upload by errno(%d)", result);
|
||||
untreated_list.ClearAll();
|
||||
pseudo_obj->ClearUploadInfo(); // clear multipart upload info
|
||||
|
||||
S3fsCurl s3fscurl_abort(true);
|
||||
int result2 = s3fscurl.AbortMultipartUpload(path.c_str(), upload_id);
|
||||
s3fscurl_abort.DestroyCurlHandle();
|
||||
if(0 != result2){
|
||||
int result2;
|
||||
if(0 != (result2 = abort_multipart_upload_request(path, upload_id))){
|
||||
S3FS_PRN_ERR("failed to abort multipart upload by errno(%d)", result2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
untreated_list.ClearAll();
|
||||
pseudo_obj->ClearUploadInfo(); // clear multipart upload info
|
||||
|
||||
@ -2126,7 +2288,7 @@ ssize_t FdEntity::WriteMultipart(PseudoFdInfo* pseudo_obj, const char* bytes, of
|
||||
S3FS_PRN_WARN("Not enough local storage to cache write request till multipart upload can start: [path=%s][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), physical_fd, static_cast<long long int>(start), size);
|
||||
return -ENOSPC; // No space left on device
|
||||
}
|
||||
if(0 != (result = NoCachePreMultipartPost(pseudo_obj))){
|
||||
if(0 != (result = NoCachePreMultipartUploadRequest(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to switch multipart uploading with no cache(errno=%d)", result);
|
||||
return result;
|
||||
}
|
||||
@ -2168,8 +2330,8 @@ ssize_t FdEntity::WriteMultipart(PseudoFdInfo* pseudo_obj, const char* bytes, of
|
||||
off_t untreated_size = 0;
|
||||
if(untreated_list.GetLastUpdatedPart(untreated_start, untreated_size, S3fsCurl::GetMultipartSize())){
|
||||
// when multipart max size is reached
|
||||
if(0 != (result = NoCacheMultipartPost(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart post(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadRequest(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart upload(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2210,7 +2372,7 @@ ssize_t FdEntity::WriteMixMultipart(PseudoFdInfo* pseudo_obj, const char* bytes,
|
||||
S3FS_PRN_WARN("Not enough local storage to cache write request till multipart upload can start: [path=%s][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), physical_fd, static_cast<long long int>(start), size);
|
||||
return -ENOSPC; // No space left on device
|
||||
}
|
||||
if(0 != (result = NoCachePreMultipartPost(pseudo_obj))){
|
||||
if(0 != (result = NoCachePreMultipartUploadRequest(pseudo_obj))){
|
||||
S3FS_PRN_ERR("failed to switch multipart uploading with no cache(errno=%d)", result);
|
||||
return result;
|
||||
}
|
||||
@ -2243,8 +2405,8 @@ ssize_t FdEntity::WriteMixMultipart(PseudoFdInfo* pseudo_obj, const char* bytes,
|
||||
off_t untreated_size = 0;
|
||||
if(untreated_list.GetLastUpdatedPart(untreated_start, untreated_size, S3fsCurl::GetMultipartSize())){
|
||||
// when multipart max size is reached
|
||||
if(0 != (result = NoCacheMultipartPost(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart post(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
if(0 != (result = NoCacheMultipartUploadRequest(pseudo_obj, physical_fd, untreated_start, untreated_size))){
|
||||
S3FS_PRN_ERR("failed to multipart upload(start=%lld, size=%lld) for file(physical_fd=%d).", static_cast<long long int>(untreated_start), static_cast<long long int>(untreated_size), physical_fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user