예제 #1
0
static int cfs_readlink(const char* path, char* buf, size_t size)
{
    FILE *temp_file = tmpfile();
    int ret = 0;

    if (!cloudfs_object_write_fp(path, temp_file))
    {
        ret = -ENOENT;
    }

    if (!pread(fileno(temp_file), buf, size, 0))
    {
        ret = -ENOENT;
    }

    fclose(temp_file);
    return ret;
}
예제 #2
0
static int cfs_open(const char *path, struct fuse_file_info *info)
{
  FILE *temp_file = tmpfile();
  dir_entry *de = path_info(path);
  if (!(info->flags & O_WRONLY))
  {
    if (!cloudfs_object_write_fp(path, temp_file))
    {
      fclose(temp_file);
      return -ENOENT;
    }
    update_dir_cache(path, (de ? de->size : 0), 0);
  }
  openfile *of = (openfile *)malloc(sizeof(openfile));
  of->fd = dup(fileno(temp_file));
  fclose(temp_file);
  of->flags = info->flags;
  info->fh = (uintptr_t)of;
  info->direct_io = 1;
  return 0;
}
예제 #3
0
static int cfs_readlink(const char* path, char* buf, size_t size)
{
  debugf(DBG_LEVEL_NORM, KBLU"cfs_readlink(%s)", path);
  //fixme: use temp file specified in config
  FILE* temp_file = tmpfile();
  int ret = 0;

  if (!cloudfs_object_write_fp(path, temp_file))
  {
    debugf(DBG_LEVEL_NORM, KRED"exit 1: cfs_readlink(%s) not found", path);
    ret = -ENOENT;
  }

  if (!pread(fileno(temp_file), buf, size, 0))
  {
    debugf(DBG_LEVEL_NORM, KRED"exit 2: cfs_readlink(%s) not found", path);
    ret = -ENOENT;
  }

  fclose(temp_file);
  debugf(DBG_LEVEL_NORM, KBLU"exit 3: cfs_readlink(%s)", path);
  return ret;
}
예제 #4
0
static int cfs_open(const char *path, struct fuse_file_info *info)
{
    FILE *temp_file;
    dir_entry *de = path_info(path);

    if (*temp_dir)
    {
        char tmp_path[PATH_MAX];
        strncpy(tmp_path, path, PATH_MAX);

        char *pch;
        while((pch = strchr(tmp_path, '/'))) {
            *pch = '.';
        }

        char file_path[PATH_MAX];
        snprintf(file_path, PATH_MAX, "%s/.cloudfuse%ld-%s", temp_dir,
                 (long)getpid(), tmp_path);

        if(access(file_path, F_OK) != -1)
        {
            // file exists
            temp_file = fopen(file_path, "r");
        }
        else if (!(info->flags & O_WRONLY))
        {
            // we need to lock on the filename another process could open the file
            // while we are writing to it and then only read part of the file

            // duplicate the directory caching datastructure to make the code easier
            // to understand.

            // each file in the cache needs:
            //  filename, is_writing, last_closed, is_removing
            // the first time a file is opened a new entry is created in the cache
            // setting the filename and is_writing to true.  This check needs to be
            // wrapped with a lock.
            //
            // each time a file is closed we set the last_closed for the file to now
            // and we check the cache for files whose last
            // closed is greater than cache_timeout, then start a new thread rming
            // that file.

            // TODO: just to prevent this craziness for now
            temp_file = fopen(file_path, "w+b");

            if (!cloudfs_object_write_fp(path, temp_file))
            {
                fclose(temp_file);
                return -ENOENT;
            }
        }
    }
    else
    {
        temp_file = tmpfile();
        if (!(info->flags & O_WRONLY))
        {
            if (!cloudfs_object_write_fp(path, temp_file))
            {
                fclose(temp_file);
                return -ENOENT;
            }
        }
    }

    update_dir_cache(path, (de ? de->size : 0), 0, 0);

    openfile *of = (openfile *)malloc(sizeof(openfile));
    of->fd = dup(fileno(temp_file));
    if (of->fd == -1)
        return -ENOENT;
    fclose(temp_file);
    of->flags = info->flags;
    info->fh = (uintptr_t)of;
    info->direct_io = 1;
    return 0;
}
예제 #5
0
// open (download) file from cloud
// todo: implement etag optimisation, download only if content changed, http://www.17od.com/2012/12/19/ten-useful-openstack-swift-features/
static int cfs_open(const char* path, struct fuse_file_info* info)
{
  debugf(DBG_LEVEL_NORM, KBLU "cfs_open(%s)", path);
  FILE* temp_file = NULL;
  int errsv;
  dir_entry* de = path_info(path);

  if (*temp_dir)
  {
    char file_path_safe[NAME_MAX];
    get_safe_cache_file_path(path, file_path_safe, temp_dir);

    debugf(DBG_LEVEL_EXT, "cfs_open: try open (%s)", file_path_safe);
    if (access(file_path_safe, F_OK) != -1)
    {
      // file exists
      temp_file = fopen(file_path_safe, "r");
      errsv = errno;
      if (temp_file == NULL)
      {
        debugf(DBG_LEVEL_NORM,
               KRED"exit 0: cfs_open can't open temp_file=[%s] err=%d:%s", file_path_safe,
               errsv, strerror(errsv));
        return -ENOENT;
      }
      else
        debugf(DBG_LEVEL_EXT, "cfs_open: file exists");
    }
    else
    {
      errsv = errno;
      debugf(DBG_LEVEL_EXT, "cfs_open: file not in cache, err=%s", strerror(errsv));
      //FIXME: commented out as this condition will not be meet in some odd cases and program will crash
      //if (!(info->flags & O_WRONLY)) {
      debugf(DBG_LEVEL_EXT, "cfs_open: opening for write");

      // we need to lock on the filename another process could open the file
      // while we are writing to it and then only read part of the file

      // duplicate the directory caching datastructure to make the code easier
      // to understand.

      // each file in the cache needs:
      //  filename, is_writing, last_closed, is_removing
      // the first time a file is opened a new entry is created in the cache
      // setting the filename and is_writing to true.  This check needs to be
      // wrapped with a lock.
      //
      // each time a file is closed we set the last_closed for the file to now
      // and we check the cache for files whose last
      // closed is greater than cache_timeout, then start a new thread rming
      // that file.

      // TODO: just to prevent this craziness for now
      temp_file = fopen(file_path_safe, "w+b");
      errsv = errno;
      if (temp_file == NULL)
      {
        debugf(DBG_LEVEL_NORM,
               KRED"exit 1: cfs_open cannot open temp_file=[%s] err=%d:%s", file_path_safe,
               errsv, strerror(errsv));
        return -ENOENT;
      }

      if (!cloudfs_object_write_fp(path, temp_file))
      {
        fclose(temp_file);
        debugf(DBG_LEVEL_NORM, KRED "exit 2: cfs_open(%s) cannot download/write",
               path);
        return -ENOENT;
      }
    }
  }
  else
  {
    temp_file = tmpfile();
    if (temp_file == NULL)
    {
      debugf(DBG_LEVEL_NORM, KRED"exit 3: cfs_open cannot create temp_file err=%s",
             strerror(errno));
      return -ENOENT;
    }

    if (!(info->flags & O_TRUNC))
    {
      if (!cloudfs_object_write_fp(path, temp_file) && !(info->flags & O_CREAT))
      {
        fclose(temp_file);
        debugf(DBG_LEVEL_NORM, KRED"exit 4: cfs_open(%s) cannot download/write", path);
        return -ENOENT;
      }
    }
  }

  update_dir_cache(path, (de ? de->size : 0), 0, 0);
  openfile* of = (openfile*)malloc(sizeof(openfile));
  of->fd = dup(fileno(temp_file));
  if (of->fd == -1)
  {
    //FIXME: potential leak if free not used?
    free(of);
    debugf(DBG_LEVEL_NORM, KRED "exit 5: cfs_open(%s) of->fd", path);
    return -ENOENT;
  }
  fclose(temp_file);
  //TODO: why this allocation to of?
  of->flags = info->flags;
  info->fh = (uintptr_t)of;
  info->direct_io = 1;
  info->nonseekable = 0;
  //FIXME: potential leak if free(of) not used? although if free(of) is used will generate bad descriptor errors
  debugf(DBG_LEVEL_NORM, KBLU "exit 6: cfs_open(%s)", path);
  return 0;
}