diff --git a/src/gfal_ext.c b/src/gfal_ext.c deleted file mode 100644 index cb1d6a416d564e1b13bf9093fa6f11749c7bcf80..0000000000000000000000000000000000000000 --- a/src/gfal_ext.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) CERN 2013-2017 - * - * Copyright (c) Members of the EMI Collaboration. 2010-2013 - * See http://www.eu-emi.eu/partners for details on the copyright - * holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file gfal_ext.c - * Some extended functionalities for gfalFS - **/ - -#include <errno.h> -#include <math.h> -#include <string.h> -#include <gfal_api.h> -#include "gfal_ext.h" - - -gfalFS_dir_handle gfalFS_dir_handle_new(void *fh, const char *dirpath) -{ - gfalFS_dir_handle ret = g_new0(struct _gfalFS_dir_handle, 1); - g_strlcpy(ret->path, dirpath, GFALFS_URL_MAX_LEN); - ret->fh = fh; - ret->offset = 0; - ret->mut = g_mutex_new(); - return ret; -} - - -void gfalFS_dir_handle_delete(gfalFS_dir_handle handle) -{ - if (handle) { - g_mutex_free(handle->mut); - free(handle); - } -} - - -int gfalFS_dir_handle_readdir(gfalFS_dir_handle handle, off_t offset, void *buf, fuse_fill_dir_t filler) -{ - char buff[2048]; - char err_buff[1024]; - int ret; - - if (offset != handle->offset) { // corrupted seq - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_readdir err : Dir descriptor corruption, not in order %ld %ld", - (long) offset, (long) handle->offset); - return -(EFAULT); - } - if (handle->dir != NULL) { // try to recover from previous saved status - - struct stat st; - memset(&st, 0, sizeof(st)); - st.st_ino = handle->dir->d_ino; - st.st_mode = handle->dir->d_type << 12; - gfalfs_tune_stat(&st); - - if (filler(buf, handle->dir->d_name, &st, handle->offset + 1) == 1) { - return 0; // filler buffer full - } - else { - handle->offset += 1; - handle->dir = NULL; - return 0; - } - } - - while ((handle->dir = gfal_readdir(handle->fh)) != NULL) { - if (fuse_interrupted()) { - return -(ECANCELED); - } - - struct stat st; - memset(&st, 0, sizeof(st)); - st.st_ino = handle->dir->d_ino; - st.st_mode = handle->dir->d_type << 12; - - ret = filler(buf, handle->dir->d_name, &st, handle->offset + 1); - if (ret == 1) { // buffer full - return 0; - } - handle->offset += 1; - - } - if ((ret = -(gfal_posix_code_error()))) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_readdir err %d for path %s: %s ", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; - } - return 0; - -} - - -void *gfalFS_dir_handle_get_fd(gfalFS_dir_handle handle) -{ - return handle->fh; -} - - -void gfalfs_tune_stat(struct stat *st) -{ - // tune block size to 16Mega for cp optimization with big files on network file system - st->st_blksize = (1 << 24); - // workaround for utilities like du that use st_blocks (LCGUTIL-289) - st->st_blocks = ceil(st->st_size / 512.0); -} diff --git a/src/gfal_ext.h b/src/gfal_ext.h deleted file mode 100644 index 2527a3e801749fa36e7e5d1c75550f03aac89fd0..0000000000000000000000000000000000000000 --- a/src/gfal_ext.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) CERN 2013-2017 - * - * Copyright (c) Members of the EMI Collaboration. 2010-2013 - * See http://www.eu-emi.eu/partners for details on the copyright - * holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -/** - * @file gfal_ext.c - * @brief Header for some extended functionalities for gfalFS - */ - -#include <stdlib.h> -#include <glib.h> -#include "gfal_opers.h" - -#define GFALFS_URL_MAX_LEN 2048 - -typedef struct _gfalFS_file_handle{ - char path[GFALFS_URL_MAX_LEN]; - void* fh; - off_t offset; - GMutex* mut; - -} *gfalFS_file_handle; - - -typedef struct _gfalFS_dir_handle{ - char path[GFALFS_URL_MAX_LEN]; - void* fh; - off_t offset; // current offset - struct dirent* dir; // last dir, NULL if no state - GMutex* mut; - -} *gfalFS_dir_handle; - - -gfalFS_dir_handle gfalFS_dir_handle_new(void* fh, const char* dirpath); -int gfalFS_dir_handle_readdir(gfalFS_dir_handle handle, off_t offset, void* buff, fuse_fill_dir_t filler); -void* gfalFS_dir_handle_get_fd(gfalFS_dir_handle handle); -void gfalFS_dir_handle_delete(gfalFS_dir_handle handle); - - -gfalFS_file_handle gfalFS_file_handle_new(void* fh, const char* path); - - -void gfalFS_file_handle_delete(gfalFS_file_handle handle); - -void* gfalFS_file_handle_get_fd(gfalFS_file_handle handle); - -int gfalFS_file_handle_write(gfalFS_file_handle handle, const char *buf, size_t size, off_t offset); - -int gfalFS_file_handle_read(gfalFS_file_handle handle, const char *buf, size_t size, off_t offset); - - -void gfalfs_tune_stat(struct stat * st); - diff --git a/src/gfal_opers.c b/src/gfal_opers.c index b8c658261fcd8a4f14fed53b4a74f37b7c4dca0b..2c5750090a9ce0d38bafe467e63e380dbb0870f1 100644 --- a/src/gfal_opers.c +++ b/src/gfal_opers.c @@ -26,9 +26,9 @@ #include <string.h> #include <errno.h> +#include <math.h> #include <gfal_api.h> #include "gfal_opers.h" -#include "gfal_ext.h" char mount_point[2048]; @@ -40,6 +40,30 @@ size_t s_local_mount_point = 0; gboolean guid_mode = FALSE; +/** + * Logs the error, frees it, and return the -code + */ +static int gfalfs_handle_error(const char *func, GError *error) +{ + int code = error->code; + if (code != ENOATTR) { + gfal2_log(G_LOG_LEVEL_WARNING, "%s: [%s] %s (%d)", func, + g_quark_to_string(error->domain), error->message, error->code); + } + g_error_free(error); + return -code; +} + + +static void gfalfs_tune_stat(struct stat *st) +{ + // tune block size to 16Mega for cp optimization with big files on network file system + st->st_blksize = (1 << 24); + // workaround for utilities like du that use st_blocks (LCGUTIL-289) + st->st_blocks = ceil(st->st_size / 512.0); +} + + void gfalfs_set_local_mount_point(const char *local_mp) { g_strlcpy(local_mount_point, local_mp, 2048); @@ -101,49 +125,44 @@ convert_external_readlink_to_local_readlink(char *external_buff, size_t s_ext, c static int gfalfs_getattr(const char *path, struct stat *stbuf) { - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_getattr path %s", (char *) path); - char buff[2048]; - char err_buff[1024]; - int ret = -1; - gfalfs_construct_path(path, buff, 2048); - if (fuse_interrupted()) { - return -(ECANCELED); - } - int a = gfal_lstat(buff, stbuf); - if ((ret = -(gfal_posix_code_error()))) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_getattr error %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; - } - else { - gfalfs_tune_stat(stbuf); + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_getattr path %s", path); + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + if(gfal2_lstat(ctx, full_url, stbuf, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + + gfalfs_tune_stat(stbuf); if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return a; + return 0; } static int gfalfs_readlink(const char *path, char *link_buff, size_t buffsiz) { - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_readlink path %s", (char *) path); - char buff[2048]; - char err_buff[1024]; + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_readlink path %s", path); + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + char tmp_link_buff[2048]; - int ret = -1; - gfalfs_construct_path(path, buff, 2048); - ssize_t a = gfal_readlink(buff, tmp_link_buff, 2048 - 1); - convert_external_readlink_to_local_readlink(tmp_link_buff, a, link_buff, buffsiz); - if ((ret = -(gfal_posix_code_error()))) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_readlink error %d for path %s: %s", - gfal_posix_code_error(), buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; + GError *error = NULL; + ssize_t ret = gfal2_readlink(ctx, full_url, tmp_link_buff, sizeof(tmp_link_buff), &error); + if (ret < 0) { + return gfalfs_handle_error(__func__, error); } + + convert_external_readlink_to_local_readlink(tmp_link_buff, ret, link_buff, buffsiz); + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } return 0; } @@ -151,103 +170,119 @@ static int gfalfs_readlink(const char *path, char *link_buff, size_t buffsiz) static int gfalfs_opendir(const char *path, struct fuse_file_info *f) { - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_opendir path %s", (char *) path); - char buff[2048]; - char err_buff[1024]; - int ret; - gfalfs_construct_path(path, buff, 2048); - DIR *i = gfal_opendir(buff); - if ((ret = -(gfal_posix_code_error()))) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_opendir err %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; - } - f->fh = (uint64_t) gfalFS_dir_handle_new((void *) i, buff); - if (fuse_interrupted()) { - return -(ECANCELED); + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_opendir path %s", path); + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + DIR *i = gfal2_opendir(ctx, full_url, &error); + if (i == NULL) { + return gfalfs_handle_error(__func__, error); } - return (i != NULL) ? 0 : -(gfal_posix_code_error()); + + f->fh = (uint64_t)i; + return 0; +} + + +static int gfalfs_releasedir(const char *path, struct fuse_file_info *fi) +{ + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_closedir fd : %d", fi->fh); + + DIR *d = (DIR*)fi->fh; + GError *error = NULL; + if (gfal2_closedir(ctx, d, &error) < 0) { + return gfalfs_handle_error(__func__, error); + } + + return 0; } static int gfalfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_readdir path %s", path); - return gfalFS_dir_handle_readdir((gfalFS_dir_handle) fi->fh, offset, buf, filler); -} + DIR *d = (DIR*)fi->fh; + GError *error = NULL; -static int gfalfs_open(const char *path, struct fuse_file_info *fi) -{ - char buff[2048]; - char err_buff[1024]; - int ret = -1; - gfalfs_construct_path(path, buff, 2048); - int i = gfal_open(buff, fi->flags, 755); - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_open path %s %d", path, i); - if ((ret = -(gfal_posix_code_error())) || i == 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_open err %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; + struct stat st; + struct dirent *dent; + + while ((dent = gfal2_readdirpp(ctx, d, &st, &error)) != NULL) { + gfalfs_tune_stat(&st); + + if (filler(buf, dent->d_name, &st, offset++) != 0) { + gfal2_log(G_LOG_LEVEL_DEBUG, "Filler full"); + break; + } + + if (fuse_interrupted()) { + return -ECANCELED; + } } - fi->fh = i; - if (fuse_interrupted()) { - return -(ECANCELED); + if (error) { + return gfalfs_handle_error(__func__, error); } + return 0; } -static int gfalfs_creat(const char *path, mode_t mode, struct fuse_file_info *fi) +static int gfalfs_open(const char *path, struct fuse_file_info *fi) { - char buff[2048]; - char err_buff[1024]; - int ret = -1; - gfalfs_construct_path(path, buff, 2048); - int i = gfal_creat(buff, mode); - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_open path %s %d", path, i); - if ((ret = -(gfal_posix_code_error())) || i == 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_open err %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - gfal_posix_clear_error(); - return ret; - } - fi->fh = i; - if (fuse_interrupted()) { - return -(ECANCELED); - } - return 0; + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_open path %s", path); -} + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + GError *error = NULL; + int fd = gfal2_open2(ctx, full_url, fi->flags, 755, &error); + if (fd < 0) { + return gfalfs_handle_error(__func__, error); + } -int gfalfs_chown(const char *path, uid_t uid, gid_t guid) -{ - // do nothing, change prop not authorized - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_chown path : %s", path); - gfal_posix_clear_error(); + fi->fh = fd; return 0; } -int gfalfs_utimens(const char *path, const struct timespec tv[2]) +static int gfalfs_creat(const char *path, mode_t mode, struct fuse_file_info *fi) { - // do nothing, not implemented yet - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_utimens path : %s", path); - gfal_posix_clear_error(); + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_creat path %s", path); + + char full_url[2048]; + gfalfs_construct_path(path, full_url, 2048); + + GError *error = NULL; + int fd = gfal2_creat(ctx, full_url, mode, &error); + if (fd < 0) { + return gfalfs_handle_error(__func__, error); + } + + fi->fh = fd; return 0; } -int gfalfs_truncate(const char *path, off_t size) +static int gfalfs_release(const char *path, struct fuse_file_info *fi) { - // do nothing, not implemented yet - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_truncate path : %s", path); - gfal_posix_clear_error(); + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_close fd : %d", fi->fh); + + GError *error = NULL; + if (gfal2_close(ctx, fi->fh, &error) < 0) { + return gfalfs_handle_error(__func__, error); + } + return 0; } @@ -255,20 +290,17 @@ int gfalfs_truncate(const char *path, off_t size) static int gfalfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - char err_buff[1024]; - int ret = 0; + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_read path : %s fd : %d", path, fi->fh); - ret = gfal_pread(GPOINTER_TO_INT(fi->fh), (void *) buf, size, offset); + GError *error = NULL; + ssize_t ret = gfal2_pread(ctx, fi->fh, buf, size, offset, &error); if (ret < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_pread err %d for path %s: %s", gfal_posix_code_error(), - path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); + return gfalfs_handle_error(__func__, error); } if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } return ret; } @@ -277,303 +309,253 @@ static int gfalfs_read(const char *path, char *buf, size_t size, off_t offset, static int gfalfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - char err_buff[1024]; - int ret = 0; + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_write path : %s fd : %d", path, fi->fh); - ret = gfal_pwrite(GPOINTER_TO_INT(fi->fh), (void *) buf, size, offset); + GError *error = NULL; + ssize_t ret = gfal2_pwrite(ctx, fi->fh, (const void *) buf, size, offset, &error); if (ret < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_pwrite err %d for path %s: %s", gfal_posix_code_error(), - path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); + return gfalfs_handle_error(__func__, error); } if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } return ret; } +int gfalfs_chown(const char *path, uid_t uid, gid_t guid) +{ + // do nothing, change prop not authorized + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_chown path : %s", path); + return 0; +} + + +int gfalfs_utimens(const char *path, const struct timespec tv[2]) +{ + // do nothing, not implemented yet + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_utimens path : %s", path); + return 0; +} + + +int gfalfs_truncate(const char *path, off_t size) +{ + // do nothing, not implemented yet + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_truncate path : %s", path); + return 0; +} + + static int gfalfs_access(const char *path, int flag) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_access path : %s", path); - char buff[2048]; - char err_buff[1024]; - int ret; - - gfalfs_construct_path(path, buff, 2048); - int i = gfal_access(buff, flag); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_access err %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + if (gfal2_access(ctx, full_url, flag, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } static int gfalfs_unlink(const char *path) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_access path : %s", path); - char buff[2048]; - char err_buff[1024]; - int ret; - - gfalfs_construct_path(path, buff, 2048); - int i = gfal_unlink(buff); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_access err %d for path %s: %s", gfal_posix_code_error(), - buff, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + if (gfal2_unlink(ctx, full_url, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } static int gfalfs_mkdir(const char *path, mode_t mode) { - gfal_posix_clear_error(); + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_mkdir path : %s", path); - char buff_path[2048]; - char err_buff[1024]; - - gfalfs_construct_path(path, buff_path, 2048); - int ret; - int i = gfal_mkdir(buff_path, mode); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_mkdir err %d for path %s: %s", gfal_posix_code_error(), - buff_path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + if (gfal2_mkdir(ctx, full_url, mode, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } static int gfalfs_getxattr(const char *path, const char *name, char *buff, size_t s_buff) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_getxattr path : %s, name : %s, size %d", path, name, s_buff); - char buff_path[2048]; - char err_buff[1024]; - - gfalfs_construct_path(path, buff_path, 2048); - int ret; - int i = gfal_getxattr(buff_path, name, buff, s_buff); - if (i < 0) { - int errcode = gfal_posix_code_error(); - if (errcode == EPROTONOSUPPORT) { // silent the non supported errors - errcode = ENOATTR; - } - if (errcode != ENOATTR) { // suppress verbose error for ENOATTR for perfs reasons - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_getxattr err %d for path %s: %s", errcode, - buff_path, gfal_posix_strerror_r(err_buff, 1024)); + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + int ret = gfal2_getxattr(ctx, full_url, name, buff, s_buff, &error); + if (ret < 0) { + if (error->code == EPROTONOSUPPORT) { // silent the non supported errors + error->code = ENOATTR; } - ret = -(errcode); - gfal_posix_clear_error(); - return ret; + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return ret; } static int gfalfs_setxattr(const char *path, const char *name, const char *buff, size_t s_buff, int flag) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_setxattr path : %s, name : %s", path, name); - char buff_path[2048]; - char err_buff[1024]; - gfalfs_construct_path(path, buff_path, 2048); - - int ret; - int i = gfal_setxattr(buff_path, name, buff, s_buff, flag); - if (i < 0) { - const int errcode = gfal_posix_code_error(); - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_setxattr err %d for path %s: %s", errcode, - buff_path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(errcode); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + if (gfal2_setxattr(ctx, full_url, name, buff, s_buff, flag, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } static int gfalfs_listxattr(const char *path, char *list, size_t s_list) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_listxattr path : %s, size %d", path, s_list); - char buff_path[2048]; - char err_buff[1024]; - gfalfs_construct_path(path, buff_path, 2048); - - int ret; - int i = gfal_listxattr(buff_path, list, s_list); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_listxattr err %d for path %s: %s", gfal_posix_code_error(), - buff_path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, sizeof(full_url)); + + GError *error = NULL; + int ret = gfal2_listxattr(ctx, full_url, list, s_list, &error); + if (ret < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return ret; } static int gfalfs_rename(const char *oldpath, const char *newpath) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_rename oldpath : %s, newpath : %s", oldpath, newpath); - char buff_oldpath[2048]; - char buff_newpath[2048]; - char err_buff[1024]; - - int ret; - gfalfs_construct_path(oldpath, buff_oldpath, 2048); - gfalfs_construct_path(newpath, buff_newpath, 2048); - int i = gfal_rename(buff_oldpath, buff_newpath); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_rename err %d for oldpath %s: %s", gfal_posix_code_error(), - buff_oldpath, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; - } - if (fuse_interrupted()) { - return -(ECANCELED); - } - return i; - -} + char full_url_old[2048]; + char full_url_new[2048]; + gfalfs_construct_path(oldpath, full_url_old, sizeof(full_url_old)); + gfalfs_construct_path(newpath, full_url_new, sizeof(full_url_new)); -static int gfalfs_symlink(const char *oldpath, const char *newpath) -{ - char buff_oldpath[2048]; - char buff_newpath[2048]; - char err_buff[1024]; - int ret; - - gfalfs_construct_path_from_abs_local(oldpath, buff_oldpath, 2048); - gfalfs_construct_path(newpath, buff_newpath, 2048); - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_symlink oldpath : %s, newpath : %s", buff_oldpath, buff_newpath); - int i = gfal_symlink(buff_oldpath, buff_newpath); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_symlink err %d for oldpath %s: %s", - gfal_posix_code_error(), buff_oldpath, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + GError *error = NULL; + if (gfal2_rename(ctx, full_url_old, full_url_new, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } -static int gfalfs_release(const char *path, struct fuse_file_info *fi) +static int gfalfs_symlink(const char *oldpath, const char *newpath) { - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_close fd : %d", fi->fh); - char err_buff[1024]; - const int fd = GPOINTER_TO_INT(fi->fh); - - int i = gfal_close(fd); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_close err %d for fd %d: %s", gfal_posix_code_error(), - fi->fh, gfal_posix_strerror_r(err_buff, 1024)); - i = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - } - return i; -} + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; + gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_symlink oldpath : %s, newpath : %s", oldpath, newpath); + char full_url_old[2048]; + char full_url_new[2048]; + gfalfs_construct_path_from_abs_local(oldpath, full_url_old, sizeof(full_url_old)); + gfalfs_construct_path(newpath, full_url_new, sizeof(full_url_new)); -static int gfalfs_releasedir(const char *path, struct fuse_file_info *fi) -{ - gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_closedir fd : %d", fi->fh); - char err_buff[1024]; + GError *error = NULL; + if (gfal2_symlink(ctx, full_url_old, full_url_new, &error) < 0) { + return gfalfs_handle_error(__func__, error); + } - DIR *d = gfalFS_dir_handle_get_fd((void *) fi->fh); - int i = gfal_closedir(d); - int ret; - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_closedir err %d for fd %d: %s", gfal_posix_code_error(), - fi->fh, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + if (fuse_interrupted()) { + return -ECANCELED; } - return i; + return 0; } static int gfalfs_chmod(const char *path, mode_t mode) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_chmod path : %s", path); - char buff_path[2048]; - char err_buff[1024]; - int ret; - - gfalfs_construct_path(path, buff_path, 2048); - int i = gfal_chmod(buff_path, mode); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_chmod err %d for path %s: %s", gfal_posix_code_error(), - buff_path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, 2048); + + GError *error = NULL; + if (gfal2_chmod(ctx, full_url, mode, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } static int gfalfs_rmdir(const char *path) { + gfal2_context_t ctx = (gfal2_context_t)fuse_get_context()->private_data; gfal2_log(G_LOG_LEVEL_MESSAGE, "gfalfs_rmdir path : %s", path); - char buff_path[2048]; - char err_buff[1024]; - int ret; - - gfalfs_construct_path(path, buff_path, 2048); - int i = gfal_rmdir(buff_path); - if (i < 0) { - gfal2_log(G_LOG_LEVEL_WARNING, "gfalfs_rmdir err %d for path %s: %s", gfal_posix_code_error(), - buff_path, gfal_posix_strerror_r(err_buff, 1024)); - ret = -(gfal_posix_code_error()); - gfal_posix_clear_error(); - return ret; + + char full_url[2048]; + gfalfs_construct_path(path, full_url, 2048); + + GError *error = NULL; + if (gfal2_rmdir(ctx, full_url, &error) < 0) { + return gfalfs_handle_error(__func__, error); } + if (fuse_interrupted()) { - return -(ECANCELED); + return -ECANCELED; } - return i; + return 0; } @@ -594,6 +576,37 @@ int gfalfs_fake_fgetattr(const char *url, struct stat *st, struct fuse_file_info } +void *gfalfs_init(struct fuse_conn_info *conn) +{ + gfal2_log(G_LOG_LEVEL_INFO, "Creating gfal2 context"); + + GError *error = NULL; + gfal2_context_t ctx = gfal2_context_new(&error); + if (!ctx) { + gfal2_log(G_LOG_LEVEL_CRITICAL, "Failed to instantiate the gfal2 context: %s", error->message); + g_clear_error(&error); + return NULL; + } + + char version_str[32]; + snprintf(version_str, sizeof(version_str), "%d.%d", conn->proto_major, conn->proto_minor); + if (gfal2_set_user_agent(ctx, "gfalFS", version_str, &error) != 0) { + gfal2_log(G_LOG_LEVEL_ERROR, "Failed to set the user agent: %s", error->message); + g_clear_error(&error); + } + + return ctx; +} + + +void gfalfs_destroy(void *ptr) +{ + gfal2_log(G_LOG_LEVEL_INFO, "Destroying gfal2 context"); + gfal2_context_t ctx = (gfal2_context_t)ptr; + gfal2_context_free(ctx); +} + + struct fuse_operations gfal_oper = { .getattr = gfalfs_getattr, .readdir = gfalfs_readdir, @@ -619,4 +632,6 @@ struct fuse_operations gfal_oper = { .listxattr = gfalfs_listxattr, .readlink = gfalfs_readlink, .unlink = gfalfs_unlink, + .init = gfalfs_init, + .destroy = gfalfs_destroy };