@@ -617,7 +617,8 @@ int FdEntity::FillFile(int fd, unsigned char byte, size_t size, off_t start)
617617// ------------------------------------------------
618618FdEntity::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// ------------------------------------------------
0 commit comments