Skip to content

Commit 7ce5f06

Browse files
authored
Merge pull request #42 from liuyongqing/master
fix data corruption about move file over limit of ensure space
2 parents 657549a + 19dc9c6 commit 7ce5f06

File tree

7 files changed

+887
-576
lines changed

7 files changed

+887
-576
lines changed

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
dnl Process this file with autoconf to produce a configure script.
2222

2323
AC_PREREQ(2.59)
24-
AC_INIT(cosfs, 1.0.18)
24+
AC_INIT(cosfs, 1.0.19)
2525
AC_CONFIG_HEADER([config.h])
2626

2727
AC_CANONICAL_SYSTEM

src/fdcache.cpp

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,8 @@ int FdEntity::FillFile(int fd, unsigned char byte, size_t size, off_t start)
617617
//------------------------------------------------
618618
FdEntity::FdEntity(const char* tpath, const char* cpath)
619619
: is_lock_init(false), refcnt(0), path(SAFESTRPTR(tpath)), cachepath(SAFESTRPTR(cpath)),
620-
fd(-1), pfile(NULL), is_modify(false), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0)
620+
fd(-1), pfile(NULL), is_modify(false), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0),
621+
is_meta_pending(false)
621622
{
622623
try{
623624
pthread_mutexattr_t attr;
@@ -892,14 +893,33 @@ bool FdEntity::GetStats(struct stat& st)
892893
return true;
893894
}
894895

895-
int FdEntity::SetMtime(time_t time)
896+
bool FdEntity::GetXattr(std::string& xattr)
897+
{
898+
AutoLock auto_lock(&fdent_lock);
899+
900+
headers_t::const_iterator iter = orgmeta.find("x-cos-meta-xattr");
901+
if(iter == orgmeta.end()){
902+
return false;
903+
}
904+
xattr = iter->second;
905+
return true;
906+
}
907+
908+
bool FdEntity::SetXattr(const std::string& xattr)
909+
{
910+
AutoLock auto_lock(&fdent_lock);
911+
orgmeta["x-cos-meta-xattr"] = xattr;
912+
return true;
913+
}
914+
915+
int FdEntity::SetMtime(time_t time, bool lock_already_held)
896916
{
897917
S3FS_PRN_INFO3("[path=%s][fd=%d][time=%jd]", path.c_str(), fd, (intmax_t)time);
898918

899919
if(-1 == time){
900920
return 0;
901921
}
902-
AutoLock auto_lock(&fdent_lock);
922+
AutoLock auto_lock(&fdent_lock, lock_already_held ? AutoLock::ALREADY_LOCKED : AutoLock::NONE);
903923
if(-1 != fd){
904924

905925
struct timeval tv[2];
@@ -1410,6 +1430,10 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
14101430
// So the file has already been removed, skip error.
14111431
S3FS_PRN_ERR("failed to truncate file(%d) to zero, but continue...", fd);
14121432
}
1433+
// put pending headers
1434+
if(0 != (result = UploadPendingMeta())){
1435+
return result;
1436+
}
14131437
}
14141438

14151439
if(0 == result){
@@ -1561,6 +1585,63 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
15611585
return wsize;
15621586
}
15631587

1588+
1589+
// [NOTE]
1590+
// Returns true if merged to orgmeta.
1591+
// If true is returned, the caller can update the header.
1592+
// If it is false, do not update the header because multipart upload is in progress.
1593+
// In this case, the header is pending internally and is updated after the upload
1594+
// is complete(flush file).
1595+
//
1596+
bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
1597+
{
1598+
AutoLock auto_lock(&fdent_lock);
1599+
1600+
merge_headers(orgmeta, updatemeta, true); // overwrite all keys
1601+
// [NOTE]
1602+
// this is special cases, we remove the key which has empty values.
1603+
for(headers_t::iterator hiter = orgmeta.begin(); hiter != orgmeta.end(); ){
1604+
if(hiter->second.empty()){
1605+
orgmeta.erase(hiter++);
1606+
}else{
1607+
++hiter;
1608+
}
1609+
}
1610+
updatemeta = orgmeta;
1611+
orgmeta.erase("x-cos-copy-source");
1612+
1613+
// update ctime/mtime
1614+
time_t updatetime = get_mtime(updatemeta, false); // not overcheck
1615+
if(0 != updatetime){
1616+
SetMtime(updatetime, true);
1617+
}
1618+
is_meta_pending |= !upload_id.empty();
1619+
1620+
return is_meta_pending;
1621+
}
1622+
1623+
1624+
// global function in s3fs.cpp
1625+
int put_headers(const char* path, headers_t& meta, bool is_copy, bool update_mtime);
1626+
1627+
int FdEntity::UploadPendingMeta()
1628+
{
1629+
if(!is_meta_pending) {
1630+
return 0;
1631+
}
1632+
AutoLock auto_lock(&fdent_lock);
1633+
1634+
headers_t updatemeta = orgmeta;
1635+
updatemeta["x-cos-copy-source"] = urlEncode(service_path + bucket + "-" + appid + get_realpath(path.c_str()));
1636+
// put headers, no need to update mtime to avoid dead lock
1637+
int result = put_headers(path.c_str(), updatemeta, true, false);
1638+
if(0 != result){
1639+
S3FS_PRN_ERR("failed to put header after flushing file(%s) by(%d).", path.c_str(), result);
1640+
}
1641+
is_meta_pending = false;
1642+
1643+
return result;
1644+
}
15641645
//------------------------------------------------
15651646
// FdManager symbol
15661647
//------------------------------------------------

src/fdcache.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class FdEntity
126126
etaglist_t etaglist; // for no cached multipart uploading when no disk space
127127
off_t mp_start; // start position for no cached multipart(write method only)
128128
size_t mp_size; // size for no cached multipart(write method only)
129+
bool is_meta_pending;
129130

130131
private:
131132
static int FillFile(int fd, unsigned char byte, size_t size, off_t start);
@@ -134,6 +135,8 @@ class FdEntity
134135
bool SetAllStatus(bool is_loaded); // [NOTE] not locking
135136
//bool SetAllStatusLoaded(void) { return SetAllStatus(true); }
136137
bool SetAllStatusUnloaded(void) { return SetAllStatus(false); }
138+
int UploadPendingMeta(void);
139+
137140

138141
public:
139142
explicit FdEntity(const char* tpath = NULL, const char* cpath = NULL);
@@ -150,13 +153,16 @@ class FdEntity
150153
int GetFd(void) const { return fd; }
151154

152155
bool GetStats(struct stat& st);
153-
int SetMtime(time_t time);
156+
int SetMtime(time_t time, bool lock_already_held = false);
154157
bool UpdateMtime(void);
155158
bool GetSize(size_t& size);
156159
bool SetMode(mode_t mode);
157160
bool SetUId(uid_t uid);
158161
bool SetGId(gid_t gid);
159162
bool SetContentType(const char* path);
163+
bool GetXattr(std::string& xattr);
164+
bool SetXattr(const std::string& xattr);
165+
bool MergeOrgMeta(headers_t& updatemeta);
160166

161167
int Load(off_t start = 0, size_t size = 0); // size=0 means loading to end
162168
int NoCacheLoadAndPost(off_t start = 0, size_t size = 0); // size=0 means loading to end

0 commit comments

Comments
 (0)