Commit d3442568 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Merge branch 'fix_IO_on_dir' into 'master'

Fix IO on directories

See merge request zdvresearch_bsc/adafs!92
parents 522f6fd1 1eb48e30
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ enum class FileType {

class OpenFile {
protected:
    FileType type_;
    std::string path_;
    std::array<bool, static_cast<int>(OpenFile_flags::flag_count)> flags_ = {false};
    off64_t pos_;
@@ -38,7 +39,7 @@ protected:
public:
    // multiple threads may want to update the file position if fd has been duplicated by dup()

    OpenFile(const std::string& path, int flags);
    OpenFile(const std::string& path, int flags, FileType type = FileType::regular);

    ~OpenFile();

@@ -55,6 +56,7 @@ public:

    void set_flag(OpenFile_flags flag, bool value);

    FileType type() const;
};


+12 −0
Original line number Diff line number Diff line
@@ -291,6 +291,12 @@ int adafs_dup2(const int oldfd, const int newfd) {
ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    auto adafs_fd = CTX->file_map()->get(fd);
    if (adafs_fd->type() != FileType::regular) {
        assert(adafs_fd->type() == FileType::directory);
        CTX->log()->warn("{}() cannot read from directory", __func__);
        errno = EISDIR;
        return -1;
    }
    auto path = make_shared<string>(adafs_fd->path());
    CTX->log()->trace("{}() fd: {}, count: {}, offset: {}", __func__, fd, count, offset);
    auto append_flag = adafs_fd->get_flag(OpenFile_flags::append);
@@ -312,6 +318,12 @@ ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) {
ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    auto adafs_fd = CTX->file_map()->get(fd);
    if (adafs_fd->type() != FileType::regular) {
        assert(adafs_fd->type() == FileType::directory);
        CTX->log()->warn("{}() cannot read from directory", __func__);
        errno = EISDIR;
        return -1;
    }
    auto path = make_shared<string>(adafs_fd->path());
    CTX->log()->trace("{}() fd: {}, count: {}, offset: {}", __func__, fd, count, offset);
    // Zeroing buffer before read is only relevant for sparse files. Otherwise sparse regions contain invalid data.
+2 −2
Original line number Diff line number Diff line
@@ -9,12 +9,12 @@ OpenDir::DirEntry::DirEntry(const std::string& name, const FileType type):
}


OpenDir::OpenDir(const std::string& path): OpenFile(path, 0){
OpenDir::OpenDir(const std::string& path) :
    OpenFile(path, 0, FileType::directory) {
    pos_ = 0;
    is_dirent_valid = false;
}


void OpenDir::add(const std::string& name, const FileType& type){
    entries.push_back(DirEntry(name, type));
}
+10 −8
Original line number Diff line number Diff line
@@ -7,7 +7,10 @@

using namespace std;

OpenFile::OpenFile(const string& path, const int flags) : path_(path) {
OpenFile::OpenFile(const string& path, const int flags, FileType type) :
    type_(type),
    path_(path)
{
    // set flags to OpenFile
    if (flags & O_CREAT)
        flags_[to_underlying(OpenFile_flags::creat)] = true;
@@ -62,6 +65,10 @@ void OpenFile::set_flag(OpenFile_flags flag, bool value) {
    flags_[to_underlying(flag)] = value;
}

FileType OpenFile::type() const {
    return type_;
}

// OpenFileMap starts here

shared_ptr<OpenFile> OpenFileMap::get(int fd) {
@@ -76,12 +83,10 @@ shared_ptr<OpenFile> OpenFileMap::get(int fd) {

shared_ptr<OpenDir> OpenFileMap::get_dir(int dirfd) {
    auto f = get(dirfd);
    if(f == nullptr){
    if (f == nullptr || f->type() != FileType::directory) {
        return nullptr;
    }
    auto open_dir = static_pointer_cast<OpenDir>(f);
    // If open_file is not an OpenDir we are returning nullptr
    return open_dir;
    return static_pointer_cast<OpenDir>(f);
}

bool OpenFileMap::exist(const int fd) {
@@ -186,6 +191,3 @@ int OpenFileMap::get_fd_idx() {
    std::lock_guard<std::mutex> inode_lock(fd_idx_mutex);
    return fd_idx;
}


+28 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ int main(int argc, char* argv[]) {


    int ret;
    int fd;
    DIR * dirstream = NULL;
    struct stat dirstat;

@@ -75,6 +76,33 @@ int main(int argc, char* argv[]) {
    }
    assert(S_ISDIR(dirstat.st_mode));

    // Open topdir
    fd = open(topdir.c_str(), O_DIRECTORY);
    if(ret != 0){
        std::cerr << "Error opening topdir: " << std::strerror(errno) << std::endl;
        return -1;
    }
    
    // Read and write should be impossible on directories
    char buff;
    ret = read(fd, &buff, 1);
    if (ret == 0) {
        std::cerr << "ERROR: succeded on reading directory" << std::endl;
        return -1;
    }
    if (errno != EISDIR) {
        std::cerr << "ERROR: wrong error number on directory read" << std::endl;
        return -1;
    }
    ret = write(fd, &buff, 1);
    if (ret == 0) {
        std::cerr << "ERROR: succeded on reading directory" << std::endl;
        return -1;
    }
    if (errno != EISDIR) {
        std::cerr << "ERROR: wrong error number on directory read" << std::endl;
        return -1;
    }

    /* Read top directory that is empty */
    //opening top directory