add chmod and stat to IDisk

This commit is contained in:
Alexander Tokmakov 2022-08-03 17:43:14 +02:00
parent f144eae388
commit b8ffaabdd8
16 changed files with 140 additions and 0 deletions

View File

@ -99,6 +99,12 @@ public:
void syncRevision(UInt64 revision) override { delegate->syncRevision(revision); }
UInt64 getRevision() const override { return delegate->getRevision(); }
bool supportsStat() const override { return delegate->supportsStat(); }
struct stat stat(const String & path) const override { return delegate->stat(path); }
bool supportsChmod() const override { return delegate->supportsChmod(); }
void chmod(const String & path, mode_t mode) override { delegate->chmod(path, mode); }
protected:
Executor & getExecutor() override;

View File

@ -11,6 +11,8 @@
#include <fstream>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <Disks/DiskFactory.h>
#include <Disks/DiskMemory.h>
@ -39,6 +41,7 @@ namespace ErrorCodes
extern const int CANNOT_UNLINK;
extern const int CANNOT_RMDIR;
extern const int BAD_ARGUMENTS;
extern const int CANNOT_STAT;
}
std::mutex DiskLocal::reservation_mutex;
@ -671,6 +674,23 @@ bool DiskLocal::setup()
return true;
}
struct stat DiskLocal::stat(const String & path) const
{
struct stat st;
auto full_path = fs::path(disk_path) / path;
if (::stat(full_path.string().c_str(), &st) == 0)
return st;
DB::throwFromErrnoWithPath("Cannot stat file: " + path, path, DB::ErrorCodes::CANNOT_STAT);
}
void DiskLocal::chmod(const String & path, mode_t mode)
{
auto full_path = fs::path(disk_path) / path;
if (::chmod(full_path.string().c_str(), mode) == 0)
return;
DB::throwFromErrnoWithPath("Cannot chmod file: " + path, path, DB::ErrorCodes::PATH_ACCESS_DENIED);
}
void registerDiskLocal(DiskFactory & factory)
{
auto creator = [](const String & name,

View File

@ -122,6 +122,12 @@ public:
bool canRead() const noexcept;
bool canWrite() const noexcept;
bool supportsStat() const override { return true; }
struct stat stat(const String & path) const override;
bool supportsChmod() const override { return true; }
void chmod(const String & path, mode_t mode) override;
private:
std::optional<UInt64> tryReserve(UInt64 bytes);

View File

@ -112,6 +112,11 @@ public:
disk.setLastModified(path, timestamp);
}
void chmod(const String & path, mode_t mode) override
{
disk.chmod(path, mode);
}
void setReadOnly(const std::string & path) override
{
disk.setReadOnly(path);

View File

@ -351,6 +351,12 @@ public:
getType());
}
virtual bool supportsStat() const { return false; }
virtual struct stat stat(const String & /*path*/) const { throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Disk does not support stat"); }
virtual bool supportsChmod() const { return false; }
virtual void chmod(const String & /*path*/, mode_t /*mode*/) { throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Disk does not support chmod"); }
protected:
friend class DiskDecorator;

View File

@ -103,6 +103,9 @@ public:
/// Set last modified time to file or directory at `path`.
virtual void setLastModified(const std::string & path, const Poco::Timestamp & timestamp) = 0;
/// Just chmod.
virtual void chmod(const String & path, mode_t mode) = 0;
/// Set file at `path` as read-only.
virtual void setReadOnly(const std::string & path) = 0;

View File

@ -367,6 +367,18 @@ time_t DiskObjectStorage::getLastChanged(const String & path) const
return metadata_storage->getLastChanged(path);
}
struct stat DiskObjectStorage::stat(const String & path) const
{
return metadata_storage->stat(path);
}
void DiskObjectStorage::chmod(const String & path, mode_t mode)
{
auto transaction = createObjectStorageTransaction();
transaction->chmod(path, mode);
transaction->commit();
}
void DiskObjectStorage::shutdown()
{
LOG_INFO(log, "Shutting down disk {}", name);

View File

@ -168,6 +168,12 @@ public:
bool supportsCache() const override;
bool supportsStat() const override { return metadata_storage->supportsStat(); }
struct stat stat(const String & path) const override;
bool supportsChmod() const override { return metadata_storage->supportsChmod(); }
void chmod(const String & path, mode_t mode) override;
private:
/// Create actual disk object storage transaction for operations

View File

@ -613,6 +613,15 @@ void DiskObjectStorageTransaction::setLastModified(const std::string & path, con
}));
}
void DiskObjectStorageTransaction::chmod(const String & path, mode_t mode)
{
operations_to_execute.emplace_back(
std::make_unique<PureMetadataObjectStorageOperation>(object_storage, metadata_storage, [path, mode](MetadataTransactionPtr tx)
{
tx->chmod(path, mode);
}));
}
void DiskObjectStorageTransaction::createFile(const std::string & path)
{
operations_to_execute.emplace_back(

View File

@ -109,6 +109,7 @@ public:
void removeSharedFiles(const RemoveBatchRequest & files, bool keep_all_batch_data, const NameSet & file_names_remove_metadata_only) override;
void setLastModified(const std::string & path, const Poco::Timestamp & timestamp) override;
void chmod(const String & path, mode_t mode) override;
void setReadOnly(const std::string & path) override;
void createHardLink(const std::string & src_path, const std::string & dst_path) override;
};

View File

@ -42,6 +42,12 @@ public:
time_t getLastChanged(const std::string & path) const override;
bool supportsChmod() const override { return disk->supportsChmod(); }
bool supportsStat() const override { return disk->supportsStat(); }
struct stat stat(const String & path) const override { return disk->stat(path); }
std::vector<std::string> listDirectory(const std::string & path) const override;
DirectoryIteratorPtr iterateDirectory(const std::string & path) const override;
@ -89,6 +95,10 @@ public:
void setLastModified(const std::string & path, const Poco::Timestamp & timestamp) override;
bool supportsChmod() const override { return disk->supportsChmod(); }
void chmod(const String & path, mode_t mode) override { disk->chmod(path, mode); }
void setReadOnly(const std::string & path) override;
void unlinkFile(const std::string & path) override;

View File

@ -37,6 +37,9 @@ public:
virtual void setLastModified(const std::string & path, const Poco::Timestamp & timestamp) = 0;
virtual bool supportsChmod() const = 0;
virtual void chmod(const String & path, mode_t mode) = 0;
virtual void setReadOnly(const std::string & path) = 0;
virtual void unlinkFile(const std::string & path) = 0;
@ -107,6 +110,11 @@ public:
virtual time_t getLastChanged(const std::string & path) const = 0;
virtual bool supportsChmod() const = 0;
virtual bool supportsStat() const = 0;
virtual struct stat stat(const String & path) const = 0;
virtual std::vector<std::string> listDirectory(const std::string & path) const = 0;
virtual DirectoryIteratorPtr iterateDirectory(const std::string & path) const = 0;

View File

@ -250,6 +250,11 @@ void MetadataStorageFromDiskTransaction::setLastModified(const std::string & pat
addOperation(std::make_unique<SetLastModifiedOperation>(path, timestamp, *metadata_storage.getDisk()));
}
void MetadataStorageFromDiskTransaction::chmod(const String & path, mode_t mode)
{
addOperation(std::make_unique<ChmodOperation>(path, mode, *metadata_storage.getDisk()));
}
void MetadataStorageFromDiskTransaction::unlinkFile(const std::string & path)
{
addOperation(std::make_unique<UnlinkFileOperation>(path, *metadata_storage.getDisk()));

View File

@ -39,6 +39,12 @@ public:
time_t getLastChanged(const std::string & path) const override;
bool supportsChmod() const override { return disk->supportsChmod(); }
bool supportsStat() const override { return disk->supportsStat(); }
struct stat stat(const String & path) const override { return disk->stat(path); }
std::vector<std::string> listDirectory(const std::string & path) const override;
DirectoryIteratorPtr iterateDirectory(const std::string & path) const override;
@ -94,6 +100,10 @@ public:
void setLastModified(const std::string & path, const Poco::Timestamp & timestamp) override;
bool supportsChmod() const override { return metadata_storage.supportsChmod(); }
void chmod(const String & path, mode_t mode) override;
void setReadOnly(const std::string & path) override;
void unlinkFile(const std::string & path) override;

View File

@ -36,6 +36,24 @@ void SetLastModifiedOperation::undo()
disk.setLastModified(path, old_timestamp);
}
ChmodOperation::ChmodOperation(const std::string & path_, mode_t mode_, IDisk & disk_)
: path(path_)
, mode(mode_)
, disk(disk_)
{
}
void ChmodOperation::execute(std::unique_lock<std::shared_mutex> &)
{
old_mode = disk.stat(path).st_mode;
disk.chmod(path, mode);
}
void ChmodOperation::undo()
{
disk.chmod(path, old_mode);
}
UnlinkFileOperation::UnlinkFileOperation(const std::string & path_, IDisk & disk_)
: path(path_)
, disk(disk_)

View File

@ -37,6 +37,21 @@ private:
IDisk & disk;
};
struct ChmodOperation final : public IMetadataOperation
{
ChmodOperation(const std::string & path_, mode_t mode_, IDisk & disk_);
void execute(std::unique_lock<std::shared_mutex> & metadata_lock) override;
void undo() override;
private:
std::string path;
mode_t mode;
mode_t old_mode;
IDisk & disk;
};
struct UnlinkFileOperation final : public IMetadataOperation
{