Merge pull request #893 from gaul/ctime

Store and retrieve file change time
This commit is contained in:
Takeshi Nakatani 2019-01-16 18:30:15 +09:00 committed by GitHub
commit ddba1c63c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 12 deletions

View File

@ -620,6 +620,9 @@ bool convert_header_to_stat(const char* path, headers_t& meta, struct stat* pst,
// mtime
pst->st_mtime = get_mtime(meta);
// ctime
pst->st_ctime = get_ctime(meta);
// size
pst->st_size = get_size(meta);

View File

@ -1050,11 +1050,23 @@ int FdEntity::SetMtime(time_t time)
return -errno;
}
}
orgmeta["x-amz-meta-ctime"] = str(time);
orgmeta["x-amz-meta-mtime"] = str(time);
return 0;
}
bool FdEntity::UpdateCtime(void)
{
AutoLock auto_lock(&fdent_lock);
struct stat st;
if(!GetStats(st)){
return false;
}
orgmeta["x-amz-meta-ctime"] = str(st.st_ctime);
return true;
}
bool FdEntity::UpdateMtime(void)
{
AutoLock auto_lock(&fdent_lock);
@ -1062,6 +1074,7 @@ bool FdEntity::UpdateMtime(void)
if(!GetStats(st)){
return false;
}
orgmeta["x-amz-meta-ctime"] = str(st.st_ctime);
orgmeta["x-amz-meta-mtime"] = str(st.st_mtime);
return true;
}

View File

@ -155,6 +155,7 @@ class FdEntity
bool GetStats(struct stat& st);
int SetMtime(time_t time);
bool UpdateCtime(void);
bool UpdateMtime(void);
bool GetSize(size_t& size);
bool SetMode(mode_t mode);

View File

@ -963,12 +963,14 @@ static int create_file_object(const char* path, mode_t mode, uid_t uid, gid_t gi
{
S3FS_PRN_INFO2("[path=%s][mode=%04o]", path, mode);
time_t now = time(NULL);
headers_t meta;
meta["Content-Type"] = S3fsCurl::LookupMimeType(string(path));
meta["x-amz-meta-uid"] = str(uid);
meta["x-amz-meta-gid"] = str(gid);
meta["x-amz-meta-mode"] = str(mode);
meta["x-amz-meta-mtime"] = str(time(NULL));
meta["x-amz-meta-ctime"] = str(now);
meta["x-amz-meta-mtime"] = str(now);
S3fsCurl s3fscurl(true);
return s3fscurl.PutRequest(path, meta, -1); // fd=-1 means for creating zero byte object.
@ -1055,6 +1057,7 @@ static int create_directory_object(const char* path, mode_t mode, time_t time, u
meta["x-amz-meta-uid"] = str(uid);
meta["x-amz-meta-gid"] = str(gid);
meta["x-amz-meta-mode"] = str(mode);
meta["x-amz-meta-ctime"] = str(time);
meta["x-amz-meta-mtime"] = str(time);
S3fsCurl s3fscurl;
@ -1199,10 +1202,12 @@ static int s3fs_symlink(const char* from, const char* to)
return result;
}
time_t now = time(NULL);
headers_t headers;
headers["Content-Type"] = string("application/octet-stream"); // Static
headers["x-amz-meta-mode"] = str(S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
headers["x-amz-meta-mtime"] = str(time(NULL));
headers["x-amz-meta-ctime"] = str(now);
headers["x-amz-meta-mtime"] = str(now);
headers["x-amz-meta-uid"] = str(pcxt->uid);
headers["x-amz-meta-gid"] = str(pcxt->gid);
@ -1591,6 +1596,7 @@ static int s3fs_chmod(const char* path, mode_t mode)
}
}else{
// normal object or directory object of newer version
meta["x-amz-meta-ctime"] = str(time(NULL));
meta["x-amz-meta-mode"] = str(mode);
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
meta["x-amz-metadata-directive"] = "REPLACE";
@ -1607,6 +1613,7 @@ static int s3fs_chmod(const char* path, mode_t mode)
//
FdEntity* ent;
if(NULL != (ent = FdManager::get()->ExistOpen(path))){
ent->UpdateCtime();
ent->SetMode(mode); // Set new mode to opened fd.
FdManager::get()->Close(ent);
}
@ -1747,6 +1754,7 @@ static int s3fs_chown(const char* path, uid_t uid, gid_t gid)
return result;
}
}else{
meta["x-amz-meta-ctime"] = str(time(NULL));
meta["x-amz-meta-uid"] = str(uid);
meta["x-amz-meta-gid"] = str(gid);
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
@ -2032,9 +2040,11 @@ static int s3fs_truncate(const char* path, off_t size)
if(NULL == (pcxt = fuse_get_context())){
return -EIO;
}
time_t now = time(NULL);
meta["Content-Type"] = string("application/octet-stream"); // Static
meta["x-amz-meta-mode"] = str(S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
meta["x-amz-meta-mtime"] = str(time(NULL));
meta["x-amz-meta-ctime"] = str(now);
meta["x-amz-meta-mtime"] = str(now);
meta["x-amz-meta-uid"] = str(pcxt->uid);
meta["x-amz-meta-gid"] = str(pcxt->gid);
@ -3103,6 +3113,7 @@ static int s3fs_setxattr(const char* path, const char* name, const char* value,
}
// set xattr all object
meta["x-amz-meta-ctime"] = str(time(NULL));
meta["x-amz-copy-source"] = urlEncode(service_path + bucket + get_realpath(strpath.c_str()));
meta["x-amz-metadata-directive"] = "REPLACE";

View File

@ -753,10 +753,10 @@ time_t get_mtime(const char *s)
return static_cast<time_t>(s3fs_strtoofft(s));
}
time_t get_mtime(headers_t& meta, bool overcheck)
static time_t get_time(headers_t& meta, bool overcheck, const char *header)
{
headers_t::const_iterator iter;
if(meta.end() == (iter = meta.find("x-amz-meta-mtime"))){
if(meta.end() == (iter = meta.find(header))){
if(overcheck){
return get_lastmodified(meta);
}
@ -765,6 +765,16 @@ time_t get_mtime(headers_t& meta, bool overcheck)
return get_mtime((*iter).second.c_str());
}
time_t get_mtime(headers_t& meta, bool overcheck)
{
return get_time(meta, overcheck, "x-amz-meta-mtime");
}
time_t get_ctime(headers_t& meta, bool overcheck)
{
return get_time(meta, overcheck, "x-amz-meta-ctime");
}
off_t get_size(const char *s)
{
return s3fs_strtoofft(s);

View File

@ -119,6 +119,7 @@ bool delete_files_in_dir(const char* dir, bool is_remove_own);
time_t get_mtime(const char *s);
time_t get_mtime(headers_t& meta, bool overcheck = true);
time_t get_ctime(headers_t& meta, bool overcheck = true);
off_t get_size(const char *s);
off_t get_size(headers_t& meta);
mode_t get_mode(const char *s);

View File

@ -400,13 +400,8 @@ function test_mtime_file {
#copy the test file with preserve mode
cp -p $TEST_TEXT_FILE $ALT_TEST_TEXT_FILE
if [ `uname` = "Darwin" ]; then
testmtime=`stat -f "%m" $TEST_TEXT_FILE`
altmtime=`stat -f "%m" $ALT_TEST_TEXT_FILE`
else
testmtime=`stat -c %Y $TEST_TEXT_FILE`
altmtime=`stat -c %Y $ALT_TEST_TEXT_FILE`
fi
testmtime=`get_mtime $TEST_TEXT_FILE`
altmtime=`get_mtime $ALT_TEST_TEXT_FILE`
if [ "$testmtime" -ne "$altmtime" ]
then
echo "File times do not match: $testmtime != $altmtime"
@ -414,6 +409,61 @@ function test_mtime_file {
fi
}
function test_update_time() {
describe "Testing update time function ..."
# create the test
mk_test_file
mtime=`get_ctime $TEST_TEXT_FILE`
ctime=`get_mtime $TEST_TEXT_FILE`
sleep 2
chmod +x $TEST_TEXT_FILE
ctime2=`get_ctime $TEST_TEXT_FILE`
mtime2=`get_mtime $TEST_TEXT_FILE`
if [ $ctime -eq $ctime2 -o $mtime -ne $mtime2 ]; then
echo "Expected updated ctime: $ctime != $ctime2 and same mtime: $mtime == $mtime2"
return 1
fi
sleep 2
chown $UID:$UID $TEST_TEXT_FILE;
ctime3=`get_ctime $TEST_TEXT_FILE`
mtime3=`get_mtime $TEST_TEXT_FILE`
if [ $ctime2 -eq $ctime3 -o $mtime2 -ne $mtime3 ]; then
echo "Expected updated ctime: $ctime2 != $ctime3 and same mtime: $mtime2 == $mtime3"
return 1
fi
if command -v setfattr >/dev/null 2>&1; then
sleep 2
setfattr -n key -v value $TEST_TEXT_FILE
ctime4=`get_ctime $TEST_TEXT_FILE`
mtime4=`get_mtime $TEST_TEXT_FILE`
if [ $ctime3 -eq $ctime4 -o $mtime3 -ne $mtime4 ]; then
echo "Expected updated ctime: $ctime3 != $ctime4 and same mtime: $mtime3 == $mtime4"
return 1
fi
else
echo "Skipping extended attribute test"
ctime4=`get_ctime $TEST_TEXT_FILE`
mtime4=`get_mtime $TEST_TEXT_FILE`
fi
sleep 2
echo foo >> $TEST_TEXT_FILE
ctime5=`get_ctime $TEST_TEXT_FILE`
mtime5=`get_mtime $TEST_TEXT_FILE`
if [ $ctime4 -eq $ctime5 -o $mtime4 -eq $mtime5 ]; then
echo "Expected updated ctime: $ctime4 != $ctime5 and updated mtime: $mtime4 != $mtime5"
return 1
fi
}
function test_rm_rf_dir {
describe "Test that rm -rf will remove directory with contents"
# Create a dir with some files and directories
@ -458,6 +508,7 @@ function add_all_tests {
add_tests test_symlink
add_tests test_extended_attributes
add_tests test_mtime_file
add_tests test_update_time
add_tests test_rm_rf_dir
add_tests test_write_after_seek_ahead
}

View File

@ -169,3 +169,19 @@ function run_suite {
return 0
fi
}
function get_ctime() {
if [ `uname` = "Darwin" ]; then
stat -f "%c" "$1"
else
stat -c %Z "$1"
fi
}
function get_mtime() {
if [ `uname` = "Darwin" ]; then
stat -f "%m" "$1"
else
stat -c %Y "$1"
fi
}