mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
eden: remove PassThru file handle usage
Summary: `creat(2)` and `open(2)` could decide to create a PassThru file handle. This diff removes that usage. There is a TODO here around handling `O_EXCL` properly. I'm punting this to a follow-up diff. Reviewed By: bolinfest Differential Revision: D3301387 fbshipit-source-id: d35104c536396e7fd064d786f3d5592ecfcbfecf
This commit is contained in:
parent
25dd9997d9
commit
88c1b44aab
@ -169,7 +169,9 @@ void FileData::materialize(int open_flags, RelativePathPiece path) {
|
||||
if (!file_) {
|
||||
try {
|
||||
// Test whether an overlay file exists by trying to open it.
|
||||
file_ = overlay_->openFile(path, O_RDWR, 0600);
|
||||
// O_NOFOLLOW because it never makes sense for the kernel to ask
|
||||
// a fuse server to open a file that is a symlink to something else.
|
||||
file_ = overlay_->openFile(path, O_RDWR | O_NOFOLLOW, 0600);
|
||||
// since we have a pre-existing overlay file, we don't need the blob.
|
||||
need_blob = false;
|
||||
} catch (const std::system_error& err) {
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "TreeEntryFileHandle.h"
|
||||
#include "eden/fs/overlay/Overlay.h"
|
||||
#include "eden/fs/store/LocalStore.h"
|
||||
#include "eden/fuse/passthru/PassThruInodes.h"
|
||||
|
||||
using folly::Future;
|
||||
using folly::StringPiece;
|
||||
@ -110,39 +109,19 @@ AbsolutePath TreeEntryFileInode::getLocalPath() const {
|
||||
|
||||
folly::Future<fusell::FileHandle*> TreeEntryFileInode::open(
|
||||
const struct fuse_file_info& fi) {
|
||||
if (!entry_) {
|
||||
auto localPath = getLocalPath();
|
||||
auto fd = ::open(localPath.c_str(), fi.flags);
|
||||
checkUnixError(fd);
|
||||
return new fusell::PassThruFileHandle(fd, ino_);
|
||||
}
|
||||
auto data = getOrLoadData();
|
||||
SCOPE_EXIT {
|
||||
data.reset();
|
||||
fileHandleDidClose();
|
||||
};
|
||||
data->materialize(
|
||||
fi.flags,
|
||||
fusell::InodeNameManager::get()->resolvePathToNode(getNodeId()));
|
||||
|
||||
switch (entry_->getFileType()) {
|
||||
case FileType::REGULAR_FILE: {
|
||||
auto data = getOrLoadData();
|
||||
SCOPE_EXIT {
|
||||
data.reset();
|
||||
fileHandleDidClose();
|
||||
};
|
||||
data->materialize(
|
||||
fi.flags,
|
||||
fusell::InodeNameManager::get()->resolvePathToNode(getNodeId()));
|
||||
|
||||
return new TreeEntryFileHandle(
|
||||
std::static_pointer_cast<TreeEntryFileInode>(shared_from_this()),
|
||||
data,
|
||||
fi.flags);
|
||||
}
|
||||
case FileType::SYMLINK:
|
||||
// man 2 open says: ELOOP ... or O_NOFOLLOW was specified but pathname
|
||||
// was a symbolic link.
|
||||
// We shouldn't really be able to get here in any case.
|
||||
folly::throwSystemErrorExplicit(ELOOP);
|
||||
default:
|
||||
// We really really should never be able to get here.
|
||||
folly::throwSystemErrorExplicit(
|
||||
EIO, "impossible filetype ", entry_->getFileType());
|
||||
}
|
||||
return new TreeEntryFileHandle(
|
||||
std::static_pointer_cast<TreeEntryFileInode>(shared_from_this()),
|
||||
data,
|
||||
fi.flags);
|
||||
}
|
||||
|
||||
Future<vector<string>> TreeEntryFileInode::listxattr() {
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "TreeInodeDirHandle.h"
|
||||
#include "eden/fs/overlay/Overlay.h"
|
||||
#include "eden/fs/store/LocalStore.h"
|
||||
#include "eden/fuse/passthru/PassThruInodes.h"
|
||||
#include "eden/utils/PathFuncs.h"
|
||||
|
||||
namespace facebook {
|
||||
@ -137,31 +136,45 @@ TreeInode::create(PathComponentPiece name, mode_t mode, int flags) {
|
||||
|
||||
// Ask the overlay manager to create it.
|
||||
auto file = overlay_->openFile(targetname, O_CREAT | flags, mode);
|
||||
// Discard the file handle and allow the FileData class to open it again.
|
||||
// We'll need to figure out something nicer than this in a follow-on diff
|
||||
// to make sure that O_EXCL|O_CREAT is working correctly.
|
||||
file.close();
|
||||
|
||||
// Generate an inode number for this new entry.
|
||||
auto node = fusell::InodeNameManager::get()->getNodeByName(ino_, name);
|
||||
|
||||
auto handle = std::make_unique<fusell::PassThruFileHandle>(
|
||||
file.release(), node->getNodeId());
|
||||
// build a corresponding TreeEntryFileInode
|
||||
auto inode = std::make_shared<TreeEntryFileInode>(
|
||||
node->getNodeId(),
|
||||
std::static_pointer_cast<TreeInode>(shared_from_this()),
|
||||
nullptr);
|
||||
|
||||
// Populate metadata.
|
||||
auto handle_ptr =
|
||||
handle.get(); // need to get this before move handle into the lambda.
|
||||
return handle_ptr->getattr().then(
|
||||
[ =, handle = std::move(handle) ](fusell::Dispatcher::Attr attr) mutable {
|
||||
fusell::DirInode::CreateResult result;
|
||||
fuse_file_info fi;
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
|
||||
result.inode = std::make_shared<TreeEntryFileInode>(
|
||||
node->getNodeId(),
|
||||
std::static_pointer_cast<TreeInode>(shared_from_this()),
|
||||
nullptr);
|
||||
// The kernel wants an open operation to return the inode,
|
||||
// the file handle and some attribute information.
|
||||
// Let's open a file handle now.
|
||||
return inode->open(fi).then([=](fusell::FileHandle* handle_ptr) {
|
||||
// Capture the handle into a unique_ptr so that we can ensure caleanup.
|
||||
// This will be removed when we remove the naked pointers in a followup.
|
||||
std::unique_ptr<fusell::FileHandle> handle(handle_ptr);
|
||||
|
||||
result.file = std::move(handle);
|
||||
result.attr = attr;
|
||||
result.node = node;
|
||||
// Now that we have the file handle, let's look up the attributes.
|
||||
return handle_ptr->getattr().then([ =, handle = std::move(handle) ](
|
||||
fusell::Dispatcher::Attr attr) mutable {
|
||||
fusell::DirInode::CreateResult result;
|
||||
|
||||
return result;
|
||||
});
|
||||
// Return all of the results back to the kernel.
|
||||
result.inode = inode;
|
||||
result.file = std::move(handle);
|
||||
result.attr = attr;
|
||||
result.node = node;
|
||||
|
||||
return result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<LocalStore> TreeInode::getStore() const {
|
||||
|
Loading…
Reference in New Issue
Block a user