Skip to content

Commit 41300ca

Browse files
committed
FUSEX: add the online editing hack for windows with fake deletion and versioning on rename - fixes EOS-6400
1 parent 7766a9e commit 41300ca

4 files changed

Lines changed: 37 additions & 1 deletion

File tree

fusex/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ This
6262
"leasetime" : 300,
6363
"write-size-flush-interval" : 10,
6464
"submounts" : 0,
65-
"inmemory-inodes" : 16384
65+
"inmemory-inodes" : 16384,
66+
"tmp-fake-delete" : false,
6667
},
6768
"auth" : {
6869
"shared-mount" : 1,

fusex/eosxd/eosfuse.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,13 @@ EosFuse::run(int argc, char* argv[], void* userdata)
10641064
config.options.x_ok = X_OK;
10651065
}
10661066

1067+
config.options.fakedelete = false;
1068+
if (root["options"].isMember("tmp-fake-delete")) {
1069+
if (root["options"]["tmp-fake-delete"]) {
1070+
config.options.fakedelete = true;
1071+
}
1072+
}
1073+
10671074
config.options.fdlimit = root["options"]["fd-limit"].asInt();
10681075
config.options.rm_rf_protect_levels =
10691076
root["options"]["rm-rf-protect-levels"].asInt();
@@ -4231,6 +4238,17 @@ EROFS pathname refers to a file on a read-only filesystem.
42314238
}
42324239
}
42334240

4241+
4242+
// fake deletion logic for online editing if configured
4243+
if (Instance().Config().options.fakedelete && (*pmd)()->tmptime()) {
4244+
auto now = time(NULL);
4245+
if ( (now - (*pmd)()->tmptime()) < 60 ) {
4246+
(*pmd)()->set_tmptime(0);
4247+
fuse_reply_err(req, rc);
4248+
return ;
4249+
}
4250+
}
4251+
42344252
if (!rc) {
42354253
if (attrMap.count(k_mdino)) { /* This is a hard link */
42364254
uint64_t mdino = std::stoull(attrMap[k_mdino]);
@@ -5096,6 +5114,21 @@ The O_NONBLOCK flag was specified, and an incompatible lease was held on the fil
50965114
(*pmd)()->set_mtime(ts.tv_sec);
50975115
(*pmd)()->set_mtime_ns(ts.tv_nsec);
50985116

5117+
auto ends_with = [](const std::string& str, const std::string& suffix) {
5118+
return str.size() >= suffix.size() &&
5119+
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
5120+
};
5121+
5122+
if (ends_with( (*md)()->name(), ".tmp")) {
5123+
if (Instance().Config().options.fakedelete) {
5124+
// set rename creates version attribute on parent
5125+
auto map = (*pmd)()->mutable_attr();
5126+
(*map)["user.fusex.rename.version"]="1";
5127+
// store last tmpe file creation time
5128+
(*pmd)()->set_tmptime(time(NULL));
5129+
}
5130+
}
5131+
50995132
// get file inline size from parent attribute
51005133
if ((*pmd)()->attr().count("sys.file.inline.maxsize")) {
51015134
auto maxsize = (*(*pmd)()->mutable_attr())["sys.file.inline.maxsize"];

fusex/eosxd/eosfuse.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public:
289289
std::vector<std::string> no_fsync_suffixes;
290290
std::vector<std::string> nowait_flush_executables;
291291
bool protect_directory_symlink_loops;
292+
bool fakedelete;
292293
} options_t;
293294

294295
typedef struct recovery {

fusex/fusex.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ message md {
5252
string mv_authid = 42; //< indicates the authid applying to the source directory of a mv
5353
fixed64 bc_time = 43; //< indicates the reception time of a broadcasted md record
5454
FLAG opflags = 44; //< indicates a flag for an operation
55+
fixed64 tmptime = 45 ; //< last time a .tmp file was created
5556
};
5657

5758
message md_state {

0 commit comments

Comments
 (0)