mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-04 23:50:50 +00:00
Merge pull request #17227 from Jokser/disk-s3-readonly-flag
Store read-only flag into metadata file for DiskS3
This commit is contained in:
commit
9cdb255ee1
@ -34,6 +34,7 @@ namespace ErrorCodes
|
|||||||
extern const int UNKNOWN_FORMAT;
|
extern const int UNKNOWN_FORMAT;
|
||||||
extern const int INCORRECT_DISK_INDEX;
|
extern const int INCORRECT_DISK_INDEX;
|
||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
|
extern const int PATH_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ namespace
|
|||||||
/// Metadata file version.
|
/// Metadata file version.
|
||||||
static constexpr UInt32 VERSION_ABSOLUTE_PATHS = 1;
|
static constexpr UInt32 VERSION_ABSOLUTE_PATHS = 1;
|
||||||
static constexpr UInt32 VERSION_RELATIVE_PATHS = 2;
|
static constexpr UInt32 VERSION_RELATIVE_PATHS = 2;
|
||||||
|
static constexpr UInt32 VERSION_READ_ONLY_FLAG = 3;
|
||||||
|
|
||||||
using PathAndSize = std::pair<String, size_t>;
|
using PathAndSize = std::pair<String, size_t>;
|
||||||
|
|
||||||
@ -109,6 +111,8 @@ namespace
|
|||||||
std::vector<PathAndSize> s3_objects;
|
std::vector<PathAndSize> s3_objects;
|
||||||
/// Number of references (hardlinks) to this metadata file.
|
/// Number of references (hardlinks) to this metadata file.
|
||||||
UInt32 ref_count;
|
UInt32 ref_count;
|
||||||
|
/// Flag indicates that file is read only.
|
||||||
|
bool read_only = false;
|
||||||
|
|
||||||
/// Load metadata by path or create empty if `create` flag is set.
|
/// Load metadata by path or create empty if `create` flag is set.
|
||||||
explicit Metadata(const String & s3_root_path_, const String & disk_path_, const String & metadata_file_path_, bool create = false)
|
explicit Metadata(const String & s3_root_path_, const String & disk_path_, const String & metadata_file_path_, bool create = false)
|
||||||
@ -122,10 +126,10 @@ namespace
|
|||||||
UInt32 version;
|
UInt32 version;
|
||||||
readIntText(version, buf);
|
readIntText(version, buf);
|
||||||
|
|
||||||
if (version != VERSION_RELATIVE_PATHS && version != VERSION_ABSOLUTE_PATHS)
|
if (version < VERSION_ABSOLUTE_PATHS || version > VERSION_READ_ONLY_FLAG)
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Unknown metadata file version. Path: " + disk_path + metadata_file_path
|
"Unknown metadata file version. Path: " + disk_path + metadata_file_path
|
||||||
+ " Version: " + std::to_string(version) + ", Maximum expected version: " + std::to_string(VERSION_RELATIVE_PATHS),
|
+ " Version: " + std::to_string(version) + ", Maximum expected version: " + std::to_string(VERSION_READ_ONLY_FLAG),
|
||||||
ErrorCodes::UNKNOWN_FORMAT);
|
ErrorCodes::UNKNOWN_FORMAT);
|
||||||
|
|
||||||
assertChar('\n', buf);
|
assertChar('\n', buf);
|
||||||
@ -158,6 +162,12 @@ namespace
|
|||||||
|
|
||||||
readIntText(ref_count, buf);
|
readIntText(ref_count, buf);
|
||||||
assertChar('\n', buf);
|
assertChar('\n', buf);
|
||||||
|
|
||||||
|
if (version >= VERSION_READ_ONLY_FLAG)
|
||||||
|
{
|
||||||
|
readBoolText(read_only, buf);
|
||||||
|
assertChar('\n', buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addObject(const String & path, size_t size)
|
void addObject(const String & path, size_t size)
|
||||||
@ -189,6 +199,9 @@ namespace
|
|||||||
writeIntText(ref_count, buf);
|
writeIntText(ref_count, buf);
|
||||||
writeChar('\n', buf);
|
writeChar('\n', buf);
|
||||||
|
|
||||||
|
writeBoolText(read_only, buf);
|
||||||
|
writeChar('\n', buf);
|
||||||
|
|
||||||
buf.finalize();
|
buf.finalize();
|
||||||
if (sync)
|
if (sync)
|
||||||
buf.sync();
|
buf.sync();
|
||||||
@ -632,6 +645,12 @@ std::unique_ptr<ReadBufferFromFileBase> DiskS3::readFile(const String & path, si
|
|||||||
std::unique_ptr<WriteBufferFromFileBase> DiskS3::writeFile(const String & path, size_t buf_size, WriteMode mode, size_t estimated_size, size_t)
|
std::unique_ptr<WriteBufferFromFileBase> DiskS3::writeFile(const String & path, size_t buf_size, WriteMode mode, size_t estimated_size, size_t)
|
||||||
{
|
{
|
||||||
bool exist = exists(path);
|
bool exist = exists(path);
|
||||||
|
if (exist)
|
||||||
|
{
|
||||||
|
Metadata metadata(s3_root_path, metadata_path, path);
|
||||||
|
if (metadata.read_only)
|
||||||
|
throw Exception("File is read-only: " + path, ErrorCodes::PATH_ACCESS_DENIED);
|
||||||
|
}
|
||||||
/// Path to store new S3 object.
|
/// Path to store new S3 object.
|
||||||
auto s3_path = getRandomName();
|
auto s3_path = getRandomName();
|
||||||
bool is_multipart = estimated_size >= min_multi_part_upload_size;
|
bool is_multipart = estimated_size >= min_multi_part_upload_size;
|
||||||
@ -797,7 +816,11 @@ void DiskS3::createFile(const String & path)
|
|||||||
|
|
||||||
void DiskS3::setReadOnly(const String & path)
|
void DiskS3::setReadOnly(const String & path)
|
||||||
{
|
{
|
||||||
Poco::File(metadata_path + path).setReadOnly(true);
|
/// We should store read only flag inside metadata file (instead of using FS flag),
|
||||||
|
/// because we modify metadata file when create hard-links from it.
|
||||||
|
Metadata metadata(s3_root_path, metadata_path, path);
|
||||||
|
metadata.read_only = true;
|
||||||
|
metadata.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
int DiskS3::open(const String & /*path*/, mode_t /*mode*/) const
|
int DiskS3::open(const String & /*path*/, mode_t /*mode*/) const
|
||||||
|
Loading…
Reference in New Issue
Block a user