Example #1
0
bool GlusterBackend::put(const SyncEvent* _putEvent) {
  if(_putEvent == nullptr || _putEvent->fullPathBuffer.empty())
      return false;

  FileNode* node = FileSystem::getInstance().findAndOpenNode(_putEvent->fullPathBuffer);
  if(node == nullptr){
    LOG(ERROR)<<_putEvent->fullPathBuffer<<" Does not exist! So can't upload it.";
    return false;
  }
  uint64_t inodeNum = FileSystem::getInstance().assignINodeNum((intptr_t)node);

  //Double check if not already uploaded
  if(node->flushed()){
    node->close(inodeNum);
    return true;
  }

  //CheckEvent validity
  if(!UploadQueue::getInstance().checkEventValidity(*_putEvent)) {
    //release file delete lock, so they can delete it
    node->close(inodeNum);
    return true;//going to be deletes so anyway say it's synced!
  }

  if(node->mustBeDeleted()){
    node->close(inodeNum);
    return true;
  }

  //Create necessary directories
  //Traverse FileSystem Hierarchies
  Poco::StringTokenizer tokenizer(_putEvent->fullPathBuffer,
      FileSystem::delimiter,Poco::StringTokenizer::TOK_TRIM |
      Poco::StringTokenizer::TOK_IGNORE_EMPTY);
  //Nested directories
  if(tokenizer.count()>=2){
    for(unsigned int i=0;i<tokenizer.count()-1;i++){
      string path = FileSystem::delimiter;
      for(unsigned int j=0;j<=i;j++){
        path += tokenizer[j];
        path += FileSystem::delimiter;
      }
      if(!createDirectory(path.c_str())){
        LOG(ERROR)<<"Failed to create parent directory("<<tokenizer[i]<<") for:"<<_putEvent->fullPathBuffer;
        node->close(inodeNum);
        return false;
      }
    }
  }
  //Create the file! (overwrite or create)
  glfs_fd_t *fd = glfs_creat((glfs_t*)fs, _putEvent->fullPathBuffer.c_str(), O_RDWR, 0644);
  //glfs_fd_t *fd = glfs_open(,O_RDWR| O_CREAT | O_TRUNC);
  if(!fd){
    LOG(ERROR)<<"Error in creating file:"<<_putEvent->fullPathBuffer<<" in GlusterFS. errno:"<<errno;
    return false;
  }

  //Ready to write (write each time a blocksize)
  uint64_t buffSize = 1024ll*1024ll*10ll;
  char *buff = new char[buffSize];//10MB buffer
  size_t offset = 0;
  long read = 0;
  //FileNode *node = _putEvent->node;
  do {
    //CheckEvent validity
    if(!UploadQueue::getInstance().checkEventValidity(*_putEvent)){
      glfs_close(fd);
      delete []buff;
      buff = nullptr;
      node->close(inodeNum);
      return true;
    }

    if(node->mustBeDeleted()){//Check Delete
      glfs_close(fd);
      delete []buff;
      buff = nullptr;
      node->close(inodeNum);
      return true;
    }

    //get lock delete so file won't be deleted
    read = node->read(buff,offset,buffSize);


    offset += read;
    int64_t written = glfs_write(fd,buff,read,0);
    if(written!=read){
      LOG(ERROR)<<"Error while writing to:"<<_putEvent->fullPathBuffer<<
          ". Asked to write:"<<read<<" but wrote:"<<written;
      glfs_close(fd);
      return false;
    }
  }
  while(read > 0);

  delete []buff;
  buff = nullptr;

  if(node->mustBeDeleted()){//Check Delete
    glfs_close(fd);
    node->close(inodeNum);
    return true;
  }

  //Now sync
  if(glfs_close(fd)!=0){
    LOG(ERROR)<<"Error in closing:"<<_putEvent->fullPathBuffer<<" errorNo:"<<errno;
    node->close(inodeNum);
    return false;
  }

  node->close(inodeNum);
  return true;
}