Exemplo n.º 1
0
static int cfs_chmod(const char* path, mode_t mode)
{
  debugf(DBG_LEVEL_NORM, KBLU"cfs_chmod(%s,%d)", path, mode);
  dir_entry* de = check_path_info(path);
  if (de)
  {
    if (de->chmod != mode)
    {
      debugf(DBG_LEVEL_NORM, "cfs_chmod(%s): change mode from %d to %d", path,
             de->chmod, mode);
      de->chmod = mode;
      //todo: issue a PUT request to update metadata (empty request just to update headers?)
      int response = cloudfs_update_meta(de);
    }
  }
  return 0;
}
Exemplo n.º 2
0
static int cfs_chown(const char* path, uid_t uid, gid_t gid)
{
  debugf(DBG_LEVEL_NORM, KBLU "cfs_chown(%s,%d,%d)", path, uid, gid);
  dir_entry* de = check_path_info(path);
  if (de)
  {
    if (de->uid != uid || de->gid != gid)
    {
      debugf(DBG_LEVEL_NORM, "cfs_chown(%s): change from uid:gid %d:%d to %d:%d",
             path, de->uid, de->gid, uid, gid);
      de->uid = uid;
      de->gid = gid;
      //issue a PUT request to update metadata (quick request just to update headers)
      int response = cloudfs_update_meta(de);
    }
  }
  return 0;
}
Exemplo n.º 3
0
static int
fixurl(char *gfarm_url)
{
	char *gfarm_file, *local_path, *e;
	char sec[GFARM_INT32STRLEN];
	struct stat sb;
	int rank;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		return 1;
	}

	/* check whether gfarm_url is directory or not. */
	e = gfarm_path_localize(gfarm_file, &local_path);
	if (e == NULL && stat(local_path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
		int r = 1;
		if (chdir(local_path) == 0)
			r = fixdir(".", gfarm_url);
		free(gfarm_file);
		free(local_path);
		return (r);
	}
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		free(gfarm_file);
		return (1);
	}
	free(local_path);

	/* XXX - assume gfarm_url is a fragmented file. */
	e = gfs_pio_get_node_rank(&rank);
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		goto error_gfarm_file;
	}

	e = gfarm_path_localize_file_fragment(gfarm_file, rank, &local_path);
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		goto error_gfarm_file;
	}

	e = check_path_info(gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		if (delete_invalid_file) {
			if (unlink(local_path) == 0)
				printf("%s on %s: deleted\n",
				       local_path, gfarm_host_get_self_name());
			else
				perror(local_path);
		}
		goto error_local_path;
	}

	sprintf(sec, "%d", rank);
	e = fixfrag_i(local_path, gfarm_file, sec);
	if (e != NULL && e != GFARM_ERR_ALREADY_EXISTS) {
		fprintf(stderr, "%s (%s) on %s: %s\n", gfarm_url, sec,
			gfarm_host_get_self_name(), e);
		if (delete_invalid_file) {
			if (unlink(local_path) == 0)
				printf("%s on %s: deleted\n",
				       local_path, gfarm_host_get_self_name());
			else
				perror(local_path);
		}
		goto error_local_path;
	}

	/* printf("%s (%s): fixed\n", gfarm_url, sec); */

	return (0);

 error_local_path:
	free(local_path);
 error_gfarm_file:
	free(gfarm_file);
	return (1);
}
Exemplo n.º 4
0
static int
fixfrag(char *pathname, char *gfarm_prefix)
{
	char *gfarm_url, *sec, *gfarm_file, *e;
	int r = 0;

	gfarm_url = malloc(strlen(gfarm_prefix) + strlen(pathname) + 2);
	if (gfarm_url == NULL) {
		fputs("not enough memory", stderr);
		return 1;
	}
	strcpy(gfarm_url, gfarm_prefix);
	if (gfarm_url[strlen(gfarm_url) - 1] != '/'
	    && gfarm_url[strlen(gfarm_url) - 1] != ':')
		strcat(gfarm_url, "/");
	strcat(gfarm_url, pathname);

	/* divide into file and section parts. */
	sec = gfarm_url + strlen(gfarm_prefix);
	while (*sec) {
		if (*sec == ':') {
			*sec = '\0';
			++sec;
			break;
		}
		++sec;
	}
	if (*sec == '\0') {
		fprintf(stderr, "%s on %s: invalid filename\n", pathname,
			gfarm_host_get_self_name());
		free(gfarm_url);
		return 1;
	}

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s on %s: %s\n", gfarm_url,
			gfarm_host_get_self_name(), e);
		free(gfarm_url);
		return 1;
	}

	/* check whether the path info is already registered. */
	e = check_path_info(gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s (%s) on %s: %s\n", gfarm_url, sec,
			gfarm_host_get_self_name(), e);
		if (delete_invalid_file) {
			if (unlink(pathname) == 0)
				printf("%s on %s: deleted\n",
				       pathname, gfarm_host_get_self_name());
			else
				perror(pathname);
		}
		r = 1;
		goto finish;
	}

	/* check whether the fragment is already registered. */
	e = fixfrag_i(pathname, gfarm_file, sec);
	if (e != NULL) {
		if (e != GFARM_ERR_ALREADY_EXISTS) {
			fprintf(stderr, "%s on %s: %s\n", pathname,
				gfarm_host_get_self_name(), e);
			if (delete_invalid_file) {
				if (unlink(pathname) == 0)
					printf("%s on %s: deleted\n",
					       pathname,
					       gfarm_host_get_self_name());
				else
					perror(pathname);
			}
			r = 1;
		}
		else
			/* no message */;
	}
	else
		printf("%s (%s) on %s: fixed\n", gfarm_url, sec,
		       gfarm_host_get_self_name());

 finish:
	free(gfarm_file);
	free(gfarm_url);

	return (r);
}
Exemplo n.º 5
0
//todo: flush will upload a file again even if just file attributes are changed.
//optimisation needed to detect if content is changed and to only save meta when just attribs are modified.
static int cfs_flush(const char* path, struct fuse_file_info* info)
{
  debugf(DBG_LEVEL_NORM, KBLU "cfs_flush(%s)", path);
  debug_print_descriptor(info);
  openfile* of = (openfile*)(uintptr_t)info->fh;
  int errsv = 0;

  if (of)
  {
    // get the actual file size and truncate it. This ensures that if the new file is smaller
    // than the previous one, the proper size is uploaded.
    struct stat stbuf;
    cfs_getattr(path, &stbuf);
    update_dir_cache(path, stbuf.st_size, 0, 0);
    ftruncate(of->fd, stbuf.st_size);

    if (of->flags & O_RDWR || of->flags & O_WRONLY)
    {
      FILE* fp = fdopen(dup(of->fd), "r");
      errsv = errno;
      if (fp != NULL)
      {
        rewind(fp);
        //calculate md5 hash, compare with cloud hash to determine if file content is changed
        char md5_file_hash_str[MD5_DIGEST_HEXA_STRING_LEN] = "\0";
        file_md5(fp, md5_file_hash_str);
        dir_entry* de = check_path_info(path);
        if (de && de->md5sum != NULL && (!strcasecmp(md5_file_hash_str, de->md5sum)))
        {
          //file content is identical, no need to upload entire file, just update metadata
          debugf(DBG_LEVEL_NORM, KBLU
                 "cfs_flush(%s): skip full upload as content did not change", path);
          cloudfs_update_meta(de);
        }
        else
        {
          rewind(fp);
          debugf(DBG_LEVEL_NORM, KBLU
                 "cfs_flush(%s): perform full upload as content changed (or no file found in cache)",
                 path);
          if (!cloudfs_object_read_fp(path, fp))
          {
            fclose(fp);
            errsv = errno;
            debugf(DBG_LEVEL_NORM, KRED"exit 0: cfs_flush(%s) result=%d:%s", path, errsv,
                   strerror(errno));
            return -ENOENT;
          }
        }
        fclose(fp);
        errsv = errno;
      }
      else
        debugf(DBG_LEVEL_EXT, KRED "status: cfs_flush, err=%d:%s", errsv,
               strerror(errno));
    }
  }
  debugf(DBG_LEVEL_NORM, KBLU "exit 1: cfs_flush(%s) result=%d:%s", path, errsv,
         strerror(errno));
  return 0;
}
Exemplo n.º 6
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;
}