diff --git a/src/IOCoordinator.cpp b/src/IOCoordinator.cpp index 9bc59bf08..5841af235 100755 --- a/src/IOCoordinator.cpp +++ b/src/IOCoordinator.cpp @@ -223,26 +223,6 @@ int IOCoordinator::read(const char *filename, uint8_t *data, off_t offset, size_ // all done return count; - -/* - int fd, err; - - OPEN(filename, O_RDONLY); - - size_t count = 0; - ::lseek(fd, offset, SEEK_SET); - while (count < length) { - err = ::read(fd, &data[count], length - count); - if (err <= 0) - if (count > 0) // return what was successfully read - return count; - else - return err; - count += err; - } - - return count; -*/ } int IOCoordinator::write(const char *filename, const uint8_t *data, off_t offset, size_t length) @@ -352,6 +332,25 @@ int IOCoordinator::append(const char *filename, const uint8_t *data, size_t leng int IOCoordinator::open(const char *filename, int openmode, struct stat *out) { + + if (openmode & O_CREAT) + { + MetadataFile meta(filename); + meta.stat(out); + } + else + { + MetadataFile meta(filename, MetadataFile::no_create_t()); + if (!meta.exists()) + { + errno = ENOENT; + return -1; + } + meta.stat(out); + } + return 0; + +#if 0 int fd, err; /* create all subdirs if necessary. We don't care if directories actually get created. */ @@ -362,6 +361,7 @@ int IOCoordinator::open(const char *filename, int openmode, struct stat *out) } OPEN(filename, openmode); return fstat(fd, out); +#endif } int IOCoordinator::listDirectory(const char *filename, vector *listing) diff --git a/src/MetadataFile.cpp b/src/MetadataFile.cpp index d5ec29607..f10aa9084 100755 --- a/src/MetadataFile.cpp +++ b/src/MetadataFile.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #define max(x, y) (x > y ? x : y) #define min(x, y) (x < y ? x : y) @@ -69,6 +70,7 @@ MetadataFile::MetadataFile(const char* filename) mpLogger = SMLogging::get(); mObjectSize = 5 * (1<<20); _exists = true; + try { mObjectSize = stoul(mpConfig->getValue("ObjectStorage", "object_size")); @@ -97,11 +99,11 @@ MetadataFile::MetadataFile(const char* filename) syslog(LOG_CRIT, "Failed to create %s, got: %s", msMetadataPath.c_str(), e.what()); throw e; } - string metadataFilename = msMetadataPath + "/" + string(filename) + ".meta"; - if (boost::filesystem::exists(metadataFilename)) + mFilename = msMetadataPath + "/" + string(filename) + ".meta"; + if (boost::filesystem::exists(mFilename)) { boost::property_tree::ptree jsontree; - boost::property_tree::read_json(metadataFilename, jsontree); + boost::property_tree::read_json(mFilename, jsontree); metadataObject newObject; //try catch mVersion = jsontree.get("version"); @@ -157,12 +159,12 @@ MetadataFile::MetadataFile(const char* filename, no_create_t) syslog(LOG_CRIT, "Failed to create %s, got: %s", msMetadataPath.c_str(), e.what()); throw e; } - string metadataFilename = msMetadataPath + "/" + string(filename) + ".meta"; - if (boost::filesystem::exists(metadataFilename)) + mFilename = msMetadataPath + "/" + string(filename) + ".meta"; + if (boost::filesystem::exists(mFilename)) { _exists = true; boost::property_tree::ptree jsontree; - boost::property_tree::read_json(metadataFilename, jsontree); + boost::property_tree::read_json(mFilename, jsontree); metadataObject newObject; //try catch mVersion = jsontree.get("version"); @@ -190,7 +192,24 @@ MetadataFile::~MetadataFile() } -bool MetadataFile::exists() +int MetadataFile::stat(struct stat *out) const +{ + int err = ::stat(mFilename.c_str(), out); + if (err) + { + cout << "Failed to stat " << mFilename << endl; + return err; + } + + cout << "Got the stat for " << mFilename << endl; + size_t totalSize = 0; + for (auto &object : mObjects) + totalSize += object.length; + out->st_size = totalSize; + return 0; +} + +bool MetadataFile::exists() const { return _exists; } @@ -276,8 +295,9 @@ metadataObject MetadataFile::addMetadataObject(const char *filename, size_t leng int MetadataFile::writeMetadata(const char *filename) { int error=0; - + string metadataFilename = msMetadataPath + "/" + string(filename) + ".meta"; + boost::filesystem::path pMetadataFilename = metadataFilename; boost::property_tree::ptree jsontree; boost::property_tree::ptree objs; jsontree.put("version",mVersion); @@ -291,8 +311,12 @@ int MetadataFile::writeMetadata(const char *filename) objs.push_back(std::make_pair("", object)); } jsontree.add_child("objects", objs); + + if (!boost::filesystem::exists(pMetadataFilename.parent_path())) + boost::filesystem::create_directories(pMetadataFilename.parent_path()); write_json(metadataFilename, jsontree); _exists = true; + mFilename = metadataFilename; return error; } diff --git a/src/MetadataFile.h b/src/MetadataFile.h index fa9979bbe..4e1a72661 100755 --- a/src/MetadataFile.h +++ b/src/MetadataFile.h @@ -8,6 +8,7 @@ #include "SMLogging.h" #include #include +#include #include #include #include @@ -32,8 +33,9 @@ class MetadataFile MetadataFile(const char* filename, no_create_t); // this one won't create it if it doesn't exist ~MetadataFile(); - bool exists(); + bool exists() const; void printObjects(); + int stat(struct stat *) const; // returns the objects needed to update std::vector metadataRead(off_t offset, size_t length); // updates the metadatafile with new object @@ -55,12 +57,12 @@ class MetadataFile private: Config *mpConfig; - std::string prefix; SMLogging *mpLogger; int mVersion; int mRevision; size_t mObjectSize; std::string msMetadataPath; + std::string mFilename; std::set mObjects; bool _exists; //vector mObjects; diff --git a/src/unit_tests.cpp b/src/unit_tests.cpp index 1d1fcaacc..b5df567c9 100755 --- a/src/unit_tests.cpp +++ b/src/unit_tests.cpp @@ -134,8 +134,12 @@ bool opentask() assert(_stat->st_size == 0); /* verify the file is there */ - assert(boost::filesystem::exists(filename)); - ::unlink(filename); + string metaPath = Config::get()->getValue("ObjectStorage", "metadata_path"); + assert(!metaPath.empty()); + metaPath += string("/") + filename + ".meta"; + + assert(boost::filesystem::exists(metaPath)); + ::unlink(metaPath.c_str()); cout << "opentask OK" << endl; return true; }