Skip to content

Commit

Permalink
fuse: implement rename within directory boundary
Browse files Browse the repository at this point in the history
  • Loading branch information
whoozle committed Dec 12, 2020
1 parent 8f643d2 commit 140beb4
Showing 1 changed file with 50 additions and 11 deletions.
61 changes: 50 additions & 11 deletions fuse/fuse_ll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,6 @@ namespace
FUSE_CALL(fuse_reply_err(req, 0));
}

void Rename(fuse_req_t req, FuseId parent, const char *name, FuseId newparent, const char *newname)
{
fuse_reply_err(req, EXDEV); //return cross-device link, so user space should re-create file and copy it
}

void SetAttr(fuse_req_t req, FuseId inode, struct stat *attr, int to_set, struct fuse_file_info *fi)
{
mtp::scoped_mutex_lock l(_mutex);
Expand All @@ -623,11 +618,46 @@ namespace
entry.ReplyError(ENOENT);
}

void UnlinkImpl(FuseId inode)
{
mtp::debug(" unlinking inode ", inode.Inode);
mtp::ObjectId id = FromFuse(inode);
_session->DeleteObject(id);
_openedFiles.erase(inode);
_objectAttrs.erase(id);
}

void Unlink(fuse_req_t req, FuseId parent, const char *name)
{
mtp::scoped_mutex_lock l(_mutex);
ChildrenObjects &children = GetChildren(parent);
auto i = children.find(name);
if (i == children.end())
{
FUSE_CALL(fuse_reply_err(req, ENOENT));
return;
}

FuseId inode = i->second;
UnlinkImpl(inode);
_directoryCache.erase(parent);
children.erase(i);

FUSE_CALL(fuse_reply_err(req, 0));
}

void RemoveDir (fuse_req_t req, FuseId parent, const char *name)
{ Unlink(req, parent, name); }

void Unlink(fuse_req_t req, FuseId parent, const char *name)
void Rename(fuse_req_t req, FuseId parent, const char *name, FuseId newparent, const char *newName)
{
if (parent != newparent) {
//no renames across directory boundary, sorry
//return cross-device link, so user space should re-create file and copy it
FUSE_CALL(fuse_reply_err(req, EXDEV));
return;
}

mtp::scoped_mutex_lock l(_mutex);
ChildrenObjects &children = GetChildren(parent);
auto i = children.find(name);
Expand All @@ -638,14 +668,23 @@ namespace
}

FuseId inode = i->second;
mtp::debug(" unlinking inode ", inode.Inode);
mtp::debug(" renaming inode ", inode.Inode, " to ", newName);

auto old = children.find(newName);
if (old != children.end())
{
mtp::debug(" unlinking target inode ", old->second.Inode);
UnlinkImpl(old->second);
children.erase(old);
}

mtp::ObjectId id = FromFuse(inode);
_directoryCache.erase(parent);
_openedFiles.erase(inode);
_objectAttrs.erase(id);
_session->SetObjectProperty(id, mtp::ObjectProperty::ObjectFilename, std::string(newName));

children.erase(i);
children.emplace(newName, inode);
_directoryCache.erase(parent);

_session->DeleteObject(id);
FUSE_CALL(fuse_reply_err(req, 0));
}

Expand Down

0 comments on commit 140beb4

Please sign in to comment.