From: František Dvořák Date: Tue, 15 Oct 2013 11:35:28 +0000 (+0200) Subject: Fix uploading into subdirectories (mkdir()s moved from PoolHandler to IO Driver)... X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=98d5f37d698c0403d7e0c5d51bb6434eb8f00754;p=dmlite-plugins-vfs.git Fix uploading into subdirectories (mkdir()s moved from PoolHandler to IO Driver), added debugging. --- diff --git a/src/VfsDriver.cpp b/src/VfsDriver.cpp index d3a48fd..25700ba 100644 --- a/src/VfsDriver.cpp +++ b/src/VfsDriver.cpp @@ -210,7 +210,7 @@ Location VfsPoolHandler::whereToWrite(const std::string& sfn) throw (DmException Chunk single; Url wloc; std::vector components; - std::string path, curdir, parentdir; + std::string path, parentdir; struct stat fstat; if (sfn.empty() || sfn[0] != '/') path = "/" + sfn; @@ -220,29 +220,9 @@ Location VfsPoolHandler::whereToWrite(const std::string& sfn) throw (DmException components.pop_back(); parentdir = Url::joinPath(components); - // - // check the parent directory and try to create subtree if not available - // - // Catalog checks permissions in all parent directories, so with disk is in - // sync with namespace, the creating of subtree should not be needed. - // - if (stat(getLocalPath(parentdir).c_str(), &fstat) == -1) { - components = Url::splitPath(path); - curdir = ""; - for (unsigned int i = 0; i < components.size() - 1; i++) { - // the first component always '/', let's use it as separator - if (i < 2) curdir += components[i]; - else curdir = curdir + "/" + components[i]; - // ignore all errors - we stupidly go from '/' toward deeper levels - mkdir(getLocalPath(curdir).c_str(), 0755); - } - - // detailed error from stat() only after the attempt for the subtree - wrapCall(stat(getLocalPath(curdir).c_str(), &fstat), "parent directory '%s' not available", curdir.c_str()); - } - + wrapCall(stat(getLocalPath(parentdir).c_str(), &fstat), "parent directory '%s' not available", parentdir.c_str()); if (!S_ISDIR(fstat.st_mode)) - vfsThrow(ENOTDIR, "'%s' is not directory", curdir.c_str()); + vfsThrow(ENOTDIR, "'%s' is not directory", parentdir.c_str()); wloc = Url(path); diff --git a/src/VfsIO.cpp b/src/VfsIO.cpp index 41111b1..60fdf4d 100644 --- a/src/VfsIO.cpp +++ b/src/VfsIO.cpp @@ -1,8 +1,11 @@ /// @file VfsIO.cpp /// @brief IO factory. /// @author Alejandro Álvarez Ayllón -#include +#include +#include #include +#include +#include #include "Vfs.h" #include "VfsIO.h" @@ -80,23 +83,45 @@ void VfsIODriver::doneWriting(const Location &loc) throw (DmException) -VfsIOHandler::VfsIOHandler(const std::string& path, const std::string& prefix, +VfsIOHandler::VfsIOHandler(const std::string& urlpath, const std::string& prefix, int flags, mode_t mode) throw (DmException): eof_(false), pos_(0) { - std::string real; + std::string path, lpath, parentdir, curdir; + std::vector components; + struct stat fstat; - if (path.compare(0, 5, "/vfs/") != 0) - vfsThrow(EINVAL, "file not on the /vfs/ namespace"); - this->prefix_ = prefix; - real = getLocalPath(path.substr(4)); + if (urlpath.compare(0, 5, "/vfs/") != 0) + vfsThrow(EINVAL, "file not on the /vfs/ namespace"); + + path = urlpath.substr(4); + components = Url::splitPath(path); + components.pop_back(); + if (components.size() == 1 && components[0] == "/") parentdir = "/"; + else parentdir = Url::joinPath(components); + + // + // check the parent directory and try to create subtree if not available + // + if (stat(getLocalPath(parentdir).c_str(), &fstat) == -1) { + curdir = this->prefix_; + for (unsigned int i = 0; i < components.size(); i++) { + // the first component always '/', let's use it as separator + if (i < 2) curdir += components[i]; + else curdir = curdir + "/" + components[i]; + // ignore all errors - just go from "/" toward deeper levels + if (mkdir(curdir.c_str(), 0755) == 0) + syslog(LOG_DEBUG, "%s: created directory '%s'", __func__, curdir.c_str()); + } + } + lpath = getLocalPath(path); - this->fd_ = ::open(real.c_str(), flags, mode); - syslog(LOG_DEBUG, "%s: open('%s', flags=%04X, mode=%04o) = %d", __func__, real.c_str(), flags, mode, this->fd_); + this->fd_ = ::open(lpath.c_str(), flags, mode); + syslog(LOG_DEBUG, "%s: open('%s', flags=%04X, mode=%04o) = %d", __func__, lpath.c_str(), flags, mode, this->fd_); if (this->fd_ == -1) - vfsThrowErrno("could not open %s)", path.c_str()); + vfsThrowErrno("could not open '%s'", lpath.c_str()); } diff --git a/src/VfsIO.h b/src/VfsIO.h index e8e6d82..eba6eea 100644 --- a/src/VfsIO.h +++ b/src/VfsIO.h @@ -36,7 +36,7 @@ namespace dmlite { class VfsIOHandler: public IOHandler { public: - VfsIOHandler(const std::string& path, const std::string& prefix, + VfsIOHandler(const std::string& urlpath, const std::string& prefix, int flags, mode_t mode) throw (DmException); ~VfsIOHandler();