Beispiel #1
0
int delete_file(char* path)
{
  debugf(DBG_LEVEL_NORM, KYEL"delete_file(%s)", path);
  char file_path_safe[NAME_MAX] = "";
  get_safe_cache_file_path(path, file_path_safe, temp_dir);
  int result = unlink(file_path_safe);
  debugf(DBG_LEVEL_EXT, KYEL"delete_file(%s) (%s) result=%s", path,
         file_path_safe, strerror(result));
  return result;
}
Beispiel #2
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;
}
Beispiel #3
0
static int cfs_create(const char* path, mode_t mode,
                      struct fuse_file_info* info)
{
  debugf(DBG_LEVEL_NORM, KBLU "cfs_create(%s)", path);
  FILE* temp_file;
  int errsv;
  char file_path_safe[NAME_MAX] = "";

  if (*temp_dir)
  {
    get_safe_cache_file_path(path, file_path_safe, temp_dir);
    temp_file = fopen(file_path_safe, "w+b");
    errsv = errno;
    if (temp_file == NULL)
    {
      debugf(DBG_LEVEL_NORM, KRED
             "exit 0: cfs_create cannot open temp file %s.error %s\n", file_path_safe,
             strerror(errsv));
      return -EIO;
    }
  }
  else
  {
    temp_file = tmpfile();
    errsv = errno;
    if (temp_file == NULL)
    {
      debugf(DBG_LEVEL_NORM, KRED
             "exit 1: cfs_create cannot open tmp file for path %s.error %s\n", path,
             strerror(errsv));
      return -EIO;
    }
  }
  openfile* of = (openfile*)malloc(sizeof(openfile));
  of->fd = dup(fileno(temp_file));
  fclose(temp_file);
  of->flags = info->flags;
  info->fh = (uintptr_t)of;
  update_dir_cache(path, 0, 0, 0);
  info->direct_io = 1;
  dir_entry* de = check_path_info(path);
  if (de)
  {
    debugf(DBG_LEVEL_EXT, KCYN"cfs_create(%s): found in cache", path);
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    debugf(DBG_LEVEL_EXT, KCYN"cfs_create(%s) set utimes as now", path);
    de->atime.tv_sec = now.tv_sec;
    de->atime.tv_nsec = now.tv_nsec;
    de->mtime.tv_sec = now.tv_sec;
    de->mtime.tv_nsec = now.tv_nsec;
    de->ctime.tv_sec = now.tv_sec;
    de->ctime.tv_nsec = now.tv_nsec;

    char time_str[TIME_CHARS] = "";
    get_timespec_as_str(&(de->atime), time_str, sizeof(time_str));
    debugf(DBG_LEVEL_EXT, KCYN"cfs_create: atime=[%s]", time_str);
    get_timespec_as_str(&(de->mtime), time_str, sizeof(time_str));
    debugf(DBG_LEVEL_EXT, KCYN"cfs_create: mtime=[%s]", time_str);
    get_timespec_as_str(&(de->ctime), time_str, sizeof(time_str));
    debugf(DBG_LEVEL_EXT, KCYN"cfs_create: ctime=[%s]", time_str);

    //set chmod & chown
    de->chmod = mode;
    de->uid = geteuid();
    de->gid = getegid();
  }
  else
    debugf(DBG_LEVEL_EXT, KBLU "cfs_create(%s) "KYEL"dir-entry not found", path);
  debugf(DBG_LEVEL_NORM, KBLU "exit 2: cfs_create(%s)=(%s) result=%d:%s", path,
         file_path_safe, errsv, strerror(errsv));
  return 0;
}