diff options
Diffstat (limited to 'api/src')
| -rw-r--r-- | api/src/Makefile.am | 2 | ||||
| -rw-r--r-- | api/src/README.Symbol_Versions | 2 | ||||
| -rw-r--r-- | api/src/gfapi-messages.h | 97 | ||||
| -rw-r--r-- | api/src/gfapi.aliases | 58 | ||||
| -rw-r--r-- | api/src/gfapi.map | 113 | ||||
| -rw-r--r-- | api/src/glfs-fops.c | 1722 | ||||
| -rw-r--r-- | api/src/glfs-handleops.c | 277 | ||||
| -rw-r--r-- | api/src/glfs-handles.h | 16 | ||||
| -rw-r--r-- | api/src/glfs-internal.h | 110 | ||||
| -rw-r--r-- | api/src/glfs-master.c | 41 | ||||
| -rw-r--r-- | api/src/glfs-mem-types.h | 2 | ||||
| -rw-r--r-- | api/src/glfs-mgmt.c | 261 | ||||
| -rw-r--r-- | api/src/glfs-resolve.c | 180 | ||||
| -rw-r--r-- | api/src/glfs.c | 337 | ||||
| -rw-r--r-- | api/src/glfs.h | 294 |
15 files changed, 2601 insertions, 911 deletions
diff --git a/api/src/Makefile.am b/api/src/Makefile.am index 6ed30bc99f6..7f9a7d17b35 100644 --- a/api/src/Makefile.am +++ b/api/src/Makefile.am @@ -19,7 +19,7 @@ libgfapi_la_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/rpc/xdr/src \ -I$(top_builddir)/rpc/xdr/src \ -DDATADIR=\"$(localstatedir)\" \ - -D__USE_FILE_OFFSET64 + -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/api/src/README.Symbol_Versions b/api/src/README.Symbol_Versions index d5cdedd826b..b6ec95f9311 100644 --- a/api/src/README.Symbol_Versions +++ b/api/src/README.Symbol_Versions @@ -1,3 +1,3 @@ -See .../doc/gfapi-symbol-versions/gfapi-symbol-versions.md +See ../../doc/developer-guide/gfapi-symbol-versions.md diff --git a/api/src/gfapi-messages.h b/api/src/gfapi-messages.h index 20418627690..b9223940416 100644 --- a/api/src/gfapi-messages.h +++ b/api/src/gfapi-messages.h @@ -11,7 +11,7 @@ #ifndef _GFAPI_MESSAGES_H__ #define _GFAPI_MESSAGES_H__ -#include "glfs-message-id.h" +#include <glusterfs/glfs-message-id.h> /* To add new message IDs, append new identifiers at the end of the list. * @@ -49,6 +49,99 @@ GLFS_MSGID(API, API_MSG_MEM_ACCT_INIT_FAILED, API_MSG_MASTER_XLATOR_INIT_FAILED, API_MSG_INODE_LINK_FAILED, API_MSG_STATEDUMP_FAILED, API_MSG_XREADDIRP_R_FAILED, API_MSG_LOCK_INSERT_MERGE_FAILED, API_MSG_SETTING_LOCK_TYPE_FAILED, API_MSG_INODE_FIND_FAILED, - API_MSG_FDCTX_SET_FAILED); + API_MSG_FDCTX_SET_FAILED, API_MSG_UPCALL_SYNCOP_FAILED, + API_MSG_INVALID_ARG, API_MSG_UPCALL_EVENT_NULL_RECEIVED, + API_MSG_FLAGS_HANDLE, API_MSG_FDCREATE_FAILED_ON_GRAPH, + API_MSG_TRANS_RDMA_DEP, API_MSG_TRANS_NOT_SUPPORTED, + API_MSG_FS_NOT_INIT, API_MSG_INVALID_SYSRQ, + API_MSG_DECODE_XDR_FAILED, API_MSG_NULL, API_MSG_CALL_NOT_SUCCESSFUL, + API_MSG_CALL_NOT_VALID, API_MSG_UNABLE_TO_DEL, + API_MSG_REMOTE_HOST_DISCONN, API_MSG_HANDLE_NOT_SET); +#define API_MSG_ALLOC_FAILED_STR "Upcall allocation failed" +#define API_MSG_LOCK_INSERT_MERGE_FAILED_STR \ + "Lock insertion and splitting/merging failed" +#define API_MSG_SETTING_LOCK_TYPE_FAILED_STR "Setting lock type failed" + +#define API_MSG_INVALID_ARG_STR "Invalid" +#define API_MSG_INVALID_ENTRY_STR "Upcall entry validation failed" +#define API_MSG_INODE_FIND_FAILED_STR "Unable to find inode entry" +#define API_MSG_CREATE_HANDLE_FAILED_STR "handle creation failed" +#define API_MSG_UPCALL_EVENT_NULL_RECEIVED_STR \ + "Upcall_EVENT_NULL received. Skipping it" +#define API_MSG_UPCALL_SYNCOP_FAILED_STR "Synctask for upcall failed" +#define API_MSG_FDCREATE_FAILED_STR "Allocating anonymous fd failed" +#define API_MSG_XREADDIRP_R_FAILED_STR "glfs_x_readdirp_r failed" +#define API_MSG_FDCTX_SET_FAILED_STR "Setting fd ctx failed" +#define API_MSG_FLAGS_HANDLE_STR "arg not set. Flags handled are" +#define API_MSG_INODE_REFRESH_FAILED_STR "inode refresh failed" +#define API_MSG_INODE_LINK_FAILED_STR "inode linking failed" +#define API_MSG_GET_CWD_FAILED_STR "Failed to get cwd" +#define API_MSG_FGETXATTR_FAILED_STR "fgetxattr failed" +#define API_MSG_LOCKINFO_KEY_MISSING_STR "missing lockinfo key" +#define API_MSG_FSYNC_FAILED_STR "fsync() failed" +#define API_MSG_FDCREATE_FAILED_ON_GRAPH_STR "fd_create failed on graph" +#define API_MSG_INODE_PATH_FAILED_STR "inode_path failed" +#define API_MSG_SYNCOP_OPEN_FAILED_STR "syncop_open failed" +#define API_MSG_LOCK_MIGRATE_FAILED_STR "lock migration failed on graph" +#define API_MSG_OPENFD_SKIPPED_STR "skipping openfd in graph" +#define API_MSG_FIRST_LOOKUP_GRAPH_FAILED_STR "first lookup on graph failed" +#define API_MSG_CWD_GRAPH_REF_FAILED_STR "cwd refresh of graph failed" +#define API_MSG_SWITCHED_GRAPH_STR "switched to graph" +#define API_MSG_FSETXATTR_FAILED_STR "fsetxattr failed" +#define API_MSG_MEM_ACCT_INIT_FAILED_STR "Memory accounting init failed" +#define API_MSG_MASTER_XLATOR_INIT_FAILED_STR \ + "master xlator for initialization failed" +#define API_MSG_GFAPI_XLATOR_INIT_FAILED_STR \ + "failed to initialize gfapi translator" +#define API_MSG_VOLFILE_OPEN_FAILED_STR "volume file open failed" +#define API_MSG_VOL_SPEC_FILE_ERROR_STR "Cannot reach volume specification file" +#define API_MSG_TRANS_RDMA_DEP_STR \ + "transport RDMA is deprecated, falling back to tcp" +#define API_MSG_TRANS_NOT_SUPPORTED_STR \ + "transport is not supported, possible values tcp|unix" +#define API_MSG_GLFS_FSOBJ_NULL_STR "fs is NULL" +#define API_MSG_FS_NOT_INIT_STR "fs is not properly initialized" +#define API_MSG_FSMUTEX_LOCK_FAILED_STR \ + "pthread lock on glfs mutex, returned error" +#define API_MSG_FSMUTEX_UNLOCK_FAILED_STR \ + "pthread unlock on glfs mutex, returned error" +#define API_MSG_COND_WAIT_FAILED_STR "cond wait failed" +#define API_MSG_INVALID_SYSRQ_STR "not a valid sysrq" +#define API_MSG_GRAPH_CONSTRUCT_FAILED_STR "failed to construct the graph" +#define API_MSG_API_XLATOR_ERROR_STR \ + "api master xlator cannot be specified in volume file" +#define API_MSG_STATEDUMP_FAILED_STR "statedump failed" +#define API_MSG_DECODE_XDR_FAILED_STR \ + "Failed to decode xdr response for GF_CBK_STATEDUMP" +#define API_MSG_NULL_STR "NULL" +#define API_MSG_XDR_PAYLOAD_FAILED_STR "failed to create XDR payload" +#define API_MSG_CALL_NOT_SUCCESSFUL_STR \ + "GET_VOLUME_INFO RPC call is not successful" +#define API_MSG_XDR_RESPONSE_DECODE_FAILED_STR \ + "Failed to decode xdr response for GET_VOLUME_INFO" +#define API_MSG_CALL_NOT_VALID_STR \ + "Response received for GET_VOLUME_INFO RPC is not valid" +#define API_MSG_GET_VOLINFO_CBK_FAILED_STR \ + "In GET_VOLUME_INFO cbk, received error" +#define API_MSG_FETCH_VOLUUID_FAILED_STR "Unable to fetch volume UUID" +#define API_MSG_INSUFF_SIZE_STR "Insufficient size passed" +#define API_MSG_FRAME_CREAT_FAILED_STR "failed to create the frame" +#define API_MSG_DICT_SET_FAILED_STR "failed to set" +#define API_MSG_XDR_DECODE_FAILED_STR "XDR decoding error" +#define API_MSG_GET_VOLFILE_FAILED_STR "failed to get the volume file" +#define API_MSG_VOLFILE_INFO_STR "No change in volfile, continuing" +#define API_MSG_UNABLE_TO_DEL_STR "unable to delete file" +#define API_MSG_WRONG_OPVERSION_STR \ + "Server is operating at an op-version which is not supported" +#define API_MSG_DICT_SERIALIZE_FAILED_STR "Failed to serialize dictionary" +#define API_MSG_REMOTE_HOST_CONN_FAILED_STR "Failed to connect to remote-host" +#define API_MSG_REMOTE_HOST_DISCONN_STR "disconnected from remote-host" +#define API_MSG_VOLFILE_SERVER_EXHAUST_STR "Exhausted all volfile servers" +#define API_MSG_VOLFILE_CONNECTING_STR "connecting to next volfile server" +#define API_MSG_CREATE_RPC_CLIENT_FAILED_STR "failed to create rpc clnt" +#define API_MSG_REG_NOTIFY_FUNC_FAILED_STR "failed to register notify function" +#define API_MSG_REG_CBK_FUNC_FAILED_STR "failed to register callback function" +#define API_MSG_NEW_GRAPH_STR "New graph coming up" +#define API_MSG_HANDLE_NOT_SET_STR "handle not set. Flags handled for xstat are" #endif /* !_GFAPI_MESSAGES_H__ */ diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases index 9eb1de86c14..bc639e6b99f 100644 --- a/api/src/gfapi.aliases +++ b/api/src/gfapi.aliases @@ -18,30 +18,24 @@ _pub_glfs_from_glfd _glfs_from_glfd$GFAPI_3.4.0 _pub_glfs_set_xlator_option _glfs_set_xlator_option$GFAPI_3.4.0 _pub_glfs_read _glfs_read$GFAPI_3.4.0 _pub_glfs_write _glfs_write$GFAPI_3.4.0 -_pub_glfs_read_async _glfs_read_async$GFAPI_3.4.0 -_pub_glfs_write_async _glfs_write_async$GFAPI_3.4.0 _pub_glfs_readv _glfs_readv$GFAPI_3.4.0 _pub_glfs_writev _glfs_writev$GFAPI_3.4.0 -_pub_glfs_readv_async _glfs_readv_async$GFAPI_3.4.0 -_pub_glfs_writev_async _glfs_writev_async$GFAPI_3.4.0 -_pub_glfs_pread _glfs_pread$GFAPI_3.4.0 -_pub_glfs_pwrite _glfs_pwrite$GFAPI_3.4.0 -_pub_glfs_pread_async _glfs_pread_async$GFAPI_3.4.0 -_pub_glfs_pwrite_async _glfs_pwrite_async$GFAPI_3.4.0 +_pub_glfs_pread34 _glfs_pread$GFAPI_3.4.0 +_pub_glfs_pwrite34 _glfs_pwrite$GFAPI_3.4.0 +_pub_glfs_pread_async34 _glfs_pread_async$GFAPI_3.4.0 +_pub_glfs_pwrite_async34 _glfs_pwrite_async$GFAPI_3.4.0 _pub_glfs_preadv _glfs_preadv$GFAPI_3.4.0 _pub_glfs_pwritev _glfs_pwritev$GFAPI_3.4.0 -_pub_glfs_preadv_async _glfs_preadv_async$GFAPI_3.4.0 -_pub_glfs_pwritev_async _glfs_pwritev_async$GFAPI_3.4.0 _pub_glfs_lseek _glfs_lseek$GFAPI_3.4.0 -_pub_glfs_ftruncate _glfs_ftruncate$GFAPI_3.4.0 -_pub_glfs_ftruncate_async _glfs_ftruncate_async$GFAPI_3.4.0 +_pub_glfs_ftruncate34 _glfs_ftruncate$GFAPI_3.4.0 +_pub_glfs_ftruncate_async34 _glfs_ftruncate_async$GFAPI_3.4.0 _pub_glfs_lstat _glfs_lstat$GFAPI_3.4.0 _pub_glfs_stat _glfs_stat$GFAPI_3.4.0 _pub_glfs_fstat _glfs_fstat$GFAPI_3.4.0 -_pub_glfs_fsync _glfs_fsync$GFAPI_3.4.0 -_pub_glfs_fsync_async _glfs_fsync_async$GFAPI_3.4.0 -_pub_glfs_fdatasync _glfs_fdatasync$GFAPI_3.4.0 -_pub_glfs_fdatasync_async _glfs_fdatasync_async$GFAPI_3.4.0 +_pub_glfs_fsync34 _glfs_fsync$GFAPI_3.4.0 +_pub_glfs_fsync_async34 _glfs_fsync_async$GFAPI_3.4.0 +_pub_glfs_fdatasync34 _glfs_fdatasync$GFAPI_3.4.0 +_pub_glfs_fdatasync_async34 _glfs_fdatasync_async$GFAPI_3.4.0 _pub_glfs_access _glfs_access$GFAPI_3.4.0 _pub_glfs_symlink _glfs_symlink$GFAPI_3.4.0 _pub_glfs_readlink _glfs_readlink$GFAPI_3.4.0 @@ -112,9 +106,7 @@ _pub_glfs_readdir _glfs_readdir$GFAPI_3.5.0 _pub_glfs_readdirplus _glfs_readdirplus$GFAPI_3.5.0 _pub_glfs_fallocate _glfs_fallocate$GFAPI_3.5.0 _pub_glfs_discard _glfs_discard$GFAPI_3.5.0 -_pub_glfs_discard_async _glfs_discard_async$GFAPI_3.5.0 _pub_glfs_zerofill _glfs_zerofill$GFAPI_3.5.0 -_pub_glfs_zerofill_async _glfs_zerofill_async$GFAPI_3.5.0 _pub_glfs_caller_specific_init _glfs_caller_specific_init$GFAPI_3.5.0 _pub_glfs_h_setxattrs _glfs_h_setxattrs$GFAPI_3.5.0 @@ -177,3 +169,33 @@ _pub_glfs_lease _glfs_lease$GFAPI_4.0.0 _pub_glfs_h_lease _glfs_h_lease$GFAPI_4.0.0 _pub_glfs_upcall_lease_get_object _glfs_upcall_lease_get_object$GFAPI_4.1.6 _pub_glfs_upcall_lease_get_lease_type _glfs_upcall_lease_get_lease_type$GFAPI_4.1.6 + +_priv_glfs_statx _glfs_statx$GFAPI_6.0 +_priv_glfs_iatt_from_statx _glfs_iatt_from_statx$GFAPI_6.0 +_priv_glfs_setfspid _glfs_setfspid$GFAPI_6.1 + +_pub_glfs_read_async _glfs_read_async$GFAPI_6.0 +_pub_glfs_write_async _glfs_write_async$GFAPI_6.0 +_pub_glfs_readv_async _glfs_readv_async$GFAPI_6.0 +_pub_glfs_writev_async _glfs_writev_async$GFAPI_6.0 +_pub_glfs_pread _glfs_pread$GFAPI_6.0 +_pub_glfs_pwrite _glfs_pwrite$GFAPI_6.0 +_pub_glfs_pread_async _glfs_pread_async$GFAPI_6.0 +_pub_glfs_pwrite_async _glfs_pwrite_async$GFAPI_6.0 +_pub_glfs_preadv_async _glfs_preadv_async$GFAPI_6.0 +_pub_glfs_pwritev_async _glfs_pwritev_async$GFAPI_6.0 +_pub_glfs_fsync _glfs_fsync$GFAPI_6.0 +_pub_glfs_fsync_async _glfs_fsync_async$GFAPI_6.0 +_pub_glfs_fdatasync _glfs_fdatasync$GFAPI_6.0 +_pub_glfs_fdatasync_async _glfs_fdatasync_async$GFAPI_6.0 +_pub_glfs_ftruncate _glfs_ftruncate$GFAPI_6.0 +_pub_glfs_ftruncate_async _glfs_ftruncate_async$GFAPI_6.0 +_pub_glfs_discard_async _glfs_discard_async$GFAPI_6.0 +_pub_glfs_zerofill_async _glfs_zerofill_async$GFAPI_6.0 +_pub_glfs_copy_file_range _glfs_copy_file_range$GFAPI_6.0 +_pub_glfs_fsetattr _glfs_fsetattr$GFAPI_6.0 +_pub_glfs_setattr _glfs_setattr$GFAPI_6.0 + +_pub_glfs_set_statedump_path _glfs_set_statedump_path@GFAPI_7.0 + +_pub_glfs_h_creat_open _glfs_h_creat_open@GFAPI_6.6 diff --git a/api/src/gfapi.map b/api/src/gfapi.map index 0e886dd84b8..228ac47c084 100644 --- a/api/src/gfapi.map +++ b/api/src/gfapi.map @@ -24,25 +24,30 @@ GFAPI_3.4.0 { glfs_set_xlator_option; glfs_read; glfs_write; - glfs_read_async; - glfs_write_async; + glfs_read_async; + glfs_write_async; glfs_readv; glfs_writev; - glfs_readv_async; - glfs_writev_async; - glfs_pread_async; - glfs_pwrite_async; + glfs_readv_async; + glfs_writev_async; + glfs_pread; + glfs_pwrite; + glfs_pread_async; + glfs_pwrite_async; glfs_preadv; glfs_pwritev; - glfs_preadv_async; - glfs_pwritev_async; + glfs_preadv_async; + glfs_pwritev_async; glfs_lseek; - glfs_ftruncate_async; + glfs_ftruncate; + glfs_ftruncate_async; glfs_lstat; glfs_stat; glfs_fstat; - glfs_fsync_async; - glfs_fdatasync_async; + glfs_fsync; + glfs_fsync_async; + glfs_fdatasync; + glfs_fdatasync_async; glfs_access; glfs_symlink; glfs_readlink; @@ -82,20 +87,9 @@ GFAPI_3.4.0 { glfs_getcwd; glfs_chdir; glfs_fchdir; + glfs_realpath; glfs_posix_lock; glfs_dup; - glfs_pread; - glfs_pwrite; - glfs_pread_async; - glfs_pwrite_async; - glfs_ftruncate; - glfs_ftruncate_async; - glfs_fsync; - glfs_fsync_async; - glfs_fdatasync; - glfs_fdatasync_async; - glfs_realpath; - glfs_h_lookupat; } GFAPI_PRIVATE_3.4.0; GFAPI_3.4.2 { @@ -130,9 +124,9 @@ GFAPI_3.5.0 { glfs_readdirplus; glfs_fallocate; glfs_discard; - glfs_discard_async; + glfs_discard_async; glfs_zerofill; - glfs_zerofill_async; + glfs_zerofill_async; glfs_caller_specific_init; glfs_h_setxattrs; } GFAPI_3.4.2; @@ -214,7 +208,7 @@ GFAPI_3.11.0 { glfs_xreaddirplus_r; glfs_xreaddirplus_r_get_stat; glfs_xreaddirplus_r_get_object; - glfs_object_copy; + glfs_object_copy; } GFAPI_3.10.7; GFAPI_PRIVATE_3.12.0 { @@ -223,20 +217,67 @@ GFAPI_PRIVATE_3.12.0 { } GFAPI_3.11.0; GFAPI_3.13.0 { - global: - glfs_upcall_register; - glfs_upcall_unregister; + global: + glfs_upcall_register; + glfs_upcall_unregister; } GFAPI_PRIVATE_3.12.0; GFAPI_4.0.0 { - global: - glfs_setfsleaseid; - glfs_file_lock; - glfs_lease; - glfs_h_lease; + global: + glfs_setfsleaseid; + glfs_file_lock; + glfs_lease; + glfs_h_lease; } GFAPI_3.13.0; GFAPI_4.1.6 { - glfs_upcall_lease_get_object; - glfs_upcall_lease_get_lease_type; + global: + glfs_upcall_lease_get_object; + glfs_upcall_lease_get_lease_type; } GFAPI_4.0.0; + +GFAPI_PRIVATE_6.0 { + global: + glfs_statx; + glfs_iatt_from_statx; +} GFAPI_4.1.6; + +GFAPI_6.0 { + global: + glfs_read_async; + glfs_write_async; + glfs_readv_async; + glfs_writev_async; + glfs_pread; + glfs_pwrite; + glfs_pread_async; + glfs_pwrite_async; + glfs_preadv_async; + glfs_pwritev_async; + glfs_fsync; + glfs_fsync_async; + glfs_fdatasync; + glfs_fdatasync_async; + glfs_ftruncate; + glfs_ftruncate_async; + glfs_discard_async; + glfs_zerofill_async; + glfs_copy_file_range; + glfs_setattr; + glfs_fsetattr; +} GFAPI_PRIVATE_6.0; + +GFAPI_PRIVATE_6.1 { + global: + glfs_setfspid; +} GFAPI_6.0; + +GFAPI_6.6 { + global: + glfs_h_creat_open; +} GFAPI_PRIVATE_6.1; + +GFAPI_7.0 { + global: + glfs_set_statedump_path; +} GFAPI_6.6; diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 104d3ffd4b1..6aa3c5602d1 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -18,12 +18,13 @@ #include "glfs-internal.h" #include "glfs-mem-types.h" -#include "syncop.h" +#include <glusterfs/syncop.h> #include "glfs.h" #include "gfapi-messages.h" -#include "compat-errno.h" +#include <glusterfs/compat-errno.h> #include <limits.h> #include "glusterfs3.h" +#include <glusterfs/iatt.h> #ifdef NAME_MAX #define GF_NAME_MAX NAME_MAX @@ -31,6 +32,11 @@ #define GF_NAME_MAX 255 #endif +struct upcall_syncop_args { + struct glfs *fs; + struct gf_upcall upcall_data; +}; + #define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1) typedef void (*glfs_io_cbk34)(glfs_fd_t *fd, ssize_t ret, void *data); @@ -113,8 +119,8 @@ glfs_get_upcall_cache_invalidation(struct gf_upcall *to_up_data, ca_data = GF_CALLOC(1, sizeof(*ca_data), glfs_mt_upcall_entry_t); if (!ca_data) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, - "Upcall entry allocation failed."); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, "entry", + NULL); goto out; } @@ -148,8 +154,8 @@ glfs_get_upcall_lease(struct gf_upcall *to_up_data, ca_data = GF_CALLOC(1, sizeof(*ca_data), glfs_mt_upcall_entry_t); if (!ca_data) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, - "Upcall entry allocation failed."); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, "entry", + NULL); goto out; } @@ -201,6 +207,201 @@ glfs_iatt_to_stat(struct glfs *fs, struct iatt *iatt, struct stat *stat) stat->st_dev = fs->dev_id; } +void +glfs_iatt_to_statx(struct glfs *fs, const struct iatt *iatt, + struct glfs_stat *statx) +{ + statx->glfs_st_mask = 0; + + statx->glfs_st_mode = 0; + if (IATT_TYPE_VALID(iatt->ia_flags)) { + statx->glfs_st_mode |= st_mode_type_from_ia(iatt->ia_type); + statx->glfs_st_mask |= GLFS_STAT_TYPE; + } + + if (IATT_MODE_VALID(iatt->ia_flags)) { + statx->glfs_st_mode |= st_mode_prot_from_ia(iatt->ia_prot); + statx->glfs_st_mask |= GLFS_STAT_MODE; + } + + if (IATT_NLINK_VALID(iatt->ia_flags)) { + statx->glfs_st_nlink = iatt->ia_nlink; + statx->glfs_st_mask |= GLFS_STAT_NLINK; + } + + if (IATT_UID_VALID(iatt->ia_flags)) { + statx->glfs_st_uid = iatt->ia_uid; + statx->glfs_st_mask |= GLFS_STAT_UID; + } + + if (IATT_GID_VALID(iatt->ia_flags)) { + statx->glfs_st_gid = iatt->ia_gid; + statx->glfs_st_mask |= GLFS_STAT_GID; + } + + if (IATT_ATIME_VALID(iatt->ia_flags)) { + statx->glfs_st_atime.tv_sec = iatt->ia_atime; + statx->glfs_st_atime.tv_nsec = iatt->ia_atime_nsec; + statx->glfs_st_mask |= GLFS_STAT_ATIME; + } + + if (IATT_MTIME_VALID(iatt->ia_flags)) { + statx->glfs_st_mtime.tv_sec = iatt->ia_mtime; + statx->glfs_st_mtime.tv_nsec = iatt->ia_mtime_nsec; + statx->glfs_st_mask |= GLFS_STAT_MTIME; + } + + if (IATT_CTIME_VALID(iatt->ia_flags)) { + statx->glfs_st_ctime.tv_sec = iatt->ia_ctime; + statx->glfs_st_ctime.tv_nsec = iatt->ia_ctime_nsec; + statx->glfs_st_mask |= GLFS_STAT_CTIME; + } + + if (IATT_BTIME_VALID(iatt->ia_flags)) { + statx->glfs_st_btime.tv_sec = iatt->ia_btime; + statx->glfs_st_btime.tv_nsec = iatt->ia_btime_nsec; + statx->glfs_st_mask |= GLFS_STAT_BTIME; + } + + if (IATT_INO_VALID(iatt->ia_flags)) { + statx->glfs_st_ino = iatt->ia_ino; + statx->glfs_st_mask |= GLFS_STAT_INO; + } + + if (IATT_SIZE_VALID(iatt->ia_flags)) { + statx->glfs_st_size = iatt->ia_size; + statx->glfs_st_mask |= GLFS_STAT_SIZE; + } + + if (IATT_BLOCKS_VALID(iatt->ia_flags)) { + statx->glfs_st_blocks = iatt->ia_blocks; + statx->glfs_st_mask |= GLFS_STAT_BLOCKS; + } + + /* unconditionally present, encode as is */ + statx->glfs_st_blksize = iatt->ia_blksize; + statx->glfs_st_rdev_major = ia_major(iatt->ia_rdev); + statx->glfs_st_rdev_minor = ia_minor(iatt->ia_rdev); + statx->glfs_st_dev_major = ia_major(fs->dev_id); + statx->glfs_st_dev_minor = ia_minor(fs->dev_id); + + /* At present we do not read any localFS attributes and pass them along, + * so setting this to 0. As we start supporting file attributes we can + * populate the same here as well */ + statx->glfs_st_attributes = 0; + statx->glfs_st_attributes_mask = 0; +} + +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_iatt_from_statx, 6.0) +void +priv_glfs_iatt_from_statx(struct iatt *iatt, const struct glfs_stat *statx) +{ + /* Most code in xlators are not checking validity flags before accessing + the items. Hence zero everything before setting valid items */ + memset(iatt, 0, sizeof(struct iatt)); + + if (GLFS_STAT_TYPE_VALID(statx->glfs_st_mask)) { + iatt->ia_type = ia_type_from_st_mode(statx->glfs_st_mode); + iatt->ia_flags |= IATT_TYPE; + } + + if (GLFS_STAT_MODE_VALID(statx->glfs_st_mask)) { + iatt->ia_prot = ia_prot_from_st_mode(statx->glfs_st_mode); + iatt->ia_flags |= IATT_MODE; + } + + if (GLFS_STAT_NLINK_VALID(statx->glfs_st_mask)) { + iatt->ia_nlink = statx->glfs_st_nlink; + iatt->ia_flags |= IATT_NLINK; + } + + if (GLFS_STAT_UID_VALID(statx->glfs_st_mask)) { + iatt->ia_uid = statx->glfs_st_uid; + iatt->ia_flags |= IATT_UID; + } + + if (GLFS_STAT_GID_VALID(statx->glfs_st_mask)) { + iatt->ia_gid = statx->glfs_st_gid; + iatt->ia_flags |= IATT_GID; + } + + if (GLFS_STAT_ATIME_VALID(statx->glfs_st_mask)) { + iatt->ia_atime = statx->glfs_st_atime.tv_sec; + iatt->ia_atime_nsec = statx->glfs_st_atime.tv_nsec; + iatt->ia_flags |= IATT_ATIME; + } + + if (GLFS_STAT_MTIME_VALID(statx->glfs_st_mask)) { + iatt->ia_mtime = statx->glfs_st_mtime.tv_sec; + iatt->ia_mtime_nsec = statx->glfs_st_mtime.tv_nsec; + iatt->ia_flags |= IATT_MTIME; + } + + if (GLFS_STAT_CTIME_VALID(statx->glfs_st_mask)) { + iatt->ia_ctime = statx->glfs_st_ctime.tv_sec; + iatt->ia_ctime_nsec = statx->glfs_st_ctime.tv_nsec; + iatt->ia_flags |= IATT_CTIME; + } + + if (GLFS_STAT_BTIME_VALID(statx->glfs_st_mask)) { + iatt->ia_btime = statx->glfs_st_btime.tv_sec; + iatt->ia_btime_nsec = statx->glfs_st_btime.tv_nsec; + iatt->ia_flags |= IATT_BTIME; + } + + if (GLFS_STAT_INO_VALID(statx->glfs_st_mask)) { + iatt->ia_ino = statx->glfs_st_ino; + iatt->ia_flags |= IATT_INO; + } + + if (GLFS_STAT_SIZE_VALID(statx->glfs_st_mask)) { + iatt->ia_size = statx->glfs_st_size; + iatt->ia_flags |= IATT_SIZE; + } + + if (GLFS_STAT_BLOCKS_VALID(statx->glfs_st_mask)) { + iatt->ia_blocks = statx->glfs_st_blocks; + iatt->ia_flags |= IATT_BLOCKS; + } + + /* unconditionally present, encode as is */ + iatt->ia_blksize = statx->glfs_st_blksize; + iatt->ia_rdev = makedev(statx->glfs_st_rdev_major, + statx->glfs_st_rdev_minor); + iatt->ia_dev = makedev(statx->glfs_st_dev_major, statx->glfs_st_dev_minor); + iatt->ia_attributes = statx->glfs_st_attributes; + iatt->ia_attributes_mask = statx->glfs_st_attributes_mask; +} + +void +glfsflags_from_gfapiflags(struct glfs_stat *stat, int *glvalid) +{ + *glvalid = 0; + if (stat->glfs_st_mask & GLFS_STAT_MODE) { + *glvalid |= GF_SET_ATTR_MODE; + } + + if (stat->glfs_st_mask & GLFS_STAT_SIZE) { + *glvalid |= GF_SET_ATTR_SIZE; + } + + if (stat->glfs_st_mask & GLFS_STAT_UID) { + *glvalid |= GF_SET_ATTR_UID; + } + + if (stat->glfs_st_mask & GLFS_STAT_GID) { + *glvalid |= GF_SET_ATTR_GID; + } + + if (stat->glfs_st_mask & GLFS_STAT_ATIME) { + *glvalid |= GF_SET_ATTR_ATIME; + } + + if (stat->glfs_st_mask & GLFS_STAT_MTIME) { + *glvalid |= GF_SET_ATTR_MTIME; + } +} + int glfs_loc_unlink(loc_t *loc) { @@ -214,6 +415,7 @@ glfs_loc_unlink(loc_t *loc) return 0; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0) struct glfs_fd * pub_glfs_open(struct glfs *fs, const char *path, int flags) { @@ -308,8 +510,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0) int pub_glfs_close(struct glfs_fd *glfd) { @@ -364,8 +565,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0) int pub_glfs_lstat(struct glfs *fs, const char *path, struct stat *stat) { @@ -406,8 +606,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0) int pub_glfs_stat(struct glfs *fs, const char *path, struct stat *stat) { @@ -448,8 +647,61 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0); +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_statx, 6.0) +int +priv_glfs_statx(struct glfs *fs, const char *path, const unsigned int mask, + struct glfs_stat *statxbuf) +{ + int ret = -1; + xlator_t *subvol = NULL; + loc_t loc = { + 0, + }; + struct iatt iatt = { + 0, + }; + int reval = 0; + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + + if (path == NULL) { + ret = -1; + errno = EINVAL; + goto out; + } + + if (mask & ~GLFS_STAT_ALL) { + ret = -1; + errno = EINVAL; + goto out; + } + + subvol = glfs_active_subvol(fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + +retry: + ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval); + ESTALE_RETRY(ret, errno, reval, &loc, retry); + + if (ret == 0 && statxbuf) + glfs_iatt_to_statx(fs, &iatt, statxbuf); +out: + loc_wipe(&loc); + + glfs_subvol_done(fs, subvol); + + __GLFS_EXIT_FS; + +invalid_fs: + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0) int pub_glfs_fstat(struct glfs_fd *glfd, struct stat *stat) { @@ -498,8 +750,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0) struct glfs_fd * pub_glfs_creat(struct glfs *fs, const char *path, int flags, mode_t mode) { @@ -646,8 +897,6 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0); - #ifdef HAVE_SEEK_HOLE static int glfs_seek(struct glfs_fd *glfd, off_t offset, int whence) @@ -701,6 +950,7 @@ out: } #endif +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0) off_t pub_glfs_lseek(struct glfs_fd *glfd, off_t offset, int whence) { @@ -756,11 +1006,9 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0); - -ssize_t -pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, - off_t offset, int flags) +static ssize_t +glfs_preadv_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, + off_t offset, int flags, struct glfs_stat *poststat) { xlator_t *subvol = NULL; ssize_t ret = -1; @@ -769,6 +1017,9 @@ pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, int cnt = 0; struct iobref *iobref = NULL; fd_t *fd = NULL; + struct iatt iatt = { + 0, + }; dict_t *fop_attr = NULL; DECLARE_OLD_THIS; @@ -796,10 +1047,13 @@ pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_readv(subvol, fd, size, offset, 0, &iov, &cnt, &iobref, + ret = syncop_readv(subvol, fd, size, offset, 0, &iov, &cnt, &iobref, &iatt, fop_attr, NULL); DECODE_SYNCOP_ERR(ret); + if (ret >= 0 && poststat) + glfs_iatt_to_statx(glfd->fs, &iatt, poststat); + if (ret <= 0) goto out; @@ -829,8 +1083,15 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0) +ssize_t +pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, + off_t offset, int flags) +{ + return glfs_preadv_common(glfd, iovec, iovcnt, offset, flags, NULL); +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0) ssize_t pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) { @@ -839,6 +1100,11 @@ pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = buf; iov.iov_len = count; @@ -847,11 +1113,10 @@ pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0); - +GFAPI_SYMVER_PUBLIC(glfs_pread34, glfs_pread, 3.4.0) ssize_t -pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, - int flags) +pub_glfs_pread34(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, + int flags) { struct iovec iov = { 0, @@ -866,21 +1131,41 @@ pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 3.4.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 6.0) +ssize_t +pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, + int flags, struct glfs_stat *poststat) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + iov.iov_base = buf; + iov.iov_len = count; + + ret = glfs_preadv_common(glfd, &iov, 1, offset, flags, poststat); + + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0) ssize_t pub_glfs_readv(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = pub_glfs_preadv(glfd, iov, count, glfd->offset, flags); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0); - struct glfs_io { struct glfs_fd *glfd; int op; @@ -888,19 +1173,26 @@ struct glfs_io { struct iovec *iov; int count; int flags; - glfs_io_cbk fn; + gf_boolean_t oldcb; + union { + glfs_io_cbk34 fn34; + glfs_io_cbk fn; + }; void *data; }; static int glfs_io_async_cbk(int op_ret, int op_errno, call_frame_t *frame, void *cookie, - struct iovec *iovec, int count) + struct iovec *iovec, int count, struct iatt *prebuf, + struct iatt *postbuf) { struct glfs_io *gio = NULL; xlator_t *subvol = NULL; struct glfs *fs = NULL; struct glfs_fd *glfd = NULL; int ret = -1; + struct glfs_stat prestat = {}, *prestatp = NULL; + struct glfs_stat poststat = {}, *poststatp = NULL; GF_VALIDATE_OR_GOTO("gfapi", frame, inval); GF_VALIDATE_OR_GOTO("gfapi", cookie, inval); @@ -931,8 +1223,21 @@ glfs_io_async_cbk(int op_ret, int op_errno, call_frame_t *frame, void *cookie, out: errno = op_errno; - gio->fn(gio->glfd, op_ret, gio->data); + if (gio->oldcb) { + gio->fn34(gio->glfd, op_ret, gio->data); + } else { + if (prebuf) { + prestatp = &prestat; + glfs_iatt_to_statx(fs, prebuf, prestatp); + } + if (postbuf) { + poststatp = &poststat; + glfs_iatt_to_statx(fs, postbuf, poststatp); + } + + gio->fn(gio->glfd, op_ret, prestatp, poststatp, gio->data); + } err: fd_unref(glfd->fd); /* Since the async operation is complete @@ -956,15 +1261,16 @@ glfs_preadv_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *iovec, int count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, iovec, count); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, iovec, count, NULL, + stbuf); return 0; } -int -pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec, - int count, off_t offset, int flags, glfs_io_cbk fn, - void *data) +static int +glfs_preadv_async_common(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, gf_boolean_t oldcb, + glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = 0; @@ -1021,6 +1327,7 @@ pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec, gio->count = count; gio->offset = offset; gio->flags = flags; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; @@ -1060,8 +1367,51 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_preadv_async34, glfs_preadv_async, 3.4.0) +int +pub_glfs_preadv_async34(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, glfs_io_cbk34 fn, + void *data) +{ + return glfs_preadv_async_common(glfd, iovec, count, offset, flags, _gf_true, + (void *)fn, data); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 6.0) +int +pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, glfs_io_cbk fn, + void *data) +{ + return glfs_preadv_async_common(glfd, iovec, count, offset, flags, + _gf_false, fn, data); +} +GFAPI_SYMVER_PUBLIC(glfs_read_async34, glfs_read_async, 3.4.0) +int +pub_glfs_read_async34(struct glfs_fd *glfd, void *buf, size_t count, int flags, + glfs_io_cbk34 fn, void *data) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + if (glfd == NULL) { + errno = EBADF; + return -1; + } + + iov.iov_base = buf; + iov.iov_len = count; + + ret = glfs_preadv_async_common(glfd, &iov, 1, glfd->offset, flags, _gf_true, + (void *)fn, data); + + return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 6.0) int pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) @@ -1071,16 +1421,40 @@ pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = buf; iov.iov_len = count; - ret = pub_glfs_preadv_async(glfd, &iov, 1, glfd->offset, flags, fn, data); + ret = glfs_preadv_async_common(glfd, &iov, 1, glfd->offset, flags, + _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_pread_async34, glfs_pread_async, 3.4.0) +int +pub_glfs_pread_async34(struct glfs_fd *glfd, void *buf, size_t count, + off_t offset, int flags, glfs_io_cbk34 fn, void *data) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + iov.iov_base = buf; + iov.iov_len = count; + + ret = glfs_preadv_async_common(glfd, &iov, 1, offset, flags, _gf_true, + (void *)fn, data); + + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 6.0) int pub_glfs_pread_async(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, int flags, glfs_io_cbk fn, void *data) @@ -1093,29 +1467,50 @@ pub_glfs_pread_async(struct glfs_fd *glfd, void *buf, size_t count, iov.iov_base = buf; iov.iov_len = count; - ret = pub_glfs_preadv_async(glfd, &iov, 1, offset, flags, fn, data); + ret = glfs_preadv_async_common(glfd, &iov, 1, offset, flags, _gf_false, fn, + data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_readv_async34, glfs_readv_async, 3.4.0) +int +pub_glfs_readv_async34(struct glfs_fd *glfd, const struct iovec *iov, int count, + int flags, glfs_io_cbk34 fn, void *data) +{ + ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + + ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags, + _gf_true, (void *)fn, data); + return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 6.0) int pub_glfs_readv_async(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) { ssize_t ret = 0; - ret = pub_glfs_preadv_async(glfd, iov, count, glfd->offset, flags, fn, - data); + if (glfd == NULL) { + errno = EBADF; + return -1; + } + + ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags, + _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 3.4.0); - -ssize_t -pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, - off_t offset, int flags) +static ssize_t +glfs_pwritev_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, + off_t offset, int flags, struct glfs_stat *prestat, + struct glfs_stat *poststat) { xlator_t *subvol = NULL; int ret = -1; @@ -1125,6 +1520,13 @@ pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, 0, }; fd_t *fd = NULL; + struct iatt preiatt = + { + 0, + }, + postiatt = { + 0, + }; dict_t *fop_attr = NULL; DECLARE_OLD_THIS; @@ -1155,10 +1557,17 @@ pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, fop_attr, - NULL); + ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, &preiatt, + &postiatt, fop_attr, NULL); DECODE_SYNCOP_ERR(ret); + if (ret >= 0) { + if (prestat) + glfs_iatt_to_statx(glfd->fs, &preiatt, prestat); + if (poststat) + glfs_iatt_to_statx(glfd->fs, &postiatt, poststat); + } + if (ret <= 0) goto out; @@ -1183,8 +1592,169 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_copy_file_range, 6.0) +ssize_t +pub_glfs_copy_file_range(struct glfs_fd *glfd_in, off64_t *off_in, + struct glfs_fd *glfd_out, off64_t *off_out, size_t len, + unsigned int flags, struct glfs_stat *statbuf, + struct glfs_stat *prestat, struct glfs_stat *poststat) +{ + xlator_t *subvol = NULL; + int ret = -1; + fd_t *fd_in = NULL; + fd_t *fd_out = NULL; + struct iatt preiatt = + { + 0, + }, + iattbuf = + { + 0, + }, + postiatt = { + 0, + }; + dict_t *fop_attr = NULL; + off64_t pos_in; + off64_t pos_out; + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FD(glfd_in, invalid_fs); + __GLFS_ENTRY_VALIDATE_FD(glfd_out, invalid_fs); + + GF_REF_GET(glfd_in); + GF_REF_GET(glfd_out); + + if (glfd_in->fs != glfd_out->fs) { + ret = -1; + errno = EXDEV; + goto out; + } + + subvol = glfs_active_subvol(glfd_in->fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + + fd_in = glfs_resolve_fd(glfd_in->fs, subvol, glfd_in); + if (!fd_in) { + ret = -1; + errno = EBADFD; + goto out; + } + fd_out = glfs_resolve_fd(glfd_out->fs, subvol, glfd_out); + if (!fd_out) { + ret = -1; + errno = EBADFD; + goto out; + } + + /* + * This is based on how the vfs layer in the kernel handles + * copy_file_range call. Upon receiving it follows the + * below method to consider the offset. + * if (off_in != NULL) + * use the value off_in to perform the op + * else if off_in == NULL + * use the current file offset position to perform the op + * + * For gfapi, glfd->offset is used. For a freshly opened + * fd, the offset is set to 0. + */ + if (off_in) + pos_in = *off_in; + else + pos_in = glfd_in->offset; + + if (off_out) + pos_out = *off_out; + else + pos_out = glfd_out->offset; + + ret = get_fop_attr_thrd_key(&fop_attr); + if (ret) + gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); + + ret = syncop_copy_file_range(subvol, fd_in, pos_in, fd_out, pos_out, len, + flags, &iattbuf, &preiatt, &postiatt, fop_attr, + NULL); + DECODE_SYNCOP_ERR(ret); + + if (ret >= 0) { + pos_in += ret; + pos_out += ret; + + if (off_in) + *off_in = pos_in; + if (off_out) + *off_out = pos_out; + + if (statbuf) + glfs_iatt_to_statx(glfd_in->fs, &iattbuf, statbuf); + if (prestat) + glfs_iatt_to_statx(glfd_in->fs, &preiatt, prestat); + if (poststat) + glfs_iatt_to_statx(glfd_in->fs, &postiatt, poststat); + } + + if (ret <= 0) + goto out; + + /* + * If *off_in is NULL, then there is no offset info that can + * obtained from the input argument. Hence follow below method. + * If *off_in is NULL, then + * glfd->offset = offset + ret; + * else + * do nothing. + * + * According to the man page of copy_file_range, if off_in is + * NULL, then the offset of the source file is advanced by + * the return value of the fop. The same applies to off_out as + * well. Otherwise, if *off_in is not NULL, then the offset + * is not advanced by the filesystem. The entity which sends + * the copy_file_range call is supposed to advance the offset + * value in its buffer (pointed to by *off_in or *off_out) + * by the return value of copy_file_range. + */ + if (!off_in) + glfd_in->offset += ret; + + if (!off_out) + glfd_out->offset += ret; + +out: + if (fd_in) + fd_unref(fd_in); + if (fd_out) + fd_unref(fd_out); + if (glfd_in) + GF_REF_PUT(glfd_in); + if (glfd_out) + GF_REF_PUT(glfd_out); + if (fop_attr) + dict_unref(fop_attr); + + glfs_subvol_done(glfd_in->fs, subvol); + + __GLFS_EXIT_FS; + +invalid_fs: + return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0) +ssize_t +pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, + off_t offset, int flags) +{ + return glfs_pwritev_common(glfd, iovec, iovcnt, offset, flags, NULL, NULL); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0) ssize_t pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) { @@ -1193,6 +1763,11 @@ pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; iov.iov_len = count; @@ -1201,24 +1776,27 @@ pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0) ssize_t pub_glfs_writev(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = pub_glfs_pwritev(glfd, iov, count, glfd->offset, flags); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0); - +GFAPI_SYMVER_PUBLIC(glfs_pwrite34, glfs_pwrite, 3.4.0) ssize_t -pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count, - off_t offset, int flags) +pub_glfs_pwrite34(struct glfs_fd *glfd, const void *buf, size_t count, + off_t offset, int flags) { struct iovec iov = { 0, @@ -1233,7 +1811,24 @@ pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 3.4.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 6.0) +ssize_t +pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count, + off_t offset, int flags, struct glfs_stat *prestat, + struct glfs_stat *poststat) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + iov.iov_base = (void *)buf; + iov.iov_len = count; + + ret = glfs_pwritev_common(glfd, &iov, 1, offset, flags, prestat, poststat); + + return ret; +} extern glfs_t * pub_glfs_from_glfd(glfs_fd_t *); @@ -1243,15 +1838,16 @@ glfs_pwritev_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf, + postbuf); return 0; } -int -pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec, - int count, off_t offset, int flags, glfs_io_cbk fn, - void *data) +static int +glfs_pwritev_async_common(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, + gf_boolean_t oldcb, glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = -1; @@ -1292,6 +1888,7 @@ pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec, gio->glfd = glfd; gio->offset = offset; gio->flags = flags; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; gio->count = 1; @@ -1351,8 +1948,51 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_pwritev_async34, glfs_pwritev_async, 3.4.0) +int +pub_glfs_pwritev_async34(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, glfs_io_cbk34 fn, + void *data) +{ + return glfs_pwritev_async_common(glfd, iovec, count, offset, flags, + _gf_true, (void *)fn, data); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 6.0) +int +pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec, + int count, off_t offset, int flags, glfs_io_cbk fn, + void *data) +{ + return glfs_pwritev_async_common(glfd, iovec, count, offset, flags, + _gf_false, fn, data); +} + +GFAPI_SYMVER_PUBLIC(glfs_write_async34, glfs_write_async, 3.4.0) +int +pub_glfs_write_async34(struct glfs_fd *glfd, const void *buf, size_t count, + int flags, glfs_io_cbk34 fn, void *data) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; + iov.iov_len = count; + + ret = glfs_pwritev_async_common(glfd, &iov, 1, glfd->offset, flags, + _gf_true, (void *)fn, data); + + return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 6.0) int pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) @@ -1362,16 +2002,40 @@ pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; iov.iov_len = count; - ret = pub_glfs_pwritev_async(glfd, &iov, 1, glfd->offset, flags, fn, data); + ret = glfs_pwritev_async_common(glfd, &iov, 1, glfd->offset, flags, + _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_pwrite_async34, glfs_pwrite_async, 3.4.0) +int +pub_glfs_pwrite_async34(struct glfs_fd *glfd, const void *buf, int count, + off_t offset, int flags, glfs_io_cbk34 fn, void *data) +{ + struct iovec iov = { + 0, + }; + ssize_t ret = 0; + + iov.iov_base = (void *)buf; + iov.iov_len = count; + + ret = glfs_pwritev_async_common(glfd, &iov, 1, offset, flags, _gf_true, + (void *)fn, data); + + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 6.0) int pub_glfs_pwrite_async(struct glfs_fd *glfd, const void *buf, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) @@ -1384,32 +2048,60 @@ pub_glfs_pwrite_async(struct glfs_fd *glfd, const void *buf, int count, iov.iov_base = (void *)buf; iov.iov_len = count; - ret = pub_glfs_pwritev_async(glfd, &iov, 1, offset, flags, fn, data); + ret = glfs_pwritev_async_common(glfd, &iov, 1, offset, flags, _gf_false, fn, + data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_writev_async34, glfs_writev_async, 3.4.0) +int +pub_glfs_writev_async34(struct glfs_fd *glfd, const struct iovec *iov, + int count, int flags, glfs_io_cbk34 fn, void *data) +{ + ssize_t ret = 0; + + if (glfd == NULL) { + errno = EBADF; + return -1; + } + + ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags, + _gf_true, (void *)fn, data); + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 6.0) int pub_glfs_writev_async(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) { ssize_t ret = 0; - ret = pub_glfs_pwritev_async(glfd, iov, count, glfd->offset, flags, fn, - data); + if (glfd == NULL) { + errno = EBADF; + return -1; + } + + ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags, + _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 3.4.0); - -int -pub_glfs_fsync(struct glfs_fd *glfd) +static int +glfs_fsync_common(struct glfs_fd *glfd, struct glfs_stat *prestat, + struct glfs_stat *poststat) { int ret = -1; xlator_t *subvol = NULL; fd_t *fd = NULL; + struct iatt preiatt = + { + 0, + }, + postiatt = { + 0, + }; dict_t *fop_attr = NULL; DECLARE_OLD_THIS; @@ -1435,9 +2127,15 @@ pub_glfs_fsync(struct glfs_fd *glfd) if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_fsync(subvol, fd, 0, fop_attr, NULL); + ret = syncop_fsync(subvol, fd, 0, &preiatt, &postiatt, fop_attr, NULL); DECODE_SYNCOP_ERR(ret); + if (ret >= 0) { + if (prestat) + glfs_iatt_to_statx(glfd->fs, &preiatt, prestat); + if (poststat) + glfs_iatt_to_statx(glfd->fs, &postiatt, poststat); + } out: if (fd) fd_unref(fd); @@ -1454,21 +2152,35 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_fsync34, glfs_fsync, 3.4.0) +int +pub_glfs_fsync34(struct glfs_fd *glfd) +{ + return glfs_fsync_common(glfd, NULL, NULL); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 6.0) +int +pub_glfs_fsync(struct glfs_fd *glfd, struct glfs_stat *prestat, + struct glfs_stat *poststat) +{ + return glfs_fsync_common(glfd, prestat, poststat); +} static int glfs_fsync_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf, + postbuf); return 0; } static int -glfs_fsync_async_common(struct glfs_fd *glfd, glfs_io_cbk fn, void *data, - int dataonly) +glfs_fsync_async_common(struct glfs_fd *glfd, gf_boolean_t oldcb, + glfs_io_cbk fn, void *data, int dataonly) { struct glfs_io *gio = NULL; int ret = 0; @@ -1512,6 +2224,7 @@ glfs_fsync_async_common(struct glfs_fd *glfd, glfs_io_cbk fn, void *data, gio->op = GF_FOP_FSYNC; gio->glfd = glfd; gio->flags = dataonly; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; @@ -1534,15 +2247,16 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_fsync_async34, glfs_fsync_async, 3.4.0) int -pub_glfs_fsync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) +pub_glfs_fsync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data) { int ret = -1; DECLARE_OLD_THIS; __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs); - ret = glfs_fsync_async_common(glfd, fn, data, 0); + ret = glfs_fsync_async_common(glfd, _gf_true, (void *)fn, data, 0); __GLFS_EXIT_FS; @@ -1550,14 +2264,37 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 6.0) int -pub_glfs_fdatasync(struct glfs_fd *glfd) +pub_glfs_fsync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) +{ + int ret = -1; + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs); + + ret = glfs_fsync_async_common(glfd, _gf_false, fn, data, 0); + + __GLFS_EXIT_FS; + +invalid_fs: + return ret; +} + +static int +glfs_fdatasync_common(struct glfs_fd *glfd, struct glfs_stat *prestat, + struct glfs_stat *poststat) { int ret = -1; xlator_t *subvol = NULL; fd_t *fd = NULL; + struct iatt preiatt = + { + 0, + }, + postiatt = { + 0, + }; dict_t *fop_attr = NULL; DECLARE_OLD_THIS; @@ -1583,9 +2320,15 @@ pub_glfs_fdatasync(struct glfs_fd *glfd) if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_fsync(subvol, fd, 1, fop_attr, NULL); + ret = syncop_fsync(subvol, fd, 1, &preiatt, &postiatt, fop_attr, NULL); DECODE_SYNCOP_ERR(ret); + if (ret >= 0) { + if (prestat) + glfs_iatt_to_statx(glfd->fs, &preiatt, prestat); + if (poststat) + glfs_iatt_to_statx(glfd->fs, &postiatt, poststat); + } out: if (fd) fd_unref(fd); @@ -1602,17 +2345,31 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_fdatasync34, glfs_fdatasync, 3.4.0) +int +pub_glfs_fdatasync34(struct glfs_fd *glfd) +{ + return glfs_fdatasync_common(glfd, NULL, NULL); +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 6.0) int -pub_glfs_fdatasync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) +pub_glfs_fdatasync(struct glfs_fd *glfd, struct glfs_stat *prestat, + struct glfs_stat *poststat) +{ + return glfs_fdatasync_common(glfd, prestat, poststat); +} + +GFAPI_SYMVER_PUBLIC(glfs_fdatasync_async34, glfs_fdatasync_async, 3.4.0) +int +pub_glfs_fdatasync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data) { int ret = -1; DECLARE_OLD_THIS; __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs); - ret = glfs_fsync_async_common(glfd, fn, data, 1); + ret = glfs_fsync_async_common(glfd, _gf_true, (void *)fn, data, 1); __GLFS_EXIT_FS; @@ -1620,14 +2377,37 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 6.0) int -pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset) +pub_glfs_fdatasync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) +{ + int ret = -1; + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs); + + ret = glfs_fsync_async_common(glfd, _gf_false, fn, data, 1); + + __GLFS_EXIT_FS; + +invalid_fs: + return ret; +} + +static int +glfs_ftruncate_common(struct glfs_fd *glfd, off_t offset, + struct glfs_stat *prestat, struct glfs_stat *poststat) { int ret = -1; xlator_t *subvol = NULL; fd_t *fd = NULL; + struct iatt preiatt = + { + 0, + }, + postiatt = { + 0, + }; dict_t *fop_attr = NULL; DECLARE_OLD_THIS; @@ -1653,9 +2433,16 @@ pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset) if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_ftruncate(subvol, fd, offset, fop_attr, NULL); + ret = syncop_ftruncate(subvol, fd, offset, &preiatt, &postiatt, fop_attr, + NULL); DECODE_SYNCOP_ERR(ret); + if (ret >= 0) { + if (prestat) + glfs_iatt_to_statx(glfd->fs, &preiatt, prestat); + if (poststat) + glfs_iatt_to_statx(glfd->fs, &postiatt, poststat); + } out: if (fd) fd_unref(fd); @@ -1672,8 +2459,22 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_ftruncate34, glfs_ftruncate, 3.4.0) +int +pub_glfs_ftruncate34(struct glfs_fd *glfd, off_t offset) +{ + return glfs_ftruncate_common(glfd, offset, NULL, NULL); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 6.0) +int +pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset, + struct glfs_stat *prestat, struct glfs_stat *poststat) +{ + return glfs_ftruncate_common(glfd, offset, prestat, poststat); +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_truncate, 3.7.15) int pub_glfs_truncate(struct glfs *fs, const char *path, off_t length) { @@ -1719,21 +2520,20 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_truncate, 3.7.15); - static int glfs_ftruncate_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf, + postbuf); return 0; } -int -pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn, - void *data) +static int +glfs_ftruncate_async_common(struct glfs_fd *glfd, off_t offset, + gf_boolean_t oldcb, glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = -1; @@ -1777,6 +2577,7 @@ pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn, gio->op = GF_FOP_FTRUNCATE; gio->glfd = glfd; gio->offset = offset; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; @@ -1811,8 +2612,24 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 3.4.0); +GFAPI_SYMVER_PUBLIC(glfs_ftruncate_async34, glfs_ftruncate_async, 3.4.0) +int +pub_glfs_ftruncate_async34(struct glfs_fd *glfd, off_t offset, glfs_io_cbk34 fn, + void *data) +{ + return glfs_ftruncate_async_common(glfd, offset, _gf_true, (void *)fn, + data); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 6.0) +int +pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn, + void *data) +{ + return glfs_ftruncate_async_common(glfd, offset, _gf_false, fn, data); +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0) int pub_glfs_access(struct glfs *fs, const char *path, int mode) { @@ -1858,8 +2675,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0) int pub_glfs_symlink(struct glfs *fs, const char *data, const char *path) { @@ -1949,8 +2765,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0) int pub_glfs_readlink(struct glfs *fs, const char *path, char *buf, size_t bufsiz) { @@ -2007,8 +2822,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0) int pub_glfs_mknod(struct glfs *fs, const char *path, mode_t mode, dev_t dev) { @@ -2098,8 +2912,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0) int pub_glfs_mkdir(struct glfs *fs, const char *path, mode_t mode) { @@ -2189,8 +3002,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0) int pub_glfs_unlink(struct glfs *fs, const char *path) { @@ -2246,8 +3058,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0) int pub_glfs_rmdir(struct glfs *fs, const char *path) { @@ -2302,8 +3113,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0) int pub_glfs_rename(struct glfs *fs, const char *oldpath, const char *newpath) { @@ -2392,8 +3202,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0) int pub_glfs_link(struct glfs *fs, const char *oldpath, const char *newpath) { @@ -2479,8 +3288,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0) struct glfs_fd * pub_glfs_opendir(struct glfs *fs, const char *path) { @@ -2561,8 +3369,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0) int pub_glfs_closedir(struct glfs_fd *glfd) { @@ -2583,22 +3390,30 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0) long pub_glfs_telldir(struct glfs_fd *fd) { + if (fd == NULL) { + errno = EBADF; + return -1; + } + return fd->offset; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0) void pub_glfs_seekdir(struct glfs_fd *fd, long offset) { gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; + if (fd == NULL) { + errno = EBADF; + return; + } + if (fd->offset == offset) return; @@ -2621,22 +3436,21 @@ pub_glfs_seekdir(struct glfs_fd *fd, long offset) */ } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0); - static int glfs_discard_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preop_stbuf, struct iatt *postop_stbuf, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, preop_stbuf, + postop_stbuf); return 0; } -int -pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len, - glfs_io_cbk fn, void *data) +static int +glfs_discard_async_common(struct glfs_fd *glfd, off_t offset, size_t len, + gf_boolean_t oldcb, glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = -1; @@ -2681,6 +3495,7 @@ pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len, gio->glfd = glfd; gio->offset = offset; gio->count = len; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; @@ -2711,7 +3526,22 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 3.5.0); +GFAPI_SYMVER_PUBLIC(glfs_discard_async35, glfs_discard_async, 3.5.0) +int +pub_glfs_discard_async35(struct glfs_fd *glfd, off_t offset, size_t len, + glfs_io_cbk34 fn, void *data) +{ + return glfs_discard_async_common(glfd, offset, len, _gf_true, (void *)fn, + data); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 6.0) +int +pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len, + glfs_io_cbk fn, void *data) +{ + return glfs_discard_async_common(glfd, offset, len, _gf_false, fn, data); +} static int glfs_zerofill_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, @@ -2719,14 +3549,15 @@ glfs_zerofill_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *preop_stbuf, struct iatt *postop_stbuf, dict_t *xdata) { - glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0); + glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, preop_stbuf, + postop_stbuf); return 0; } -int -pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len, - glfs_io_cbk fn, void *data) +static int +glfs_zerofill_async_common(struct glfs_fd *glfd, off_t offset, off_t len, + gf_boolean_t oldcb, glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = -1; @@ -2771,6 +3602,7 @@ pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len, gio->glfd = glfd; gio->offset = offset; gio->count = len; + gio->oldcb = oldcb; gio->fn = fn; gio->data = data; @@ -2803,7 +3635,22 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 3.5.0); +GFAPI_SYMVER_PUBLIC(glfs_zerofill_async35, glfs_zerofill_async, 3.5.0) +int +pub_glfs_zerofill_async35(struct glfs_fd *glfd, off_t offset, off_t len, + glfs_io_cbk34 fn, void *data) +{ + return glfs_zerofill_async_common(glfd, offset, len, _gf_true, (void *)fn, + data); +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 6.0) +int +pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len, + glfs_io_cbk fn, void *data) +{ + return glfs_zerofill_async_common(glfd, offset, len, _gf_false, fn, data); +} void gf_dirent_to_dirent(gf_dirent_t *gf_dirent, struct dirent *dirent) @@ -2822,7 +3669,7 @@ gf_dirent_to_dirent(gf_dirent_t *gf_dirent, struct dirent *dirent) dirent->d_namlen = strlen(gf_dirent->d_name); #endif - snprintf(dirent->d_name, NAME_MAX, "%s", gf_dirent->d_name); + snprintf(dirent->d_name, NAME_MAX + 1, "%s", gf_dirent->d_name); } int @@ -2964,6 +3811,7 @@ unlock: return buf; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0) int pub_glfs_readdirplus_r(struct glfs_fd *glfd, struct stat *stat, struct dirent *ext, struct dirent **res) @@ -3019,8 +3867,7 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0) int pub_glfs_readdir_r(struct glfs_fd *glfd, struct dirent *buf, struct dirent **res) @@ -3028,8 +3875,7 @@ pub_glfs_readdir_r(struct glfs_fd *glfd, struct dirent *buf, return pub_glfs_readdirplus_r(glfd, 0, buf, res); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0) struct dirent * pub_glfs_readdirplus(struct glfs_fd *glfd, struct stat *stat) { @@ -3043,16 +3889,14 @@ pub_glfs_readdirplus(struct glfs_fd *glfd, struct stat *stat) return res; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0) struct dirent * pub_glfs_readdir(struct glfs_fd *glfd) { return pub_glfs_readdirplus(glfd, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0) int pub_glfs_statvfs(struct glfs *fs, const char *path, struct statvfs *buf) { @@ -3098,13 +3942,13 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setattr, 6.0) int -glfs_setattr(struct glfs *fs, const char *path, struct iatt *iatt, int valid, - int follow) +pub_glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat, + int follow) { int ret = -1; + int glvalid; xlator_t *subvol = NULL; loc_t loc = { 0, @@ -3112,11 +3956,16 @@ glfs_setattr(struct glfs *fs, const char *path, struct iatt *iatt, int valid, struct iatt riatt = { 0, }; + struct iatt iatt = { + 0, + }; int reval = 0; DECLARE_OLD_THIS; __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + GF_VALIDATE_OR_GOTO("glfs_setattr", stat, out); + subvol = glfs_active_subvol(fs); if (!subvol) { ret = -1; @@ -3134,8 +3983,11 @@ retry: if (ret) goto out; + glfs_iatt_from_statx(&iatt, stat); + glfsflags_from_gfapiflags(stat, &glvalid); + /* TODO : Add leaseid */ - ret = syncop_setattr(subvol, &loc, iatt, valid, 0, 0, NULL, NULL); + ret = syncop_setattr(subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL); DECODE_SYNCOP_ERR(ret); ESTALE_RETRY(ret, errno, reval, &loc, retry); @@ -3150,10 +4002,15 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetattr, 6.0) int -glfs_fsetattr(struct glfs_fd *glfd, struct iatt *iatt, int valid) +pub_glfs_fsetattr(struct glfs_fd *glfd, struct glfs_stat *stat) { int ret = -1; + int glvalid; + struct iatt iatt = { + 0, + }; xlator_t *subvol = NULL; fd_t *fd = NULL; @@ -3162,6 +4019,8 @@ glfs_fsetattr(struct glfs_fd *glfd, struct iatt *iatt, int valid) GF_REF_GET(glfd); + GF_VALIDATE_OR_GOTO("glfs_fsetattr", stat, out); + subvol = glfs_active_subvol(glfd->fs); if (!subvol) { ret = -1; @@ -3176,8 +4035,11 @@ glfs_fsetattr(struct glfs_fd *glfd, struct iatt *iatt, int valid) goto out; } + glfs_iatt_from_statx(&iatt, stat); + glfsflags_from_gfapiflags(stat, &glvalid); + /* TODO : Add leaseid */ - ret = syncop_fsetattr(subvol, fd, iatt, valid, 0, 0, NULL, NULL); + ret = syncop_fsetattr(subvol, fd, &iatt, glvalid, 0, 0, NULL, NULL); DECODE_SYNCOP_ERR(ret); out: if (fd) @@ -3193,196 +4055,174 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0) int pub_glfs_chmod(struct glfs *fs, const char *path, mode_t mode) { int ret = -1; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; - int valid = 0; - iatt.ia_prot = ia_prot_from_st_mode(mode); - valid = GF_SET_ATTR_MODE; + stat.glfs_st_mode = mode; + stat.glfs_st_mask = GLFS_STAT_MODE; - ret = glfs_setattr(fs, path, &iatt, valid, 1); + ret = glfs_setattr(fs, path, &stat, 1); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0) int pub_glfs_fchmod(struct glfs_fd *glfd, mode_t mode) { int ret = -1; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; - int valid = 0; - iatt.ia_prot = ia_prot_from_st_mode(mode); - valid = GF_SET_ATTR_MODE; + stat.glfs_st_mode = mode; + stat.glfs_st_mask = GLFS_STAT_MODE; - ret = glfs_fsetattr(glfd, &iatt, valid); + ret = glfs_fsetattr(glfd, &stat); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0) int pub_glfs_chown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) { int ret = 0; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; if (uid != (uid_t)-1) { - iatt.ia_uid = uid; - valid = GF_SET_ATTR_UID; + stat.glfs_st_uid = uid; + stat.glfs_st_mask = GLFS_STAT_UID; } if (gid != (uid_t)-1) { - iatt.ia_gid = gid; - valid = valid | GF_SET_ATTR_GID; + stat.glfs_st_gid = gid; + stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID; } - if (valid) - ret = glfs_setattr(fs, path, &iatt, valid, 1); + if (stat.glfs_st_mask) + ret = glfs_setattr(fs, path, &stat, 1); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0) int pub_glfs_lchown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) { int ret = 0; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; if (uid != (uid_t)-1) { - iatt.ia_uid = uid; - valid = GF_SET_ATTR_UID; + stat.glfs_st_uid = uid; + stat.glfs_st_mask = GLFS_STAT_UID; } if (gid != (uid_t)-1) { - iatt.ia_gid = gid; - valid = valid | GF_SET_ATTR_GID; + stat.glfs_st_gid = gid; + stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID; } - if (valid) - ret = glfs_setattr(fs, path, &iatt, valid, 0); + if (stat.glfs_st_mask) + ret = glfs_setattr(fs, path, &stat, 0); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0) int pub_glfs_fchown(struct glfs_fd *glfd, uid_t uid, gid_t gid) { int ret = 0; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; if (uid != (uid_t)-1) { - iatt.ia_uid = uid; - valid = GF_SET_ATTR_UID; + stat.glfs_st_uid = uid; + stat.glfs_st_mask = GLFS_STAT_UID; } if (gid != (uid_t)-1) { - iatt.ia_gid = gid; - valid = valid | GF_SET_ATTR_GID; + stat.glfs_st_gid = gid; + stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID; } - if (valid) - ret = glfs_fsetattr(glfd, &iatt, valid); + if (stat.glfs_st_mask) + ret = glfs_fsetattr(glfd, &stat); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0) int pub_glfs_utimens(struct glfs *fs, const char *path, const struct timespec times[2]) { int ret = -1; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; - iatt.ia_atime = times[0].tv_sec; - iatt.ia_atime_nsec = times[0].tv_nsec; - iatt.ia_mtime = times[1].tv_sec; - iatt.ia_mtime_nsec = times[1].tv_nsec; + stat.glfs_st_atime = times[0]; + stat.glfs_st_mtime = times[1]; - valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; + stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME; - ret = glfs_setattr(fs, path, &iatt, valid, 1); + ret = glfs_setattr(fs, path, &stat, 1); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0) int pub_glfs_lutimens(struct glfs *fs, const char *path, const struct timespec times[2]) { int ret = -1; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; - iatt.ia_atime = times[0].tv_sec; - iatt.ia_atime_nsec = times[0].tv_nsec; - iatt.ia_mtime = times[1].tv_sec; - iatt.ia_mtime_nsec = times[1].tv_nsec; + stat.glfs_st_atime = times[0]; + stat.glfs_st_mtime = times[1]; - valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; + stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME; - ret = glfs_setattr(fs, path, &iatt, valid, 0); + ret = glfs_setattr(fs, path, &stat, 0); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0) int pub_glfs_futimens(struct glfs_fd *glfd, const struct timespec times[2]) { int ret = -1; - int valid = 0; - struct iatt iatt = { + struct glfs_stat stat = { 0, }; - iatt.ia_atime = times[0].tv_sec; - iatt.ia_atime_nsec = times[0].tv_nsec; - iatt.ia_mtime = times[1].tv_sec; - iatt.ia_mtime_nsec = times[1].tv_nsec; + stat.glfs_st_atime = times[0]; + stat.glfs_st_mtime = times[1]; - valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; + stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME; - ret = glfs_fsetattr(glfd, &iatt, valid); + ret = glfs_fsetattr(glfd, &stat); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0); - int glfs_getxattr_process(void *value, size_t size, dict_t *xattr, const char *name) { @@ -3482,6 +4322,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0) ssize_t pub_glfs_getxattr(struct glfs *fs, const char *path, const char *name, void *value, size_t size) @@ -3489,8 +4330,7 @@ pub_glfs_getxattr(struct glfs *fs, const char *path, const char *name, return glfs_getxattr_common(fs, path, name, value, size, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0) ssize_t pub_glfs_lgetxattr(struct glfs *fs, const char *path, const char *name, void *value, size_t size) @@ -3498,8 +4338,7 @@ pub_glfs_lgetxattr(struct glfs *fs, const char *path, const char *name, return glfs_getxattr_common(fs, path, name, value, size, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0) ssize_t pub_glfs_fgetxattr(struct glfs_fd *glfd, const char *name, void *value, size_t size) @@ -3562,8 +4401,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0); - int glfs_listxattr_process(void *value, size_t size, dict_t *xattr) { @@ -3647,22 +4484,21 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0) ssize_t pub_glfs_listxattr(struct glfs *fs, const char *path, void *value, size_t size) { return glfs_listxattr_common(fs, path, value, size, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0) ssize_t pub_glfs_llistxattr(struct glfs *fs, const char *path, void *value, size_t size) { return glfs_listxattr_common(fs, path, value, size, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0) ssize_t pub_glfs_flistxattr(struct glfs_fd *glfd, void *value, size_t size) { @@ -3712,8 +4548,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0); - int glfs_setxattr_common(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags, int follow) @@ -3793,6 +4627,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0) int pub_glfs_setxattr(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags) @@ -3800,8 +4635,7 @@ pub_glfs_setxattr(struct glfs *fs, const char *path, const char *name, return glfs_setxattr_common(fs, path, name, value, size, flags, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0) int pub_glfs_lsetxattr(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags) @@ -3809,8 +4643,7 @@ pub_glfs_lsetxattr(struct glfs *fs, const char *path, const char *name, return glfs_setxattr_common(fs, path, name, value, size, flags, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0) int pub_glfs_fsetxattr(struct glfs_fd *glfd, const char *name, const void *value, size_t size, int flags) @@ -3885,8 +4718,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0); - int glfs_removexattr_common(struct glfs *fs, const char *path, const char *name, int follow) @@ -3937,22 +4768,21 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0) int pub_glfs_removexattr(struct glfs *fs, const char *path, const char *name) { return glfs_removexattr_common(fs, path, name, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0) int pub_glfs_lremovexattr(struct glfs *fs, const char *path, const char *name) { return glfs_removexattr_common(fs, path, name, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0) int pub_glfs_fremovexattr(struct glfs_fd *glfd, const char *name) { @@ -3995,8 +4825,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0) int pub_glfs_fallocate(struct glfs_fd *glfd, int keep_size, off_t offset, size_t len) @@ -4047,8 +4876,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0) int pub_glfs_discard(struct glfs_fd *glfd, off_t offset, size_t len) { @@ -4098,8 +4926,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0) int pub_glfs_zerofill(struct glfs_fd *glfd, off_t offset, off_t len) { @@ -4147,8 +4974,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0) int pub_glfs_chdir(struct glfs *fs, const char *path) { @@ -4198,8 +5024,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0) int pub_glfs_fchdir(struct glfs_fd *glfd) { @@ -4251,8 +5076,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0); - static gf_boolean_t warn_realpath = _gf_true; /* log once */ static char * @@ -4313,7 +5136,7 @@ retry: goto out; if (loc.path) { - snprintf(retpath, PATH_MAX, "%s", loc.path); + snprintf(retpath, PATH_MAX + 1, "%s", loc.path); } out: @@ -4335,22 +5158,21 @@ invalid_fs: return retpath; } +GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0) char * pub_glfs_realpath34(struct glfs *fs, const char *path, char *resolved_path) { return glfs_realpath_common(fs, path, resolved_path, _gf_true); } -GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17) char * pub_glfs_realpath(struct glfs *fs, const char *path, char *resolved_path) { return glfs_realpath_common(fs, path, resolved_path, _gf_false); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0) char * pub_glfs_getcwd(struct glfs *fs, char *buf, size_t n) { @@ -4399,8 +5221,6 @@ invalid_fs: return buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0); - static void gf_flock_to_flock(struct gf_flock *gf_flock, struct flock *flock) { @@ -4486,11 +5306,9 @@ glfs_lock_common(struct glfs_fd *glfd, int cmd, struct flock *flock, if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW)) { ret = fd_lk_insert_and_merge(fd, cmd, &saved_flock); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, - API_MSG_LOCK_INSERT_MERGE_FAILED, - "Lock insertion and splitting/merging failed " - "on gfid %s", - uuid_utoa(fd->inode->gfid)); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, + API_MSG_LOCK_INSERT_MERGE_FAILED, "gfid=%s", + uuid_utoa(fd->inode->gfid), NULL); ret = 0; } } @@ -4509,6 +5327,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0) int pub_glfs_file_lock(struct glfs_fd *glfd, int cmd, struct flock *flock, glfs_lock_mode_t lk_mode) @@ -4529,9 +5348,8 @@ pub_glfs_file_lock(struct glfs_fd *glfd, int cmd, struct flock *flock, * GLFS_LK_MANDATORY */ ret = dict_set_uint32(xdata_in, GF_LOCK_MODE, GF_LK_MANDATORY); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, - API_MSG_SETTING_LOCK_TYPE_FAILED, - "Setting lock type failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, + API_MSG_SETTING_LOCK_TYPE_FAILED, NULL); ret = -1; errno = ENOMEM; goto out; @@ -4546,16 +5364,14 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0) int pub_glfs_posix_lock(struct glfs_fd *glfd, int cmd, struct flock *flock) { return glfs_lock_common(glfd, cmd, flock, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7) int pub_glfs_fd_set_lkowner(struct glfs_fd *glfd, void *data, int len) { @@ -4572,8 +5388,8 @@ pub_glfs_fd_set_lkowner(struct glfs_fd *glfd, void *data, int len) if ((len <= 0) || (len > GFAPI_MAX_LOCK_OWNER_LEN)) { errno = EINVAL; - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, - "Invalid lk_owner len (%d)", len); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG, + "lk_owner len=%d", len, NULL); goto out; } @@ -4591,8 +5407,8 @@ out: invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0) struct glfs_fd * pub_glfs_dup(struct glfs_fd *glfd) { @@ -4643,8 +5459,6 @@ invalid_fs: return dupfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0); - static void glfs_enqueue_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) { @@ -4657,8 +5471,8 @@ glfs_enqueue_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) u_list = GF_CALLOC(1, sizeof(*u_list), glfs_mt_upcall_entry_t); if (!u_list) { - gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, - "Upcall entry allocation failed."); + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry", + NULL); goto out; } @@ -4680,8 +5494,7 @@ glfs_enqueue_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) } if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, - "Upcall entry validation failed."); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, NULL); goto out; } @@ -4723,9 +5536,7 @@ glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data) inode_t *inode = NULL; struct glfs_fd *glfd = NULL; struct glfs_fd *tmp = NULL; - struct list_head glfd_list = { - 0, - }; + struct list_head glfd_list; fd_t *fd = NULL; uint64_t value = 0; struct glfs_lease lease = { @@ -4753,9 +5564,9 @@ glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data) inode = inode_find(subvol->itable, up_data->gfid); if (!inode) { ret = -1; - gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INODE_FIND_FAILED, - "Unable to find inode entry for gfid:%s graph id:%d", - uuid_utoa(up_data->gfid), subvol->graph->id); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INODE_FIND_FAILED, + "gfid=%s", uuid_utoa(up_data->gfid), "graph_id=%d", + subvol->graph->id, NULL); goto out; } @@ -4764,7 +5575,7 @@ glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data) list_for_each_entry(fd, &inode->fd_list, inode_list) { ret = fd_ctx_get(fd, subvol, &value); - glfd = (struct glfs_fd *)value; + glfd = (struct glfs_fd *)(uintptr_t)value; if (glfd) { gf_msg_trace(THIS->name, 0, "glfd (%p) has held lease", glfd); GF_REF_GET(glfd); @@ -4774,22 +5585,24 @@ glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data) } UNLOCK(&inode->lock); - list_for_each_entry_safe(glfd, tmp, &glfd_list, list) - { - LOCK(&glfd->lock); + if (!list_empty(&glfd_list)) { + list_for_each_entry_safe(glfd, tmp, &glfd_list, list) { - if (glfd->state != GLFD_CLOSE) { - gf_msg_trace(THIS->name, 0, - "glfd (%p) has held lease, " - "calling recall cbk", - glfd); - glfd->cbk(lease, glfd->cookie); + LOCK(&glfd->lock); + { + if (glfd->state != GLFD_CLOSE) { + gf_msg_trace(THIS->name, 0, + "glfd (%p) has held lease, " + "calling recall cbk", + glfd); + glfd->cbk(lease, glfd->cookie); + } } - } - UNLOCK(&glfd->lock); + UNLOCK(&glfd->lock); - list_del_init(&glfd->list); - GF_REF_PUT(glfd); + list_del_init(&glfd->list); + GF_REF_PUT(glfd); + } } out: @@ -4831,8 +5644,8 @@ glfs_recall_lease_upcall(struct glfs *fs, struct glfs_upcall *up_arg, * the handle and hence will no more be interested in * the upcall for this particular gfid. */ - gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED, - "handle creation of %s failed", uuid_utoa(up_data->gfid)); + gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED, + "gfid=%s", uuid_utoa(up_data->gfid), NULL); errno = ESTALE; goto out; } @@ -4863,25 +5676,66 @@ out: return ret; } -static void -glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) +static int +upcall_syncop_args_free(struct upcall_syncop_args *args) { - int ret = -1; + dict_t *dict = NULL; + struct gf_upcall *upcall_data = NULL; + + if (args) { + upcall_data = &args->upcall_data; + switch (upcall_data->event_type) { + case GF_UPCALL_CACHE_INVALIDATION: + dict = ((struct gf_upcall_cache_invalidation *)(upcall_data + ->data)) + ->dict; + break; + case GF_UPCALL_RECALL_LEASE: + dict = ((struct gf_upcall_recall_lease *)(upcall_data->data)) + ->dict; + break; + } + if (dict) + dict_unref(dict); + + GF_FREE(upcall_data->client_uid); + GF_FREE(upcall_data->data); + } + GF_FREE(args); + return 0; +} + +static int +glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque) +{ + struct upcall_syncop_args *args = opaque; + + (void)upcall_syncop_args_free(args); + + return 0; +} + +static int +glfs_cbk_upcall_syncop(void *opaque) +{ + struct upcall_syncop_args *args = opaque; + struct gf_upcall *upcall_data = NULL; struct glfs_upcall *up_arg = NULL; + struct glfs *fs; + int ret = -1; - if (!fs || !upcall_data) - goto out; + fs = args->fs; + upcall_data = &args->upcall_data; - if (!(fs->upcall_events & upcall_data->event_type)) { - /* ignore events which application hasn't registered*/ + if (!upcall_data) { goto out; } up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall, glfs_mt_upcall_entry_t); if (!up_arg) { - gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, - "Upcall entry allocation failed."); + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry", + NULL); goto out; } @@ -4896,32 +5750,182 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) errno = EINVAL; } - if (!ret && (up_arg->reason != GLFS_UPCALL_EVENT_NULL)) { - /* It could so happen that the file which got - * upcall notification may have got deleted by - * the same client. In such cases up_arg->reason - * is set to GLFS_UPCALL_EVENT_NULL. No need to - * send upcall then */ - (fs->up_cbk)(up_arg, fs->up_data); - } else if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) { - gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_INVALID_ENTRY, - "Upcall_EVENT_NULL received. Skipping it."); + /* It could so happen that the file which got + * upcall notification may have got deleted by + * the same client. In such cases up_arg->reason + * is set to GLFS_UPCALL_EVENT_NULL. No need to + * send upcall then + */ + if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) { + gf_smsg(THIS->name, GF_LOG_DEBUG, errno, + API_MSG_UPCALL_EVENT_NULL_RECEIVED, NULL); + ret = 0; + GLFS_FREE(up_arg); goto out; - } else { - gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, - "Upcall entry validation failed."); + } else if (ret) { + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, NULL); + GLFS_FREE(up_arg); goto out; } + if (fs->up_cbk && up_arg) + (fs->up_cbk)(up_arg, fs->up_data); + /* application takes care of calling glfs_free on up_arg post * their processing */ - ret = 0; out: - if (ret && up_arg) { - GLFS_FREE(up_arg); + return ret; +} + +static struct gf_upcall_cache_invalidation * +gf_copy_cache_invalidation(struct gf_upcall_cache_invalidation *src) +{ + struct gf_upcall_cache_invalidation *dst = NULL; + + if (!src) + goto out; + + dst = GF_CALLOC(1, sizeof(struct gf_upcall_cache_invalidation), + glfs_mt_upcall_entry_t); + + if (!dst) { + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry", + NULL); + goto out; + } + + dst->flags = src->flags; + dst->expire_time_attr = src->expire_time_attr; + dst->stat = src->stat; + dst->p_stat = src->p_stat; + dst->oldp_stat = src->oldp_stat; + + if (src->dict) + dst->dict = dict_copy_with_ref(src->dict, NULL); + + return dst; +out: + return NULL; +} + +static struct gf_upcall_recall_lease * +gf_copy_recall_lease(struct gf_upcall_recall_lease *src) +{ + struct gf_upcall_recall_lease *dst = NULL; + + if (!src) + goto out; + + dst = GF_CALLOC(1, sizeof(struct gf_upcall_recall_lease), + glfs_mt_upcall_entry_t); + + if (!dst) { + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry", + NULL); + goto out; + } + + dst->lease_type = src->lease_type; + memcpy(dst->tid, src->tid, 16); + + if (src->dict) + dst->dict = dict_copy_with_ref(src->dict, NULL); + + return dst; +out: + return NULL; +} + +static struct upcall_syncop_args * +upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) +{ + struct upcall_syncop_args *args = NULL; + int ret = -1; + struct gf_upcall *t_data = NULL; + + if (!fs || !upcall_data) + goto out; + + args = GF_CALLOC(1, sizeof(struct upcall_syncop_args), + glfs_mt_upcall_entry_t); + if (!args) { + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, + "syncop args", NULL); + goto out; + } + + /* Note: we are not taking any ref on fs here. + * Ideally applications have to unregister for upcall events + * or stop polling for upcall events before performing + * glfs_fini. And as for outstanding synctasks created, we wait + * for all syncenv threads to finish tasks before cleaning up the + * fs->ctx. Hence it seems safe to process these callback + * notification without taking any lock/ref. + */ + args->fs = fs; + t_data = &(args->upcall_data); + t_data->client_uid = gf_strdup(upcall_data->client_uid); + + gf_uuid_copy(t_data->gfid, upcall_data->gfid); + t_data->event_type = upcall_data->event_type; + + switch (t_data->event_type) { + case GF_UPCALL_CACHE_INVALIDATION: + t_data->data = gf_copy_cache_invalidation( + (struct gf_upcall_cache_invalidation *)upcall_data->data); + break; + case GF_UPCALL_RECALL_LEASE: + t_data->data = gf_copy_recall_lease( + (struct gf_upcall_recall_lease *)upcall_data->data); + break; + } + + if (!t_data->data) + goto out; + + return args; +out: + if (ret) { + if (args) { + GF_FREE(args->upcall_data.client_uid); + GF_FREE(args); + } + } + + return NULL; +} + +static void +glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) +{ + struct upcall_syncop_args *args = NULL; + int ret = -1; + + if (!fs || !upcall_data) + goto out; + + if (!(fs->upcall_events & upcall_data->event_type)) { + /* ignore events which application hasn't registered*/ + goto out; } + args = upcall_syncop_args_init(fs, upcall_data); + + if (!args) + goto out; + + ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop, + glfs_upcall_syncop_cbk, NULL, args); + /* should we retry incase of failure? */ + if (ret) { + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED, + "event_type=%d", upcall_data->event_type, "gfid=%s", + (char *)(upcall_data->gfid), NULL); + upcall_syncop_args_free(args); + } + +out: return; } @@ -4939,6 +5943,7 @@ out: * Otherwise all the upcall events are queued up in a list * to be read/polled by the applications. */ +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0) void priv_glfs_process_upcall_event(struct glfs *fs, void *data) { @@ -5006,7 +6011,6 @@ out: err: return; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0); ssize_t glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object, @@ -5045,8 +6049,7 @@ glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object, fd = fd_anonymous(inode); if (!fd) { ret = -1; - gf_msg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, - "Allocating anonymous fd failed"); + gf_smsg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, NULL); errno = ENOMEM; goto out; } @@ -5083,7 +6086,8 @@ glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object, iov.iov_len = size; /* TODO : set leaseid */ - ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, NULL, NULL); + ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, NULL, NULL, + NULL, NULL); DECODE_SYNCOP_ERR(ret); iobuf_unref(iobuf); @@ -5143,8 +6147,7 @@ glfs_anonymous_preadv(struct glfs *fs, struct glfs_object *object, fd = fd_anonymous(inode); if (!fd) { ret = -1; - gf_msg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, - "Allocating anonymous fd failed"); + gf_smsg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, NULL); errno = ENOMEM; goto out; } @@ -5153,7 +6156,7 @@ glfs_anonymous_preadv(struct glfs *fs, struct glfs_object *object, /* TODO : set leaseid */ ret = syncop_readv(subvol, fd, size, offset, flags, &iov, &cnt, &iobref, - NULL, NULL); + NULL, NULL, NULL); DECODE_SYNCOP_ERR(ret); if (ret <= 0) goto out; @@ -5193,6 +6196,7 @@ glfs_release_xreaddirp_stat(void *ptr) * Given glfd of a directory, this function does readdirp and returns * xstat along with dirents. */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_r, 3.11.0) int pub_glfs_xreaddirplus_r(struct glfs_fd *glfd, uint32_t flags, struct glfs_xreaddirp_stat **xstat_p, @@ -5287,8 +6291,8 @@ out: GF_REF_PUT(glfd); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_WARNING, errno, API_MSG_XREADDIRP_R_FAILED, - "glfs_x_readdirp_r failed - reason (%s)", strerror(errno)); + gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_XREADDIRP_R_FAILED, + "reason=%s", strerror(errno), NULL); if (xstat) GLFS_FREE(xstat); @@ -5301,41 +6305,43 @@ out: invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_r, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_stat, 3.11.0) struct stat * pub_glfs_xreaddirplus_get_stat(struct glfs_xreaddirp_stat *xstat) { GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_stat", xstat, out); if (!xstat->flags_handled & GFAPI_XREADDIRP_STAT) - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, - "GFAPI_XREADDIRP_STAT is not set. Flags" - "handled for xstat(%p) are (%x)", - xstat, xstat->flags_handled); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_FLAGS_HANDLE, + "GFAPI_XREADDIRP_STAT" + "xstat=%p", + xstat, "handles=%x", xstat->flags_handled, NULL); return &xstat->st; out: return NULL; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_stat, 3.11.0); void gf_lease_to_glfs_lease(struct gf_lease *gf_lease, struct glfs_lease *lease) { + u_int lease_type = gf_lease->lease_type; lease->cmd = gf_lease->cmd; - lease->lease_type = gf_lease->lease_type; + lease->lease_type = lease_type; memcpy(lease->lease_id, gf_lease->lease_id, LEASE_ID_SIZE); } void glfs_lease_to_gf_lease(struct glfs_lease *lease, struct gf_lease *gf_lease) { + u_int lease_type = lease->lease_type; gf_lease->cmd = lease->cmd; - gf_lease->lease_type = lease->lease_type; + gf_lease->lease_type = lease_type; memcpy(gf_lease->lease_id, lease->lease_id, LEASE_ID_SIZE); } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lease, 4.0.0) int pub_glfs_lease(struct glfs_fd *glfd, struct glfs_lease *lease, glfs_recall_cbk fn, void *data) @@ -5416,8 +6422,8 @@ pub_glfs_lease(struct glfs_fd *glfd, struct glfs_lease *lease, if (ret == 0) { ret = fd_ctx_set(glfd->fd, subvol, (uint64_t)(long)glfd); if (ret) { - gf_msg(subvol->name, GF_LOG_ERROR, ENOMEM, API_MSG_FDCTX_SET_FAILED, - "Setting fd ctx failed for fd(%p)", glfd->fd); + gf_smsg(subvol->name, GF_LOG_ERROR, ENOMEM, + API_MSG_FDCTX_SET_FAILED, "fd=%p", glfd->fd, NULL); goto out; } glfd->cbk = fn; @@ -5437,5 +6443,3 @@ out: invalid_fs: return ret; } - -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lease, 4.0.0); diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index 7e9f4c5c915..53c2ee896f9 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -10,7 +10,7 @@ #include "glfs-internal.h" #include "glfs-mem-types.h" -#include "syncop.h" +#include <glusterfs/syncop.h> #include "glfs.h" #include "glfs-handles.h" #include "gfapi-messages.h" @@ -18,7 +18,7 @@ int glfs_listxattr_process(void *value, size_t size, dict_t *xattr); -static void +void glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt, int *glvalid) { @@ -60,6 +60,7 @@ glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt, return; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4) struct glfs_object * pub_glfs_h_lookupat(struct glfs *fs, struct glfs_object *parent, const char *path, struct stat *stat, int follow) @@ -126,8 +127,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4); - +GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2) struct glfs_object * pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent, const char *path, struct stat *stat) @@ -135,8 +135,7 @@ pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent, return pub_glfs_h_lookupat(fs, parent, path, stat, 0); } -GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0) int pub_glfs_h_statfs(struct glfs *fs, struct glfs_object *object, struct statvfs *statvfs) @@ -194,8 +193,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2) int pub_glfs_h_stat(struct glfs *fs, struct glfs_object *object, struct stat *stat) { @@ -259,8 +257,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2) int pub_glfs_h_getattrs(struct glfs *fs, struct glfs_object *object, struct stat *stat) @@ -317,8 +314,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2); - int glfs_h_getxattrs_common(struct glfs *fs, struct glfs_object *object, dict_t **xattr, const char *name, @@ -380,6 +375,7 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1) int pub_glfs_h_getxattrs(struct glfs *fs, struct glfs_object *object, const char *name, void *value, size_t size) @@ -416,8 +412,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2) int pub_glfs_h_setattrs(struct glfs *fs, struct glfs_object *object, struct stat *stat, int valid) @@ -480,8 +475,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0) int pub_glfs_h_setxattrs(struct glfs *fs, struct glfs_object *object, const char *name, const void *value, size_t size, @@ -568,8 +562,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1) int pub_glfs_h_removexattrs(struct glfs *fs, struct glfs_object *object, const char *name) @@ -626,8 +619,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2) struct glfs_fd * pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags) { @@ -699,7 +691,7 @@ pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags) if (ret) gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); - ret = syncop_open(subvol, &loc, flags, glfd->fd, NULL, NULL); + ret = syncop_open(subvol, &loc, flags, glfd->fd, fop_attr, NULL); DECODE_SYNCOP_ERR(ret); glfd->fd->flags = flags; @@ -727,8 +719,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2) struct glfs_object * pub_glfs_h_creat(struct glfs *fs, struct glfs_object *parent, const char *path, int flags, mode_t mode, struct stat *stat) @@ -840,8 +831,141 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6) +struct glfs_object * +pub_glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent, + const char *path, int flags, mode_t mode, + struct stat *stat, struct glfs_fd **out_fd) +{ + int ret = -1; + struct glfs_fd *glfd = NULL; + xlator_t *subvol = NULL; + inode_t *inode = NULL; + loc_t loc = { + 0, + }; + struct iatt iatt = { + 0, + }; + uuid_t gfid; + dict_t *xattr_req = NULL; + struct glfs_object *object = NULL; + dict_t *fop_attr = NULL; + + /* validate in args */ + if ((fs == NULL) || (parent == NULL) || (path == NULL) || + (out_fd == NULL)) { + errno = EINVAL; + return NULL; + } + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + + /* get the active volume */ + subvol = glfs_active_subvol(fs); + if (!subvol) { + ret = -1; + goto out; + } + + /* get/refresh the in arg objects inode in correlation to the xlator */ + inode = glfs_resolve_inode(fs, subvol, parent); + if (!inode) { + ret = -1; + goto out; + } + + xattr_req = dict_new(); + if (!xattr_req) { + ret = -1; + errno = ENOMEM; + goto out; + } + + gf_uuid_generate(gfid); + ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true); + if (ret) { + ret = -1; + errno = ENOMEM; + goto out; + } + + GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path); + + glfd = glfs_fd_new(fs); + if (!glfd) { + ret = -1; + errno = ENOMEM; + goto out; + } + + glfd->fd = fd_create(loc.inode, getpid()); + if (!glfd->fd) { + ret = -1; + errno = ENOMEM; + goto out; + } + glfd->fd->flags = flags; + + ret = get_fop_attr_thrd_key(&fop_attr); + if (ret) + gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed"); + + /* fop/op */ + ret = syncop_create(subvol, &loc, flags, mode, glfd->fd, &iatt, xattr_req, + NULL); + DECODE_SYNCOP_ERR(ret); + + /* populate out args */ + if (ret == 0) { + glfd->fd->flags = flags; + + ret = glfs_loc_link(&loc, &iatt); + if (ret != 0) { + goto out; + } + + if (stat) + glfs_iatt_to_stat(fs, &iatt, stat); + + ret = glfs_create_object(&loc, &object); + } + +out: + if (ret && object != NULL) { + /* Release the held reference */ + glfs_h_close(object); + object = NULL; + } + + loc_wipe(&loc); + + if (inode) + inode_unref(inode); + + if (fop_attr) + dict_unref(fop_attr); + + if (xattr_req) + dict_unref(xattr_req); + + if (ret && glfd) { + GF_REF_PUT(glfd); + } else if (glfd) { + glfd_set_state_bind(glfd); + *out_fd = glfd; + } + + glfs_subvol_done(fs, subvol); + + __GLFS_EXIT_FS; + +invalid_fs: + return object; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2) struct glfs_object * pub_glfs_h_mkdir(struct glfs *fs, struct glfs_object *parent, const char *path, mode_t mode, struct stat *stat) @@ -939,8 +1063,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2) struct glfs_object * pub_glfs_h_mknod(struct glfs *fs, struct glfs_object *parent, const char *path, mode_t mode, dev_t dev, struct stat *stat) @@ -1037,8 +1160,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2) int pub_glfs_h_unlink(struct glfs *fs, struct glfs_object *parent, const char *path) { @@ -1109,8 +1231,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2) struct glfs_fd * pub_glfs_h_opendir(struct glfs *fs, struct glfs_object *object) { @@ -1192,8 +1313,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0) int pub_glfs_h_access(struct glfs *fs, struct glfs_object *object, int mask) { @@ -1250,8 +1370,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2) ssize_t pub_glfs_h_extract_handle(struct glfs_object *object, unsigned char *handle, int len) @@ -1282,8 +1401,7 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2) struct glfs_object * pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len, struct stat *stat) @@ -1360,9 +1478,9 @@ pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len, ret = syncop_lookup(subvol, &loc, &iatt, 0, 0, 0); DECODE_SYNCOP_ERR(ret); if (ret) { - gf_msg(subvol->name, GF_LOG_WARNING, errno, - API_MSG_INODE_REFRESH_FAILED, "inode refresh of %s failed: %s", - uuid_utoa(loc.gfid), strerror(errno)); + gf_smsg(subvol->name, GF_LOG_WARNING, errno, + API_MSG_INODE_REFRESH_FAILED, "gfid=%s", uuid_utoa(loc.gfid), + "error=%s", strerror(errno), NULL); goto out; } @@ -1373,8 +1491,8 @@ pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len, } inode_lookup(newinode); } else { - gf_msg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, - "inode linking of %s failed", uuid_utoa(loc.gfid)); + gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, + "gfid=%s", uuid_utoa(loc.gfid), NULL); goto out; } @@ -1406,8 +1524,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2) int pub_glfs_h_close(struct glfs_object *object) { @@ -1420,8 +1537,7 @@ pub_glfs_h_close(struct glfs_object *object) return 0; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2) int pub_glfs_h_truncate(struct glfs *fs, struct glfs_object *object, off_t offset) { @@ -1481,8 +1597,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2) struct glfs_object * pub_glfs_h_symlink(struct glfs *fs, struct glfs_object *parent, const char *name, const char *data, struct stat *stat) @@ -1581,8 +1696,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2) int pub_glfs_h_readlink(struct glfs *fs, struct glfs_object *object, char *buf, size_t bufsiz) @@ -1647,8 +1761,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2) int pub_glfs_h_link(struct glfs *fs, struct glfs_object *linksrc, struct glfs_object *parent, const char *name) @@ -1745,8 +1858,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2) int pub_glfs_h_rename(struct glfs *fs, struct glfs_object *olddir, const char *oldname, struct glfs_object *newdir, @@ -1856,8 +1968,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2); - /* * Given a handle/gfid, find if the corresponding inode is present in * the inode table. If yes create and return the corresponding glfs_object. @@ -1962,8 +2072,8 @@ glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg, * the handle and hence will no more be interested in * the upcall for this particular gfid. */ - gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED, - "handle creation of %s failed", uuid_utoa(upcall_data->gfid)); + gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED, + "gfid=%s", uuid_utoa(upcall_data->gfid), NULL); errno = ESTALE; goto out; } @@ -1986,9 +2096,9 @@ glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg, p_object = glfs_h_find_handle(fs, ca_data->p_stat.ia_gfid, GFAPI_HANDLE_LENGTH); if (!p_object) { - gf_msg(THIS->name, GF_LOG_DEBUG, errno, - API_MSG_CREATE_HANDLE_FAILED, "handle creation of %s failed", - uuid_utoa(ca_data->p_stat.ia_gfid)); + gf_smsg(THIS->name, GF_LOG_DEBUG, errno, + API_MSG_CREATE_HANDLE_FAILED, "gfid=%s", + uuid_utoa(ca_data->p_stat.ia_gfid), NULL); errno = ESTALE; goto out; } @@ -2002,9 +2112,9 @@ glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg, oldp_object = glfs_h_find_handle(fs, ca_data->oldp_stat.ia_gfid, GFAPI_HANDLE_LENGTH); if (!oldp_object) { - gf_msg(THIS->name, GF_LOG_DEBUG, errno, - API_MSG_CREATE_HANDLE_FAILED, "handle creation of %s failed", - uuid_utoa(ca_data->oldp_stat.ia_gfid)); + gf_smsg(THIS->name, GF_LOG_DEBUG, errno, + API_MSG_CREATE_HANDLE_FAILED, "gfid=%s", + uuid_utoa(ca_data->oldp_stat.ia_gfid), NULL); errno = ESTALE; /* By the time we receive upcall old parent_dir may * have got removed. We still need to send upcall @@ -2065,6 +2175,7 @@ glfs_release_upcall(void *ptr) * calling glfs_fini(..). Hence making an assumption that 'fs' & ctx structures * cannot be freed while in this routine. */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16) int pub_glfs_h_poll_upcall(struct glfs *fs, struct glfs_upcall **up_arg) { @@ -2182,8 +2293,6 @@ err: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16); - static gf_boolean_t log_upcall370 = _gf_true; /* log once */ /* The old glfs_h_poll_upcall interface requires intimate knowledge of the @@ -2197,6 +2306,7 @@ static gf_boolean_t log_upcall370 = _gf_true; /* log once */ * * WARNING: this function will be removed in the future. */ +GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0) int pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg) { @@ -2216,7 +2326,7 @@ pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg) ret = pub_glfs_h_poll_upcall(fs, &upcall); if (ret == 0) { up_arg->fs = fs; - if (errno == ENOENT || upcall->event == NULL) { + if ((errno == ENOENT) || !upcall || !upcall->event) { up_arg->reason = GLFS_UPCALL_EVENT_NULL; goto out; } @@ -2264,12 +2374,11 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0); - #ifdef HAVE_ACL_LIBACL_H -#include "glusterfs-acl.h" +#include <glusterfs/glusterfs-acl.h> #include <acl/libacl.h> +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0) int pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, const acl_type_t type, const acl_t acl) @@ -2318,6 +2427,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0) acl_t pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, const acl_type_t type) @@ -2372,6 +2482,7 @@ invalid_fs: return acl; } #else /* !HAVE_ACL_LIBACL_H */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0) acl_t pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, const acl_type_t type) @@ -2380,6 +2491,7 @@ pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, return NULL; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0) int pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, const acl_type_t type, const acl_t acl) @@ -2388,10 +2500,9 @@ pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, return -1; } #endif -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0); -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0); /* The API to perform read using anonymous fd */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0) ssize_t pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object, const void *buf, size_t count, off_t offset) @@ -2415,9 +2526,8 @@ pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0); - /* The API to perform write using anonymous fd */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0) ssize_t pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object, const void *buf, size_t count, off_t offset) @@ -2441,8 +2551,7 @@ pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0) struct glfs_object * pub_glfs_object_copy(struct glfs_object *src) { @@ -2453,9 +2562,8 @@ pub_glfs_object_copy(struct glfs_object *src) object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t); if (object == NULL) { errno = ENOMEM; - gf_msg(THIS->name, GF_LOG_WARNING, errno, API_MSG_CREATE_HANDLE_FAILED, - "glfs_dup_object for gfid-%s failed", - uuid_utoa(src->inode->gfid)); + gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_CREATE_HANDLE_FAILED, + "glfs_dup_object gfid=%s", uuid_utoa(src->inode->gfid), NULL); return NULL; } @@ -2465,26 +2573,25 @@ pub_glfs_object_copy(struct glfs_object *src) out: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0) struct glfs_object * pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat) { GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_object", xstat, out); if (!(xstat->flags_handled & GFAPI_XREADDIRP_HANDLE)) - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, - "GFAPI_XREADDIRP_HANDLE is not set. Flags" - "handled for xstat(%p) are (%x)", - xstat, xstat->flags_handled); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_HANDLE_NOT_SET, + "GFAPI_XREADDIRP_HANDLE xstat=%p", xstat, "handle=%x", + xstat->flags_handled, NULL); return xstat->object; out: return NULL; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0) int pub_glfs_h_lease(struct glfs *fs, struct glfs_object *object, struct glfs_lease *lease) @@ -2546,5 +2653,3 @@ out: invalid_fs: return ret; } - -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0); diff --git a/api/src/glfs-handles.h b/api/src/glfs-handles.h index 09b3b2ed493..4d039b9c76b 100644 --- a/api/src/glfs-handles.h +++ b/api/src/glfs-handles.h @@ -12,7 +12,6 @@ #define _GLFS_HANDLES_H #include "glfs.h" -#include <inttypes.h> /* GLFS OBJECT BASED OPERATIONS * @@ -47,16 +46,6 @@ * */ -/* Values for valid flags to be used when using XXXsetattr, to set multiple - attribute values passed via the related stat structure. - */ -#define GFAPI_SET_ATTR_MODE 0x1 -#define GFAPI_SET_ATTR_UID 0x2 -#define GFAPI_SET_ATTR_GID 0x4 -#define GFAPI_SET_ATTR_SIZE 0x8 -#define GFAPI_SET_ATTR_ATIME 0x10 -#define GFAPI_SET_ATTR_MTIME 0x20 - /* Handle length for object handles returned from glfs_h_extract_handle or * glfs_h_create_from_handle */ #define GFAPI_HANDLE_LENGTH 16 @@ -261,6 +250,11 @@ int glfs_h_access(glfs_t *fs, glfs_object_t *object, int mask) __THROW GFAPI_PUBLIC(glfs_h_access, 3.6.0); +struct glfs_object * +glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent, const char *path, + int flags, mode_t mode, struct stat *stat, + struct glfs_fd **out_fd) __THROW + GFAPI_PUBLIC(glfs_h_creat_open, 6.6); /* SYNOPSIS diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index a8d5c59e209..7cc3b18a104 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -11,11 +11,12 @@ #ifndef _GLFS_INTERNAL_H #define _GLFS_INTERNAL_H -#include "xlator.h" -#include "glusterfs.h" -#include "upcall-utils.h" +#include <glusterfs/xlator.h> +#include <glusterfs/glusterfs.h> +#include <glusterfs/upcall-utils.h> #include "glfs-handles.h" -#include "refcount.h" +#include <glusterfs/refcount.h> +#include <glusterfs/syncop.h> #define GLFS_SYMLINK_MAX_FOLLOW 2048 @@ -80,25 +81,40 @@ #ifndef GFAPI_PRIVATE #define GFAPI_PRIVATE(sym, ver) /**/ #endif +#if __GNUC__ >= 10 #define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \ - asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver)) + __attribute__((__symver__(STR(fn) "@@GFAPI_" STR(ver)))) #define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \ - asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver)) + __attribute__((__symver__(STR(fn) "@@GFAPI_PRIVATE_" STR(ver)))) #define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \ - asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver)) + __attribute__((__symver__(STR(fn2) "@GFAPI_" STR(ver)))) #define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \ - asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver)) + __attribute__((__symver__(STR(fn2) "@GFAPI_PRIVATE_" STR(ver)))) + +#else +#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \ + asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver)); + +#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \ + asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver)); + +#define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \ + asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver)); + +#define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \ + asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver)); +#endif #define STR(str) #str #else #ifndef GFAPI_PUBLIC -#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver)) +#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver)); #endif #ifndef GFAPI_PRIVATE #define GFAPI_PRIVATE(sym, ver) \ - __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver)) + __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver)); #endif #define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, dotver) /**/ #define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, dotver) /**/ @@ -207,6 +223,7 @@ struct glfs { glfs_upcall_cbk up_cbk; /* upcall cbk function to be registered */ void *up_data; /* Opaque data provided by application * during upcall registration */ + struct list_head waitq; /* waiting synctasks */ }; /* This enum is used to maintain the state of glfd. In case of async fops @@ -442,6 +459,34 @@ glfs_process_upcall_event(struct glfs *fs, void *data) THIS = glfd->fd->inode->table->xl->ctx->master; \ } while (0) +#define __GLFS_LOCK_WAIT(fs) \ + do { \ + struct synctask *task = NULL; \ + \ + task = synctask_get(); \ + \ + if (task) { \ + list_add_tail(&task->waitq, &fs->waitq); \ + pthread_mutex_unlock(&fs->mutex); \ + synctask_yield(task, NULL); \ + pthread_mutex_lock(&fs->mutex); \ + } else { \ + /* non-synctask */ \ + pthread_cond_wait(&fs->cond, &fs->mutex); \ + } \ + } while (0) + +#define __GLFS_SYNCTASK_WAKE(fs) \ + do { \ + struct synctask *waittask = NULL; \ + \ + while (!list_empty(&fs->waitq)) { \ + waittask = list_entry(fs->waitq.next, struct synctask, waitq); \ + list_del_init(&waittask->waitq); \ + synctask_wake(waittask); \ + } \ + } while (0) + /* By default all lock attempts from user context must use glfs_lock() and glfs_unlock(). This allows @@ -466,10 +511,10 @@ glfs_lock(struct glfs *fs, gf_boolean_t wait_for_migration) pthread_mutex_lock(&fs->mutex); while (!fs->init) - pthread_cond_wait(&fs->cond, &fs->mutex); + __GLFS_LOCK_WAIT(fs); while (wait_for_migration && fs->migration_in_progress) - pthread_cond_wait(&fs->cond, &fs->mutex); + __GLFS_LOCK_WAIT(fs); return 0; } @@ -522,6 +567,9 @@ int glfs_loc_touchup(loc_t *loc) GFAPI_PRIVATE(glfs_loc_touchup, 3.4.0); void glfs_iatt_to_stat(struct glfs *fs, struct iatt *iatt, struct stat *stat); +void +glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt, + int *gvalid); int glfs_loc_link(loc_t *loc, struct iatt *iatt); int @@ -667,4 +715,42 @@ get_fop_attr_thrd_key(dict_t **fop_attr); void unset_fop_attr(dict_t **fop_attr); + +/* + SYNOPSIS + glfs_statx: Fetch extended file attributes for the given path. + + DESCRIPTION + This function fetches extended file attributes for the given path. + + PARAMETERS + @fs: The 'virtual mount' object referencing a volume, under which file exists. + @path: Path of the file within the virtual mount. + @mask: Requested extended file attributes mask, (See mask defines above) + + RETURN VALUES + -1 : Failure. @errno will be set with the type of failure. + 0 : Filled in statxbuf with appropriate masks for valid items in the + structure. + + ERRNO VALUES + EINVAL: fs is invalid + EINVAL: mask has unsupported bits set + Other errors as returned by stat(2) + */ + +int +glfs_statx(struct glfs *fs, const char *path, unsigned int mask, + struct glfs_stat *statxbuf) GFAPI_PRIVATE(glfs_statx, 6.0); + +void +glfs_iatt_from_statx(struct iatt *, const struct glfs_stat *) + GFAPI_PRIVATE(glfs_iatt_from_statx, 6.0); + +/* + * This API is a per thread setting, similar to glfs_setfs{u/g}id, because of + * the call to syncopctx_setfspid. + */ +int +glfs_setfspid(struct glfs *, pid_t) GFAPI_PRIVATE(glfs_setfspid, 6.1); #endif /* !_GLFS_INTERNAL_H */ diff --git a/api/src/glfs-master.c b/api/src/glfs-master.c index 969095a8224..100dcc16cc0 100644 --- a/api/src/glfs-master.c +++ b/api/src/glfs-master.c @@ -8,15 +8,9 @@ cases as published by the Free Software Foundation. */ -#include <unistd.h> -#include <string.h> -#include <stdlib.h> #include <stdio.h> -#include <inttypes.h> -#include <limits.h> -#include "xlator.h" -#include "glusterfs.h" +#include <glusterfs/glusterfs.h> #include "glfs-internal.h" #include "glfs-mem-types.h" @@ -81,9 +75,10 @@ notify(xlator_t *this, int event, void *data, ...) switch (event) { case GF_EVENT_GRAPH_NEW: - gf_msg(this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH, - "New graph %s (%d) coming up", - uuid_utoa((unsigned char *)graph->graph_uuid), graph->id); + gf_smsg(this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH, + "graph-uuid=%s", + uuid_utoa((unsigned char *)graph->graph_uuid), "id=%d", + graph->id, NULL); break; case GF_EVENT_CHILD_UP: pthread_mutex_lock(&fs->mutex); @@ -126,9 +121,8 @@ mem_acct_init(xlator_t *this) ret = xlator_mem_acct_init(this, glfs_mt_end + 1); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED, - "Failed to initialise " - "memory accounting"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED, + NULL); return ret; } @@ -169,6 +163,21 @@ struct xlator_dumpops dumpops; struct xlator_fops fops; -struct xlator_cbks cbks = {.forget = glfs_forget, - .release = glfs_release, - .releasedir = glfs_releasedir}; +struct xlator_cbks cbks = { + .forget = glfs_forget, + .release = glfs_release, + .releasedir = glfs_releasedir, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .mem_acct_init = mem_acct_init, + .op_version = {1}, + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .identifier = "glfs-api", + .category = GF_MAINTAINED, +}; diff --git a/api/src/glfs-mem-types.h b/api/src/glfs-mem-types.h index e1316d128af..bfa325a3ad9 100644 --- a/api/src/glfs-mem-types.h +++ b/api/src/glfs-mem-types.h @@ -11,7 +11,7 @@ #ifndef _GLFS_MEM_TYPES_H #define _GLFS_MEM_TYPES_H -#include "mem-types.h" +#include <glusterfs/mem-types.h> #define GF_MEM_TYPE_START (gf_common_mt_end + 1) diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 87b62173689..7c82b8cd162 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -15,27 +15,20 @@ #include <signal.h> #include <pthread.h> -#include "glusterfs.h" +#include <glusterfs/glusterfs.h> #include "glfs.h" -#include "dict.h" -#include "gf-event.h" -#include "defaults.h" +#include <glusterfs/dict.h> #include "rpc-clnt.h" #include "protocol-common.h" -#include "glusterfs3.h" -#include "portmap-xdr.h" -#include "xdr-common.h" #include "xdr-generic.h" #include "rpc-common-xdr.h" -#include "syncop.h" -#include "xlator.h" +#include <glusterfs/syncop.h> #include "glfs-internal.h" -#include "glfs-mem-types.h" #include "gfapi-messages.h" -#include "syscall.h" +#include <glusterfs/syscall.h> int glfs_volfile_fetch(struct glfs *fs); @@ -53,16 +46,15 @@ glfs_process_volfp(struct glfs *fs, FILE *fp) ctx = fs->ctx; graph = glusterfs_graph_construct(fp); if (!graph) { - gf_msg("glfs", GF_LOG_ERROR, errno, API_MSG_GRAPH_CONSTRUCT_FAILED, - "failed to construct the graph"); + gf_smsg("glfs", GF_LOG_ERROR, errno, API_MSG_GRAPH_CONSTRUCT_FAILED, + NULL); goto out; } for (trav = graph->first; trav; trav = trav->next) { if (strcmp(trav->type, "mount/api") == 0) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_API_XLATOR_ERROR, - "api master xlator cannot be specified " - "in volume file"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_API_XLATOR_ERROR, + NULL); goto out; } } @@ -127,32 +119,28 @@ mgmt_cbk_statedump(struct rpc_clnt *rpc, void *mydata, void *data) this = mydata; if (!this) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED, - "NULL mydata"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "mydata", NULL); errno = EINVAL; goto out; } fs = this->private; if (!fs) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED, - "NULL glfs"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "glfs", NULL); errno = EINVAL; goto out; } iov = (struct iovec *)data; if (!iov) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED, - "NULL iovec data"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "iovec data", NULL); errno = EINVAL; goto out; } ret = xdr_to_generic(*iov, &target_pid, (xdrproc_t)xdr_gf_statedump); if (ret < 0) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED, - "Failed to decode xdr response for GF_CBK_STATEDUMP"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_DECODE_XDR_FAILED, NULL); goto out; } @@ -163,22 +151,21 @@ mgmt_cbk_statedump(struct rpc_clnt *rpc, void *mydata, void *data) ret = glfs_sysrq(fs, GLFS_SYSRQ_STATEDUMP); if (ret < 0) { - gf_msg("glfs", GF_LOG_INFO, 0, API_MSG_STATEDUMP_FAILED, - "statedump failed"); + gf_smsg("glfs", GF_LOG_INFO, 0, API_MSG_STATEDUMP_FAILED, NULL); } } out: return ret; } -rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = { - [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec}, - [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY, - mgmt_cbk_event}, - [GF_CBK_STATEDUMP] = {"STATEDUMP", GF_CBK_STATEDUMP, mgmt_cbk_statedump}, +static rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = { + [GF_CBK_FETCHSPEC] = {"FETCHSPEC", mgmt_cbk_spec, GF_CBK_FETCHSPEC}, + [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", mgmt_cbk_event, + GF_CBK_EVENT_NOTIFY}, + [GF_CBK_STATEDUMP] = {"STATEDUMP", mgmt_cbk_statedump, GF_CBK_STATEDUMP}, }; -struct rpcclnt_cb_program mgmt_cbk_prog = { +static struct rpcclnt_cb_program mgmt_cbk_prog = { .progname = "GlusterFS Callback", .prognum = GLUSTER_CBK_PROGRAM, .progver = GLUSTER_CBK_VERSION, @@ -186,7 +173,7 @@ struct rpcclnt_cb_program mgmt_cbk_prog = { .numactors = GF_CBK_MAXVALUE, }; -char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { +static char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = "NULL", [GF_HNDSK_SETVOLUME] = "SETVOLUME", [GF_HNDSK_GETSPEC] = "GETSPEC", @@ -195,7 +182,7 @@ char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_GET_VOLUME_INFO] = "GETVOLUMEINFO", }; -rpc_clnt_prog_t clnt_handshake_prog = { +static rpc_clnt_prog_t clnt_handshake_prog = { .progname = "GlusterFS Handshake", .prognum = GLUSTER_HNDSK_PROGRAM, .progver = GLUSTER_HNDSK_VERSION, @@ -237,8 +224,8 @@ mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx, /* Create the xdr payload */ ret = xdr_serialize_generic(iov, req, xdrproc); if (ret == -1) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_XDR_PAYLOAD_FAILED, - "failed to create XDR payload"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_XDR_PAYLOAD_FAILED, + NULL); goto out; } iov.iov_len = ret; @@ -268,7 +255,6 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, int ret = 0; char *volume_id_str = NULL; dict_t *dict = NULL; - char key[1024] = {0}; gf_get_volume_info_rsp rsp = { 0, }; @@ -282,8 +268,8 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, args = frame->local; if (!ctx) { - gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "NULL context"); + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_NULL, + "context", NULL); errno = EINVAL; ret = -1; goto out; @@ -292,8 +278,8 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, fs = ((xlator_t *)ctx->master)->private; if (-1 == req->rpc_status) { - gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "GET_VOLUME_INFO RPC call is not successful"); + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + API_MSG_CALL_NOT_SUCCESSFUL, NULL); errno = EINVAL; ret = -1; goto out; @@ -302,9 +288,8 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_get_volume_info_rsp); if (ret < 0) { - gf_msg(frame->this->name, GF_LOG_ERROR, 0, - API_MSG_XDR_RESPONSE_DECODE_FAILED, - "Failed to decode xdr response for GET_VOLUME_INFO"); + gf_smsg(frame->this->name, GF_LOG_ERROR, 0, + API_MSG_XDR_RESPONSE_DECODE_FAILED, NULL); goto out; } @@ -320,9 +305,8 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, } if (!rsp.dict.dict_len) { - gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "Response received for " - "GET_VOLUME_INFO RPC call is not valid"); + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_CALL_NOT_VALID, + NULL); ret = -1; errno = EINVAL; goto out; @@ -343,8 +327,7 @@ mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count, goto out; } - snprintf(key, sizeof(key), "volume_id"); - ret = dict_get_str(dict, key, &volume_id_str); + ret = dict_get_str_sizen(dict, "volume_id", &volume_id_str); if (ret) { errno = EINVAL; goto out; @@ -360,11 +343,9 @@ out: } if (ret) { - gf_msg(frame->this->name, GF_LOG_ERROR, errno, - API_MSG_GET_VOLINFO_CBK_FAILED, - "In GET_VOLUME_INFO " - "cbk, received error: %s", - strerror(errno)); + gf_smsg(frame->this->name, GF_LOG_ERROR, errno, + API_MSG_GET_VOLINFO_CBK_FAILED, "error=%s", strerror(errno), + NULL); } if (dict) @@ -383,6 +364,7 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0) int pub_glfs_get_volumeid(struct glfs *fs, char *volid, size_t size) { @@ -406,9 +388,8 @@ pub_glfs_get_volumeid(struct glfs *fs, char *volid, size_t size) glfs_get_volume_info(fs); if (gf_uuid_is_null(fs->vol_uuid)) { - gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_FETCH_VOLUUID_FAILED, - "Unable to fetch " - "volume UUID"); + gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_FETCH_VOLUUID_FAILED, + NULL); goto out; } @@ -420,8 +401,7 @@ done: } if (size < uuid_size) { - gf_msg(THIS->name, GF_LOG_ERROR, ERANGE, API_MSG_INSUFF_SIZE, - "Insufficient size passed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ERANGE, API_MSG_INSUFF_SIZE, NULL); errno = ERANGE; goto out; } @@ -439,8 +419,6 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0); - int glfs_get_volume_info(struct glfs *fs) { @@ -454,8 +432,7 @@ glfs_get_volume_info(struct glfs *fs) ctx = fs->ctx; frame = create_frame(THIS, ctx->pool); if (!frame) { - gf_msg("glfs", GF_LOG_ERROR, ENOMEM, API_MSG_FRAME_CREAT_FAILED, - "failed to create the frame"); + gf_smsg("glfs", GF_LOG_ERROR, ENOMEM, API_MSG_FRAME_CREAT_FAILED, NULL); ret = -1; goto out; } @@ -511,8 +488,8 @@ glfs_get_volume_info_rpc(call_frame_t *frame, xlator_t *this, struct glfs *fs) flags = (int32_t)GF_GET_VOLUME_UUID; // ctx->flags; ret = dict_set_int32(dict, "flags", flags); if (ret) { - gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED, - "failed to set flags"); + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + API_MSG_DICT_SET_FAILED, "flags", NULL); goto out; } @@ -582,8 +559,8 @@ glfs_mgmt_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count, ctx = frame->this->ctx; if (!ctx) { - gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "NULL context"); + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_NULL, + "context", NULL); errno = EINVAL; ret = -1; goto out; @@ -599,16 +576,15 @@ glfs_mgmt_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count, ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp); if (ret < 0) { - gf_msg(frame->this->name, GF_LOG_ERROR, 0, API_MSG_XDR_DECODE_FAILED, - "XDR decoding error"); + gf_smsg(frame->this->name, GF_LOG_ERROR, 0, API_MSG_XDR_DECODE_FAILED, + NULL); ret = -1; goto out; } if (-1 == rsp.op_ret) { - gf_msg(frame->this->name, GF_LOG_ERROR, rsp.op_errno, - API_MSG_GET_VOLFILE_FAILED, - "failed to get the 'volume file' from server"); + gf_smsg(frame->this->name, GF_LOG_ERROR, rsp.op_errno, + API_MSG_GET_VOLFILE_FAILED, "from server", NULL); ret = -1; errno = rsp.op_errno; goto out; @@ -653,12 +629,14 @@ volfile: ret = 0; size = rsp.op_ret; + pthread_mutex_lock(&fs->mutex); if ((size == fs->oldvollen) && (memcmp(fs->oldvolfile, rsp.spec, size) == 0)) { - gf_msg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO, - "No change in volfile, continuing"); + pthread_mutex_unlock(&fs->mutex); + gf_smsg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO, NULL); goto out; } + pthread_mutex_unlock(&fs->mutex); /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */ tmp_fd = mkstemp(template); @@ -672,8 +650,8 @@ volfile: */ ret = sys_unlink(template); if (ret < 0) { - gf_msg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO, - "Unable to delete file: %s", template); + gf_smsg(frame->this->name, GF_LOG_INFO, 0, API_MSG_UNABLE_TO_DEL, + "template=%s", template, NULL); ret = 0; } @@ -694,12 +672,15 @@ volfile: * volfile if topology hasn't changed. * glusterfs_volfile_reconfigure returns 3 possible return states * return 0 =======> reconfiguration of options has succeeded - * return 1 =======> the graph has to be reconstructed and all the - * xlators should be inited return -1(or -ve) =======> Some Internal Error - * occurred during the operation + * return 1 =======> the graph has to be reconstructed and all + * the xlators should be inited return -1(or -ve) =======> Some Internal + * Error occurred during the operation */ + pthread_mutex_lock(&fs->mutex); ret = gf_volfile_reconfigure(fs->oldvollen, tmpfp, fs->ctx, fs->oldvolfile); + pthread_mutex_unlock(&fs->mutex); + if (ret == 0) { gf_msg_debug("glusterfsd-mgmt", 0, "No need to re-load " @@ -732,9 +713,7 @@ out: // Stop if server is running at an unsupported op-version if (ENOTSUP == ret) { - gf_msg("mgmt", GF_LOG_ERROR, ENOTSUP, API_MSG_WRONG_OPVERSION, - "Server is operating at an op-version which is not " - "supported"); + gf_smsg("mgmt", GF_LOG_ERROR, ENOTSUP, API_MSG_WRONG_OPVERSION, NULL); errno = ENOTSUP; glfs_init_done(fs, -1); } @@ -743,9 +722,8 @@ out: /* Do it only for the first time */ /* Failed to get the volume file, something wrong, restart the process */ - gf_msg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "failed to fetch volume file (key:%s)", - ctx->cmd_args.volfile_id); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_GET_VOLFILE_FAILED, + "key=%s", ctx->cmd_args.volfile_id, NULL); if (!need_retry) { if (!errno) errno = EINVAL; @@ -768,7 +746,7 @@ glfs_volfile_fetch(struct glfs *fs) gf_getspec_req req = { 0, }; - int ret = 0; + int ret = -1; call_frame_t *frame = NULL; glusterfs_ctx_t *ctx = NULL; dict_t *dict = NULL; @@ -776,14 +754,11 @@ glfs_volfile_fetch(struct glfs *fs) ctx = fs->ctx; cmd_args = &ctx->cmd_args; - frame = create_frame(THIS, ctx->pool); - req.key = cmd_args->volfile_id; req.flags = 0; dict = dict_new(); if (!dict) { - ret = -1; goto out; } @@ -791,15 +766,15 @@ glfs_volfile_fetch(struct glfs *fs) // decision ret = dict_set_int32(dict, "min-op-version", GD_OP_VERSION_MIN); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED, - "Failed to set min-op-version in request dict"); + gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED, + "min-op-version", NULL); goto out; } ret = dict_set_int32(dict, "max-op-version", GD_OP_VERSION_MAX); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED, - "Failed to set max-op-version in request dict"); + gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED, + "max-op-version", NULL); goto out; } @@ -811,8 +786,14 @@ glfs_volfile_fetch(struct glfs *fs) ret = dict_allocate_and_serialize(dict, &req.xdata.xdata_val, &req.xdata.xdata_len); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, API_MSG_DICT_SERIALIZE_FAILED, - "Failed to serialize dictionary"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, API_MSG_DICT_SERIALIZE_FAILED, + NULL); + goto out; + } + + frame = create_frame(THIS, ctx->pool); + if (!frame) { + ret = -1; goto out; } @@ -853,15 +834,13 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, case RPC_CLNT_DISCONNECT: if (!ctx->active) { if (rpc_trans->connect_failed) - gf_msg("glfs-mgmt", GF_LOG_ERROR, 0, - API_MSG_REMOTE_HOST_CONN_FAILED, - "failed to connect to remote-host: %s", - ctx->cmd_args.volfile_server); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, 0, + API_MSG_REMOTE_HOST_CONN_FAILED, "server=%s", + ctx->cmd_args.volfile_server, NULL); else - gf_msg("glfs-mgmt", GF_LOG_INFO, 0, - API_MSG_REMOTE_HOST_CONN_FAILED, - "disconnected from remote-host: %s", - ctx->cmd_args.volfile_server); + gf_smsg("glfs-mgmt", GF_LOG_INFO, 0, + API_MSG_REMOTE_HOST_CONN_FAILED, "server=%s", + ctx->cmd_args.volfile_server, NULL); if (!rpc->disabled) { /* @@ -876,9 +855,8 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, server = ctx->cmd_args.curr_server; if (server->list.next == &ctx->cmd_args.volfile_servers) { errno = ENOTCONN; - gf_msg("glfs-mgmt", GF_LOG_INFO, ENOTCONN, - API_MSG_VOLFILE_SERVER_EXHAUST, - "Exhausted all volfile servers"); + gf_smsg("glfs-mgmt", GF_LOG_INFO, ENOTCONN, + API_MSG_VOLFILE_SERVER_EXHAUST, NULL); glfs_init_done(fs, -1); break; } @@ -891,10 +869,9 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, ret = dict_set_str(rpc_trans->options, "transport-type", server->transport); if (ret != 0) { - gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, - API_MSG_DICT_SET_FAILED, - "failed to set transport-type: %s", - server->transport); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, + API_MSG_DICT_SET_FAILED, "transport-type=%s", + server->transport, NULL); errno = ENOTCONN; glfs_init_done(fs, -1); break; @@ -905,10 +882,10 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, "transport.socket.connect-path", server->volfile_server); if (ret != 0) { - gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, - API_MSG_DICT_SET_FAILED, - "failed to set socket.connect-path: %s", - server->volfile_server); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, + API_MSG_DICT_SET_FAILED, + "socket.connect-path=%s", + server->volfile_server, NULL); errno = ENOTCONN; glfs_init_done(fs, -1); break; @@ -923,9 +900,9 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, ret = dict_set_int32(rpc_trans->options, "remote-port", server->port); if (ret != 0) { - gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, - API_MSG_DICT_SET_FAILED, - "failed to set remote-port: %d", server->port); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, + API_MSG_DICT_SET_FAILED, "remote-port=%d", + server->port, NULL); errno = ENOTCONN; glfs_init_done(fs, -1); break; @@ -934,10 +911,9 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, ret = dict_set_str(rpc_trans->options, "remote-host", server->volfile_server); if (ret != 0) { - gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, - API_MSG_DICT_SET_FAILED, - "failed to set remote-host: %s", - server->volfile_server); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN, + API_MSG_DICT_SET_FAILED, "remote-host=%s", + server->volfile_server, NULL); errno = ENOTCONN; glfs_init_done(fs, -1); break; @@ -950,10 +926,9 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, "transport.socket.connect-path"); } - gf_msg("glfs-mgmt", GF_LOG_INFO, 0, API_MSG_VOLFILE_CONNECTING, - "connecting to next volfile server %s" - " at port %d with transport: %s", - server->volfile_server, server->port, server->transport); + gf_smsg("glfs-mgmt", GF_LOG_INFO, 0, API_MSG_VOLFILE_CONNECTING, + "server=%s", server->volfile_server, "port=%d", + server->port, "transport=%s", server->transport, NULL); } break; case RPC_CLNT_CONNECT: @@ -961,9 +936,9 @@ mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, if (ret && (ctx->active == NULL)) { /* Do it only for the first time */ /* Exit the process.. there are some wrong options */ - gf_msg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "failed to fetch volume file (key:%s)", - ctx->cmd_args.volfile_id); + gf_smsg("glfs-mgmt", GF_LOG_ERROR, EINVAL, + API_MSG_GET_VOLFILE_FAILED, "key=%s", + ctx->cmd_args.volfile_id, NULL); errno = EINVAL; glfs_init_done(fs, -1); } @@ -1009,6 +984,10 @@ glfs_mgmt_init(struct glfs *fs) if (ctx->mgmt) return 0; + options = dict_new(); + if (!options) + goto out; + if (cmd_args->volfile_server_port) port = cmd_args->volfile_server_port; @@ -1023,38 +1002,36 @@ glfs_mgmt_init(struct glfs *fs) if (cmd_args->volfile_server_transport && !strcmp(cmd_args->volfile_server_transport, "unix")) { - ret = rpc_transport_unix_options_build(&options, host, 0); + ret = rpc_transport_unix_options_build(options, host, 0); } else { - ret = rpc_transport_inet_options_build(&options, host, port); + xlator_cmdline_option_t *opt = find_xlator_option_in_cmd_args_t( + "address-family", cmd_args); + ret = rpc_transport_inet_options_build(options, host, port, + (opt ? opt->value : NULL)); } if (ret) goto out; - if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) { - ctx->secure_mgmt = 1; - ctx->ssl_cert_depth = glusterfs_read_secure_access_file(); - } - rpc = rpc_clnt_new(options, THIS, THIS->name, 8); if (!rpc) { ret = -1; - gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_CREATE_RPC_CLIENT_FAILED, - "failed to create rpc clnt"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_CREATE_RPC_CLIENT_FAILED, + NULL); goto out; } ret = rpc_clnt_register_notify(rpc, mgmt_rpc_notify, THIS); if (ret) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_NOTIFY_FUNC_FAILED, - "failed to register notify function"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_NOTIFY_FUNC_FAILED, + NULL); goto out; } ret = rpcclnt_cbk_program_register(rpc, &mgmt_cbk_prog, THIS); if (ret) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_CBK_FUNC_FAILED, - "failed to register callback function"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_CBK_FUNC_FAILED, + NULL); goto out; } @@ -1066,5 +1043,7 @@ glfs_mgmt_init(struct glfs *fs) ret = rpc_clnt_start(rpc); out: + if (options) + dict_unref(options); return ret; } diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index fc08311c59f..8a393ecb464 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -15,16 +15,16 @@ #include <inttypes.h> #include <limits.h> -#include "glusterfs.h" -#include "logging.h" -#include "stack.h" -#include "gf-event.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/logging.h> +#include <glusterfs/stack.h> +#include <glusterfs/gf-event.h> #include "glfs-mem-types.h" -#include "common-utils.h" -#include "syncop.h" -#include "call-stub.h" +#include <glusterfs/common-utils.h> +#include <glusterfs/syncop.h> +#include <glusterfs/call-stub.h> #include "gfapi-messages.h" -#include "inode.h" +#include <glusterfs/inode.h> #include "glfs-internal.h" #define graphid_str(subvol) \ @@ -65,6 +65,9 @@ __glfs_first_lookup(struct glfs *fs, xlator_t *subvol) fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return ret; } @@ -116,9 +119,9 @@ glfs_refresh_inode_safe(xlator_t *subvol, inode_t *oldinode, DECODE_SYNCOP_ERR(ret); if (ret) { - gf_msg(subvol->name, GF_LOG_WARNING, errno, - API_MSG_INODE_REFRESH_FAILED, "inode refresh of %s failed: %s", - uuid_utoa(oldinode->gfid), strerror(errno)); + gf_smsg(subvol->name, GF_LOG_WARNING, errno, + API_MSG_INODE_REFRESH_FAILED, "gfid=%s", + uuid_utoa(oldinode->gfid), "err=%s", strerror(errno), NULL); loc_wipe(&loc); return NULL; } @@ -129,9 +132,8 @@ glfs_refresh_inode_safe(xlator_t *subvol, inode_t *oldinode, inode_ctx_set(newinode, THIS, &ctx_value); inode_lookup(newinode); } else { - gf_msg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, - "inode linking of %s failed", - uuid_utoa((unsigned char *)&iatt.ia_gfid)); + gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, + "gfid=%s", uuid_utoa((unsigned char *)&iatt.ia_gfid), NULL); } loc_wipe(&loc); @@ -154,9 +156,13 @@ __glfs_refresh_inode(struct glfs *fs, xlator_t *subvol, inode_t *inode, fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return newinode; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0) int priv_glfs_loc_touchup(loc_t *loc) { @@ -171,8 +177,6 @@ priv_glfs_loc_touchup(loc_t *loc) return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0); - int glfs_resolve_symlink(struct glfs *fs, xlator_t *subvol, inode_t *inode, char **lpath) @@ -335,6 +339,7 @@ glfs_resolve_component(struct glfs *fs, xlator_t *subvol, inode_t *parent, if (temp_parent) { inode_unref(loc.parent); loc.parent = temp_parent; + gf_uuid_copy(loc.pargfid, temp_parent->gfid); inode_find_directory_name(loc.inode, &loc.name); } @@ -345,11 +350,13 @@ glfs_resolve_component(struct glfs *fs, xlator_t *subvol, inode_t *parent, if (temp_parent) { inode_unref(loc.parent); loc.parent = temp_parent; + gf_uuid_copy(loc.pargfid, temp_parent->gfid); inode_find_directory_name(loc.inode, &loc.name); } else if (__is_root_gfid(loc.inode->gfid)) { inode_unref(loc.parent); loc.parent = inode_ref(loc.inode); - loc.name = ""; + gf_uuid_copy(loc.pargfid, loc.inode->gfid); + loc.name = "."; } else { inode_unref(loc.inode); loc.inode = NULL; @@ -439,9 +446,8 @@ glfs_resolve_component(struct glfs *fs, xlator_t *subvol, inode_t *parent, inode = inode_link(loc.inode, loc.parent, component, &ciatt); if (!inode) { - gf_msg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, - "inode linking of %s failed", - uuid_utoa((unsigned char *)&ciatt.ia_gfid)); + gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED, + "gfid=%s", uuid_utoa((unsigned char *)&ciatt.ia_gfid), NULL); goto out; } else if (inode == loc.inode) inode_ctx_set(inode, THIS, &ctx_value); @@ -460,6 +466,7 @@ out: return inode; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0) int priv_glfs_resolve_at(struct glfs *fs, xlator_t *subvol, inode_t *at, const char *origpath, loc_t *loc, struct iatt *iatt, @@ -610,8 +617,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0); - int glfs_resolve_path(struct glfs *fs, xlator_t *subvol, const char *origpath, loc_t *loc, struct iatt *iatt, int follow, int reval) @@ -625,8 +630,8 @@ glfs_resolve_path(struct glfs *fs, xlator_t *subvol, const char *origpath, cwd = glfs_cwd_get(fs); if (NULL == cwd) { - gf_msg(subvol->name, GF_LOG_WARNING, EIO, API_MSG_GET_CWD_FAILED, - "Failed to get cwd"); + gf_smsg(subvol->name, GF_LOG_WARNING, EIO, API_MSG_GET_CWD_FAILED, + NULL); errno = EIO; goto out; } @@ -640,6 +645,7 @@ out: return ret; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0) int priv_glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *origpath, loc_t *loc, struct iatt *iatt, int reval) @@ -650,7 +656,6 @@ priv_glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *origpath, return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0); int glfs_lresolve(struct glfs *fs, xlator_t *subvol, const char *origpath, @@ -680,28 +685,27 @@ glfs_migrate_fd_locks_safe(struct glfs *fs, xlator_t *oldsubvol, fd_t *oldfd, NULL, NULL); DECODE_SYNCOP_ERR(ret); if (ret < 0) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FGETXATTR_FAILED, - "fgetxattr (%s) failed (%s) on graph %s (%d)", - uuid_utoa_r(oldfd->inode->gfid, uuid1), strerror(errno), - graphid_str(oldsubvol), oldsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FGETXATTR_FAILED, + "gfid=%s", uuid_utoa_r(oldfd->inode->gfid, uuid1), "err=%s", + strerror(errno), "subvol=%s", graphid_str(oldsubvol), "id=%d", + oldsubvol->graph->id, NULL); goto out; } if (!dict_get(lockinfo, GF_XATTR_LOCKINFO_KEY)) { - gf_msg(fs->volname, GF_LOG_WARNING, 0, API_MSG_LOCKINFO_KEY_MISSING, - "missing lockinfo key (%s) on graph %s (%d)", - uuid_utoa_r(oldfd->inode->gfid, uuid1), graphid_str(oldsubvol), - oldsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, 0, API_MSG_LOCKINFO_KEY_MISSING, + "gfid=%s", uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s", + graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id, NULL); goto out; } ret = syncop_fsetxattr(newsubvol, newfd, lockinfo, 0, NULL, NULL); DECODE_SYNCOP_ERR(ret); if (ret < 0) { - gf_msg(fs->volname, GF_LOG_WARNING, 0, API_MSG_FSETXATTR_FAILED, - "fsetxattr (%s) failed (%s) on graph %s (%d)", - uuid_utoa_r(newfd->inode->gfid, uuid1), strerror(errno), - graphid_str(newsubvol), newsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, 0, API_MSG_FSETXATTR_FAILED, + "gfid=%s", uuid_utoa_r(newfd->inode->gfid, uuid1), "err=%s", + strerror(errno), "subvol=%s", graphid_str(newsubvol), "id=%d", + newsubvol->graph->id, NULL); goto out; } out: @@ -722,6 +726,7 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) 0, }; char uuid1[64]; + dict_t *xdata = NULL; oldinode = oldfd->inode; oldsubvol = oldinode->table->xl; @@ -730,32 +735,43 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) return fd_ref(oldfd); if (!oldsubvol->switched) { - ret = syncop_fsync(oldsubvol, oldfd, 0, NULL, NULL); + xdata = dict_new(); + if (!xdata || dict_set_int8(xdata, "last-fsync", 1)) { + gf_smsg(fs->volname, GF_LOG_WARNING, ENOMEM, API_MSG_FSYNC_FAILED, + "err=%s", "last-fsync set failed", "gfid=%s", + uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s", + graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id, + NULL); + } + + ret = syncop_fsync(oldsubvol, oldfd, 0, NULL, NULL, xdata, NULL); DECODE_SYNCOP_ERR(ret); if (ret) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FSYNC_FAILED, - "fsync() failed " - "(%s) on %s graph %s (%d)", - strerror(errno), uuid_utoa_r(oldfd->inode->gfid, uuid1), - graphid_str(oldsubvol), oldsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FSYNC_FAILED, + "err=%s", strerror(errno), "gfid=%s", + uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s", + graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id, + NULL); } } newinode = glfs_refresh_inode_safe(newsubvol, oldinode, _gf_false); if (!newinode) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_INODE_REFRESH_FAILED, - "inode (%s) refresh failed (%s) on graph %s (%d)", - uuid_utoa_r(oldinode->gfid, uuid1), strerror(errno), - graphid_str(newsubvol), newsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, + API_MSG_INODE_REFRESH_FAILED, "gfid=%s", + uuid_utoa_r(oldinode->gfid, uuid1), "err=%s", strerror(errno), + "subvol=%s", graphid_str(newsubvol), "id=%d", + newsubvol->graph->id, NULL); goto out; } newfd = fd_create(newinode, getpid()); if (!newfd) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FDCREATE_FAILED, - "fd_create (%s) failed (%s) on graph %s (%d)", - uuid_utoa_r(newinode->gfid, uuid1), strerror(errno), - graphid_str(newsubvol), newsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, + API_MSG_FDCREATE_FAILED_ON_GRAPH, "gfid=%s", + uuid_utoa_r(newinode->gfid, uuid1), "err=%s", strerror(errno), + "subvol=%s", graphid_str(newsubvol), "id=%d", + newsubvol->graph->id, NULL); goto out; } @@ -763,8 +779,7 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) ret = inode_path(oldfd->inode, NULL, (char **)&loc.path); if (ret < 0) { - gf_msg(fs->volname, GF_LOG_INFO, 0, API_MSG_INODE_PATH_FAILED, - "inode_path failed"); + gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_INODE_PATH_FAILED, NULL); goto out; } @@ -780,21 +795,21 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) loc_wipe(&loc); if (ret) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_SYNCOP_OPEN_FAILED, - "syncop_open%s (%s) failed (%s) on graph %s (%d)", - IA_ISDIR(oldinode->ia_type) ? "dir" : "", - uuid_utoa_r(newinode->gfid, uuid1), strerror(errno), - graphid_str(newsubvol), newsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_SYNCOP_OPEN_FAILED, + "type=%s", IA_ISDIR(oldinode->ia_type) ? "dir" : "", "gfid=%s", + uuid_utoa_r(newinode->gfid, uuid1), "err=%s", strerror(errno), + "subvol=%s", graphid_str(newsubvol), "id=%d", + newsubvol->graph->id, NULL); goto out; } ret = glfs_migrate_fd_locks_safe(fs, oldsubvol, oldfd, newsubvol, newfd); if (ret) { - gf_msg(fs->volname, GF_LOG_WARNING, errno, API_MSG_LOCK_MIGRATE_FAILED, - "lock migration (%s) failed (%s) on graph %s (%d)", - uuid_utoa_r(newinode->gfid, uuid1), strerror(errno), - graphid_str(newsubvol), newsubvol->graph->id); + gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_LOCK_MIGRATE_FAILED, + "gfid=%s", uuid_utoa_r(newinode->gfid, uuid1), "err=%s", + strerror(errno), "subvol=%s", graphid_str(newsubvol), "id=%d", + newsubvol->graph->id, NULL); goto out; } @@ -809,6 +824,9 @@ out: newfd = NULL; } + if (xdata) + dict_unref(xdata); + return newfd; } @@ -829,6 +847,9 @@ __glfs_migrate_fd(struct glfs *fs, xlator_t *newsubvol, struct glfs_fd *glfd) fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return newfd; } @@ -875,9 +896,9 @@ __glfs_migrate_openfds(struct glfs *fs, xlator_t *subvol) list_for_each_entry(glfd, &fs->openfds, openfds) { if (gf_uuid_is_null(glfd->fd->inode->gfid)) { - gf_msg(fs->volname, GF_LOG_INFO, 0, API_MSG_OPENFD_SKIPPED, - "skipping openfd %p/%p in graph %s (%d)", glfd, glfd->fd, - graphid_str(subvol), subvol->graph->id); + gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_OPENFD_SKIPPED, + "glfd=%p", glfd, "glfd->fd=%p", glfd->fd, "subvol=%s", + graphid_str(subvol), "id=%d", subvol->graph->id, NULL); /* create in progress, defer */ continue; } @@ -912,10 +933,10 @@ __glfs_active_subvol(struct glfs *fs) ret = __glfs_first_lookup(fs, new_subvol); if (ret) { - gf_msg(fs->volname, GF_LOG_INFO, errno, - API_MSG_FIRST_LOOKUP_GRAPH_FAILED, - "first lookup on graph %s (%d) failed (%s)", - graphid_str(new_subvol), new_subvol->graph->id, strerror(errno)); + gf_smsg(fs->volname, GF_LOG_INFO, errno, + API_MSG_FIRST_LOOKUP_GRAPH_FAILED, "subvol=%s", + graphid_str(new_subvol), "id=%d", new_subvol->graph->id, + "err=%s", strerror(errno), NULL); return NULL; } @@ -924,11 +945,11 @@ __glfs_active_subvol(struct glfs *fs) if (!new_cwd) { char buf1[64]; - gf_msg(fs->volname, GF_LOG_INFO, errno, - API_MSG_CWD_GRAPH_REF_FAILED, - "cwd refresh of %s graph %s (%d) failed (%s)", - uuid_utoa_r(fs->cwd->gfid, buf1), graphid_str(new_subvol), - new_subvol->graph->id, strerror(errno)); + gf_smsg(fs->volname, GF_LOG_INFO, errno, + API_MSG_CWD_GRAPH_REF_FAILED, "buf=%s", + uuid_utoa_r(fs->cwd->gfid, buf1), "subvol=%s", + graphid_str(new_subvol), "id=%d", new_subvol->graph->id, + "err=%s", strerror(errno), NULL); return NULL; } } @@ -949,13 +970,13 @@ __glfs_active_subvol(struct glfs *fs) inode_unref(new_cwd); } - gf_msg(fs->volname, GF_LOG_INFO, 0, API_MSG_SWITCHED_GRAPH, - "switched to graph %s (%d)", graphid_str(new_subvol), - new_subvol->graph->id); + gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_SWITCHED_GRAPH, "subvol=%s", + graphid_str(new_subvol), "id=%d", new_subvol->graph->id, NULL); return new_subvol; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0) void priv_glfs_subvol_done(struct glfs *fs, xlator_t *subvol) { @@ -983,8 +1004,7 @@ priv_glfs_subvol_done(struct glfs *fs, xlator_t *subvol) } } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0) xlator_t * priv_glfs_active_subvol(struct glfs *fs) { @@ -1012,8 +1032,6 @@ priv_glfs_active_subvol(struct glfs *fs) return subvol; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0); - int __glfs_cwd_set(struct glfs *fs, inode_t *inode) { diff --git a/api/src/glfs.c b/api/src/glfs.c index f009621d93b..b4bf1423f6d 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -34,17 +34,18 @@ #include <sys/prctl.h> #endif -#include "glusterfs.h" -#include "logging.h" -#include "stack.h" -#include "gf-event.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/logging.h> +#include <glusterfs/stack.h> +#include <glusterfs/gf-event.h> #include "glfs-mem-types.h" -#include "common-utils.h" -#include "syncop.h" -#include "call-stub.h" -#include "hashfn.h" +#include <glusterfs/common-utils.h> +#include <glusterfs/syncop.h> +#include <glusterfs/call-stub.h> +#include <glusterfs/hashfn.h> #include "rpc-clnt.h" -#include "statedump.h" +#include <glusterfs/statedump.h> +#include <glusterfs/syscall.h> #include "gfapi-messages.h" #include "glfs.h" @@ -68,8 +69,8 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) ret = xlator_mem_acct_init(THIS, glfs_mt_end + 1); if (ret != 0) { - gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED, - "Memory accounting init failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED, + NULL); return ret; } @@ -91,8 +92,8 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) goto err; } - ctx->event_pool = event_pool_new(DEFAULT_EVENT_POOL_SIZE, - STARTING_EVENT_THREADS); + ctx->event_pool = gf_event_pool_new(DEFAULT_EVENT_POOL_SIZE, + STARTING_EVENT_THREADS); if (!ctx->event_pool) { goto err; } @@ -188,23 +189,21 @@ create_master(struct glfs *fs) goto err; if (xlator_set_type(master, "mount/api") == -1) { - gf_msg("glfs", GF_LOG_ERROR, 0, API_MSG_MASTER_XLATOR_INIT_FAILED, - "master xlator " - "for %s initialization failed", - fs->volname); + gf_smsg("glfs", GF_LOG_ERROR, 0, API_MSG_MASTER_XLATOR_INIT_FAILED, + "name=%s", fs->volname, NULL); goto err; } master->ctx = fs->ctx; master->private = fs; - master->options = get_new_dict(); + master->options = dict_new(); if (!master->options) goto err; ret = xlator_init(master); if (ret) { - gf_msg("glfs", GF_LOG_ERROR, 0, API_MSG_GFAPI_XLATOR_INIT_FAILED, - "failed to initialize gfapi translator"); + gf_smsg("glfs", GF_LOG_ERROR, 0, API_MSG_GFAPI_XLATOR_INIT_FAILED, + NULL); goto err; } @@ -230,9 +229,8 @@ get_volfp(struct glfs *fs) cmd_args = &fs->ctx->cmd_args; if ((specfp = fopen(cmd_args->volfile, "r")) == NULL) { - gf_msg("glfs", GF_LOG_ERROR, errno, API_MSG_VOLFILE_OPEN_FAILED, - "volume file %s open failed: %s", cmd_args->volfile, - strerror(errno)); + gf_smsg("glfs", GF_LOG_ERROR, errno, API_MSG_VOLFILE_OPEN_FAILED, + "file=%s", cmd_args->volfile, "err=%s", strerror(errno), NULL); return NULL; } @@ -253,6 +251,11 @@ glfs_volumes_init(struct glfs *fs) if (!vol_assigned(cmd_args)) return -1; + if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) { + fs->ctx->secure_mgmt = 1; + fs->ctx->ssl_cert_depth = glusterfs_read_secure_access_file(); + } + if (cmd_args->volfile_server) { ret = glfs_mgmt_init(fs); goto out; @@ -261,8 +264,8 @@ glfs_volumes_init(struct glfs *fs) fp = get_volfp(fs); if (!fp) { - gf_msg("glfs", GF_LOG_ERROR, ENOENT, API_MSG_VOL_SPEC_FILE_ERROR, - "Cannot reach volume specification file"); + gf_smsg("glfs", GF_LOG_ERROR, ENOENT, API_MSG_VOL_SPEC_FILE_ERROR, + NULL); ret = -1; goto out; } @@ -277,6 +280,7 @@ out: /////////////////////////////////////////////////////////////////////////////// +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0) int pub_glfs_set_xlator_option(struct glfs *fs, const char *xlator, const char *key, const char *value) @@ -326,8 +330,7 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1) int pub_glfs_unset_volfile_server(struct glfs *fs, const char *transport, const char *host, const int port) @@ -368,6 +371,8 @@ pub_glfs_unset_volfile_server(struct glfs *fs, const char *transport, list_for_each_entry_safe(server, tmp, &cmd_args->curr_server->list, list) { + if (!server->volfile_server || !server->transport) + continue; if ((!strcmp(server->volfile_server, host) && !strcmp(server->transport, transport_val) && (server->port == port_val))) { @@ -385,8 +390,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0) int pub_glfs_set_volfile_server(struct glfs *fs, const char *transport, const char *host, int port) @@ -419,14 +423,11 @@ pub_glfs_set_volfile_server(struct glfs *fs, const char *transport, server_transport = gf_strdup(transport); } else if (!strcmp(transport, "rdma")) { server_transport = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT); - gf_msg("glfs", GF_LOG_WARNING, EINVAL, API_MSG_INVALID_ENTRY, - "transport RDMA is deprecated, " - "falling back to tcp"); + gf_smsg("glfs", GF_LOG_WARNING, EINVAL, API_MSG_TRANS_RDMA_DEP, + NULL); } else { - gf_msg("glfs", GF_LOG_TRACE, EINVAL, API_MSG_INVALID_ENTRY, - "transport %s is not supported, " - "possible values tcp|unix", - transport); + gf_smsg("glfs", GF_LOG_TRACE, EINVAL, API_MSG_TRANS_NOT_SUPPORTED, + "transport=%s", transport, NULL); goto out; } } else { @@ -468,8 +469,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0); - /* * * Used to free the arguments allocated by glfs_set_volfile_server() */ @@ -512,6 +511,7 @@ glfs_free_xlator_options(cmd_args_t *cmd_args) } } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2) int pub_glfs_setfsuid(uid_t fsuid) { @@ -521,8 +521,7 @@ pub_glfs_setfsuid(uid_t fsuid) return syncopctx_setfsuid(&fsuid); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2) int pub_glfs_setfsgid(gid_t fsgid) { @@ -532,8 +531,7 @@ pub_glfs_setfsgid(gid_t fsgid) return syncopctx_setfsgid(&fsgid); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2) int pub_glfs_setfsgroups(size_t size, const gid_t *list) { @@ -543,8 +541,7 @@ pub_glfs_setfsgroups(size_t size, const gid_t *list) return syncopctx_setfsgroups(size, list); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0) int pub_glfs_setfsleaseid(glfs_leaseid_t leaseid) { @@ -566,8 +563,6 @@ pub_glfs_setfsleaseid(glfs_leaseid_t leaseid) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0); - int get_fop_attr_glfd(dict_t **fop_attr, struct glfs_fd *glfd) { @@ -655,14 +650,19 @@ unset_fop_attr(dict_t **fop_attr) *fop_attr = NULL; } } + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0) struct glfs * pub_glfs_from_glfd(struct glfs_fd *glfd) { + if (glfd == NULL) { + errno = EBADF; + return NULL; + } + return glfd->fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0); - static void glfs_fd_destroy(struct glfs_fd *glfd) { @@ -724,7 +724,7 @@ glfs_poller(void *data) fs = data; - event_dispatch(fs->ctx->event_pool); + gf_event_dispatch(fs->ctx->event_pool); return NULL; } @@ -740,6 +740,7 @@ glfs_new_fs(const char *volname) INIT_LIST_HEAD(&fs->openfds); INIT_LIST_HEAD(&fs->upcall_list); + INIT_LIST_HEAD(&fs->waitq); PTHREAD_MUTEX_INIT(&fs->mutex, NULL, fs->pthread_flags, GLFS_INIT_MUTEX, err); @@ -810,27 +811,45 @@ unlock: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0) struct glfs * pub_glfs_new(const char *volname) { + if (!volname) { + errno = EINVAL; + return NULL; + } + struct glfs *fs = NULL; + int i = 0; int ret = -1; glusterfs_ctx_t *ctx = NULL; xlator_t *old_THIS = NULL; char pname[16] = ""; char msg[32] = ""; - if (!volname) { + if (volname[0] == '/' || volname[0] == '-') { + if (strncmp(volname, "/snaps/", 7) == 0) { + goto label; + } errno = EINVAL; return NULL; } + for (i = 0; i < strlen(volname); i++) { + if (!isalnum(volname[i]) && (volname[i] != '_') && + (volname[i] != '-')) { + errno = EINVAL; + return NULL; + } + } + +label: /* * Do this as soon as possible in case something else depends on * pool allocations. */ - mem_pools_init_early(); - mem_pools_init_late(); + mem_pools_init(); fs = glfs_new_fs(volname); if (!fs) @@ -899,8 +918,7 @@ out: return fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0) struct glfs * priv_glfs_new_from_ctx(glusterfs_ctx_t *ctx) { @@ -919,8 +937,7 @@ out: return fs; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0) void priv_glfs_free_from_ctx(struct glfs *fs) { @@ -956,8 +973,7 @@ priv_glfs_free_from_ctx(struct glfs *fs) FREE(fs); } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0) int pub_glfs_set_volfile(struct glfs *fs, const char *volfile) { @@ -974,8 +990,7 @@ pub_glfs_set_volfile(struct glfs *fs, const char *volfile) return 0; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0) int pub_glfs_set_logging(struct glfs *fs, const char *logfile, int loglevel) { @@ -1013,8 +1028,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0); - int glfs_init_wait(struct glfs *fs) { @@ -1033,14 +1046,14 @@ glfs_init_wait(struct glfs *fs) return ret; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0) void priv_glfs_init_done(struct glfs *fs, int ret) { glfs_init_cbk init_cbk; if (!fs) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_GLFS_FSOBJ_NULL, - "fs is NULL"); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_GLFS_FSOBJ_NULL, NULL); goto out; } @@ -1064,8 +1077,6 @@ out: return; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0); - int glfs_init_common(struct glfs *fs) { @@ -1093,8 +1104,7 @@ glfs_init_async(struct glfs *fs, glfs_init_cbk cbk) int ret = -1; if (!fs || !fs->ctx) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "fs is not properly initialized."); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_FS_NOT_INIT, NULL); errno = EINVAL; return ret; } @@ -1106,6 +1116,7 @@ glfs_init_async(struct glfs *fs, glfs_init_cbk cbk) return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0) int pub_glfs_init(struct glfs *fs) { @@ -1114,8 +1125,7 @@ pub_glfs_init(struct glfs *fs) DECLARE_OLD_THIS; if (!fs || !fs->ctx) { - gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY, - "fs is not properly initialized."); + gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_FS_NOT_INIT, NULL); errno = EINVAL; return ret; } @@ -1139,8 +1149,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0); - static int glusterfs_ctx_destroy(glusterfs_ctx_t *ctx) { @@ -1189,7 +1197,7 @@ glusterfs_ctx_destroy(glusterfs_ctx_t *ctx) } /* Free the event pool */ - ret = event_pool_destroy(ctx->event_pool); + ret = gf_event_pool_destroy(ctx->event_pool); /* Free the iobuf pool */ iobuf_pool_destroy(ctx->iobuf_pool); @@ -1212,11 +1220,13 @@ glusterfs_ctx_destroy(glusterfs_ctx_t *ctx) glusterfs_graph_destroy_residual(trav_graph); } + GF_FREE(ctx->statedump_path); FREE(ctx); return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0) int pub_glfs_fini(struct glfs *fs) { @@ -1228,24 +1238,35 @@ pub_glfs_fini(struct glfs *fs) call_pool_t *call_pool = NULL; int fs_init = 0; int err = -1; + struct synctask *waittask = NULL; DECLARE_OLD_THIS; - __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + if (!fs) { + errno = EINVAL; + goto invalid_fs; + } ctx = fs->ctx; if (!ctx) { goto free_fs; } + THIS = fs->ctx->master; + if (ctx->mgmt) { rpc_clnt_disable(ctx->mgmt); - rpc_clnt_unref(ctx->mgmt); - ctx->mgmt = NULL; } call_pool = fs->ctx->pool; + /* Wake up any suspended synctasks */ + while (!list_empty(&fs->waitq)) { + waittask = list_entry(fs->waitq.next, struct synctask, waitq); + list_del_init(&waittask->waitq); + synctask_wake(waittask); + } + while (countdown--) { /* give some time for background frames to finish */ pthread_mutex_lock(&fs->mutex); @@ -1264,7 +1285,7 @@ pub_glfs_fini(struct glfs *fs) } } pthread_mutex_unlock(&fs->mutex); - usleep(100000); + gf_nanosleep(100000 * GF_US_IN_NS); } /* leaked frames may exist, we ignore */ @@ -1297,10 +1318,8 @@ pub_glfs_fini(struct glfs *fs) graph = subvol->graph; err = pthread_mutex_lock(&fs->mutex); if (err != 0) { - gf_msg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_LOCK_FAILED, - "pthread lock on glfs mutex, " - "returned error: (%s)", - strerror(err)); + gf_smsg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_LOCK_FAILED, + "error=%s", strerror(err), NULL); goto fail; } /* check and wait for CHILD_DOWN for active subvol*/ @@ -1308,19 +1327,17 @@ pub_glfs_fini(struct glfs *fs) while (graph->used) { err = pthread_cond_wait(&fs->child_down_cond, &fs->mutex); if (err != 0) - gf_msg("glfs", GF_LOG_INFO, err, - API_MSG_COND_WAIT_FAILED, - "%s cond wait failed %s", subvol->name, - strerror(err)); + gf_smsg("glfs", GF_LOG_INFO, err, + API_MSG_COND_WAIT_FAILED, "name=%s", + subvol->name, "err=%s", strerror(err), NULL); } } err = pthread_mutex_unlock(&fs->mutex); if (err != 0) { - gf_msg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_UNLOCK_FAILED, - "pthread unlock on glfs mutex, " - "returned error: (%s)", - strerror(err)); + gf_smsg("glfs", GF_LOG_ERROR, err, + API_MSG_FSMUTEX_UNLOCK_FAILED, "error=%s", + strerror(err), NULL); goto fail; } } @@ -1355,10 +1372,17 @@ pub_glfs_fini(struct glfs *fs) syncenv_destroy(ctx->env); /* Join the poller thread */ - if (event_dispatch_destroy(ctx->event_pool) < 0) + if (gf_event_dispatch_destroy(ctx->event_pool) < 0) ret = -1; } + /* Avoid dispatching events to mgmt after freed, + * unreference mgmt after the event_dispatch_destroy */ + if (ctx->mgmt) { + rpc_clnt_unref(ctx->mgmt); + ctx->mgmt = NULL; + } + /* log infra has to be brought down before destroying * timer registry, as logging uses timer infra */ @@ -1393,8 +1417,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0) ssize_t pub_glfs_get_volfile(struct glfs *fs, void *buf, size_t len) { @@ -1420,8 +1443,7 @@ invalid_fs: return res; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0) int priv_glfs_ipc(struct glfs *fs, int opcode, void *xd_in, void **xd_out) { @@ -1449,107 +1471,118 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0); +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_setfspid, 6.1) +int +priv_glfs_setfspid(struct glfs *fs, pid_t pid) +{ + cmd_args_t *cmd_args = NULL; + int ret = 0; + + cmd_args = &fs->ctx->cmd_args; + cmd_args->client_pid = pid; + cmd_args->client_pid_set = 1; + ret = syncopctx_setfspid(&pid); + + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16) void pub_glfs_free(void *ptr) { GLFS_FREE(ptr); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16) struct glfs * pub_glfs_upcall_get_fs(struct glfs_upcall *arg) { return arg->fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16) enum glfs_upcall_reason pub_glfs_upcall_get_reason(struct glfs_upcall *arg) { return arg->reason; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16) void * pub_glfs_upcall_get_event(struct glfs_upcall *arg) { return arg->event; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_object(struct glfs_upcall_inode *arg) { return arg->object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16) uint64_t pub_glfs_upcall_inode_get_flags(struct glfs_upcall_inode *arg) { return arg->flags; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_stat(struct glfs_upcall_inode *arg) { return &arg->buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16) uint64_t pub_glfs_upcall_inode_get_expire(struct glfs_upcall_inode *arg) { return arg->expire_time_attr; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_pobject(struct glfs_upcall_inode *arg) { return arg->p_object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_pstat(struct glfs_upcall_inode *arg) { return &arg->p_buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_oldpobject(struct glfs_upcall_inode *arg) { return arg->oldp_object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_oldpstat(struct glfs_upcall_inode *arg) { return &arg->oldp_buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6) struct glfs_object * pub_glfs_upcall_lease_get_object(struct glfs_upcall_lease *arg) { - return arg->object; + return arg->object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6) uint32_t pub_glfs_upcall_lease_get_lease_type(struct glfs_upcall_lease *arg) { return arg->lease_type; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6); /* definitions of the GLFS_SYSRQ_* chars are in glfs.h */ static struct glfs_sysrq_help { @@ -1559,6 +1592,7 @@ static struct glfs_sysrq_help { {GLFS_SYSRQ_STATEDUMP, "(S)tatedump"}, {0, NULL}}; +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0) int pub_glfs_sysrq(struct glfs *fs, char sysrq) { @@ -1598,8 +1632,8 @@ pub_glfs_sysrq(struct glfs *fs, char sysrq) gf_proc_dump_info(SIGUSR1, ctx); break; default: - gf_msg("glfs", GF_LOG_ERROR, ENOTSUP, API_MSG_INVALID_ENTRY, - "'%c' is not a valid sysrq", sysrq); + gf_smsg("glfs", GF_LOG_ERROR, ENOTSUP, API_MSG_INVALID_SYSRQ, + "sysrq=%c", sysrq, NULL); errno = ENOTSUP; ret = -1; } @@ -1607,8 +1641,7 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0) int pub_glfs_upcall_register(struct glfs *fs, uint32_t event_list, glfs_upcall_cbk cbk, void *data) @@ -1630,8 +1663,8 @@ pub_glfs_upcall_register(struct glfs *fs, uint32_t event_list, if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) { errno = EINVAL; ret = -1; - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, - "invalid event_list (0x%08x)", event_list); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG, + "event_list=(0x%08x)", event_list, NULL); goto out; } @@ -1664,8 +1697,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0) int pub_glfs_upcall_unregister(struct glfs *fs, uint32_t event_list) { @@ -1683,8 +1715,8 @@ pub_glfs_upcall_unregister(struct glfs *fs, uint32_t event_list) if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) { errno = EINVAL; ret = -1; - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, - "invalid event_list (0x%08x)", event_list); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG, + "event_list=(0x%08x)", event_list, NULL); goto out; } @@ -1712,4 +1744,63 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_statedump_path, 7.0) +int +pub_glfs_set_statedump_path(struct glfs *fs, const char *path) +{ + struct stat st; + int ret; + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + + if (!path) { + gf_log("glfs", GF_LOG_ERROR, "path is NULL"); + errno = EINVAL; + goto err; + } + + /* If path is not present OR, if it is directory AND has enough permission + * to create files, then proceed */ + ret = sys_stat(path, &st); + if (ret && errno != ENOENT) { + gf_log("glfs", GF_LOG_ERROR, "%s: not a valid path (%s)", path, + strerror(errno)); + errno = EINVAL; + goto err; + } + + if (!ret) { + /* file is present, now check other things */ + if (!S_ISDIR(st.st_mode)) { + gf_log("glfs", GF_LOG_ERROR, "%s: path is not directory", path); + errno = EINVAL; + goto err; + } + if (sys_access(path, W_OK | X_OK) < 0) { + gf_log("glfs", GF_LOG_ERROR, + "%s: path doesn't have write permission", path); + errno = EPERM; + goto err; + } + } + + /* If set, it needs to be freed, so we don't have leak */ + GF_FREE(fs->ctx->statedump_path); + + fs->ctx->statedump_path = gf_strdup(path); + if (!fs->ctx->statedump_path) { + gf_log("glfs", GF_LOG_ERROR, + "%s: failed to set statedump path, no memory", path); + errno = ENOMEM; + goto err; + } + + __GLFS_EXIT_FS; + + return 0; +err: + __GLFS_EXIT_FS; + +invalid_fs: + return -1; +} diff --git a/api/src/glfs.h b/api/src/glfs.h index ba57244f87f..279d11d58ee 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -20,6 +20,17 @@ both the library and the application. */ +/* Values for valid flags to be used when using XXXsetattr, to set multiple + attribute values passed via the related stat structure. + */ + +#define GFAPI_SET_ATTR_MODE 0x1 +#define GFAPI_SET_ATTR_UID 0x2 +#define GFAPI_SET_ATTR_GID 0x4 +#define GFAPI_SET_ATTR_SIZE 0x8 +#define GFAPI_SET_ATTR_ATIME 0x10 +#define GFAPI_SET_ATTR_MTIME 0x20 + #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif @@ -40,7 +51,40 @@ #include <sys/cdefs.h> #include <dirent.h> #include <sys/statvfs.h> -#include <inttypes.h> +#include <stdint.h> +#include <sys/time.h> + +/* + * For off64_t to be defined, we need both + * __USE_LARGEFILE64 to be true and __off64_t_defnined to be + * false. But, making __USE_LARGEFILE64 true causes other issues + * such as redinition of stat and fstat to stat64 and fstat64 + * respectively which again causes compilation issues. + * Without off64_t being defined, this will not compile as + * copy_file_range uses off64_t. Hence define it here. First + * check whether __off64_t_defined is true or not. <unistd.h> + * sets that flag when it defines off64_t. If __off64_t_defined + * is false and __USE_FILE_OFFSET64 is true, then go on to define + * off64_t using __off64_t. + */ +#ifndef GF_BSD_HOST_OS +#if defined(__USE_FILE_OFFSET64) && !defined(__off64_t_defined) +typedef __off64_t off64_t; +#endif /* defined(__USE_FILE_OFFSET64) && !defined(__off64_t_defined) */ +#else +#include <stdio.h> +#ifndef _OFF64_T_DECLARED +/* + * Including <stdio.h> (done above) should actually define + * _OFF64_T_DECLARED with off64_t data type being available + * for consumption. But, off64_t data type is not recognizable + * for FreeBSD versions less than 11. Hence, int64_t is typedefed + * to off64_t. + */ +#define _OFF64_T_DECLARED +typedef int64_t off64_t; +#endif /* _OFF64_T_DECLARED */ +#endif /* GF_BSD_HOST_OS */ #if defined(HAVE_SYS_ACL_H) || (defined(USE_POSIX_ACLS) && USE_POSIX_ACLS) #include <sys/acl.h> @@ -371,6 +415,116 @@ glfs_get_volumeid(glfs_t *fs, char *volid, size_t size) __THROW struct glfs_fd; typedef struct glfs_fd glfs_fd_t; +/* + * Mask for request/result items in the struct glfs_stat. + * + * Query request/result mask for glfs_stat() (family of functions) and + * struct glfs_stat::glfs_st_mask. + * + * These bits should be set in the mask argument of glfs_stat() (family of + * functions) to request particular items when calling glfs_stat(). + * + * NOTE: Lower order 32 bits are used to reflect statx(2) bits. For Gluster + * specific attrs/extensions, use higher order 32 bits. + * + */ +#define GLFS_STAT_TYPE 0x0000000000000001U /* Want/got stx_mode & S_IFMT */ +#define GLFS_STAT_MODE 0x0000000000000002U /* Want/got stx_mode & ~S_IFMT */ +#define GLFS_STAT_NLINK 0x0000000000000004U /* Want/got stx_nlink */ +#define GLFS_STAT_UID 0x0000000000000008U /* Want/got stx_uid */ +#define GLFS_STAT_GID 0x0000000000000010U /* Want/got stx_gid */ +#define GLFS_STAT_ATIME 0x0000000000000020U /* Want/got stx_atime */ +#define GLFS_STAT_MTIME 0x0000000000000040U /* Want/got stx_mtime */ +#define GLFS_STAT_CTIME 0x0000000000000080U /* Want/got stx_ctime */ +#define GLFS_STAT_INO 0x0000000000000100U /* Want/got stx_ino */ +#define GLFS_STAT_SIZE 0x0000000000000200U /* Want/got stx_size */ +#define GLFS_STAT_BLOCKS 0x0000000000000400U /* Want/got stx_blocks */ +#define GLFS_STAT_BASIC_STATS \ + 0x00000000000007ffU /* Items in the normal stat struct */ +#define GLFS_STAT_BTIME 0x0000000000000800U /* Want/got stx_btime */ +#define GLFS_STAT_ALL 0x0000000000000fffU /* All currently supported flags */ +#define GLFS_STAT_RESERVED \ + 0x8000000000000000U /* Reserved to denote future expansion */ + +/* Macros for checking validity of struct glfs_stat members.*/ +#define GLFS_STAT_TYPE_VALID(stmask) (stmask & GLFS_STAT_TYPE) +#define GLFS_STAT_MODE_VALID(stmask) (stmask & GLFS_STAT_MODE) +#define GLFS_STAT_NLINK_VALID(stmask) (stmask & GLFS_STAT_NLINK) +#define GLFS_STAT_UID_VALID(stmask) (stmask & GLFS_STAT_UID) +#define GLFS_STAT_GID_VALID(stmask) (stmask & GLFS_STAT_GID) +#define GLFS_STAT_ATIME_VALID(stmask) (stmask & GLFS_STAT_ATIME) +#define GLFS_STAT_MTIME_VALID(stmask) (stmask & GLFS_STAT_MTIME) +#define GLFS_STAT_CTIME_VALID(stmask) (stmask & GLFS_STAT_CTIME) +#define GLFS_STAT_INO_VALID(stmask) (stmask & GLFS_STAT_INO) +#define GLFS_STAT_SIZE_VALID(stmask) (stmask & GLFS_STAT_SIZE) +#define GLFS_STAT_BLOCKS_VALID(stmask) (stmask & GLFS_STAT_BLOCKS) +#define GLFS_STAT_BTIME_VALID(stmask) (stmask & GLFS_STAT_BTIME) +#define GLFS_STAT_GFID_VALID(stmask) (stmask & GLFS_STAT_GFID) + +/* + * Attributes to be found in glfs_st_attributes and masked in + * glfs_st_attributes_mask. + * + * These give information about the features or the state of a file that might + * be of use to programs. + * + * NOTE: Lower order 32 bits are used to reflect statx(2) attribute bits. For + * Gluster specific attrs, use higher order 32 bits. + * + * NOTE: We do not support any file attributes or state as yet! + */ +#define GLFS_STAT_ATTR_RESERVED \ + 0x8000000000000000U /* Reserved to denote future expansion */ + +/* Extended file attribute structure. + * + * The caller passes a mask of what they're specifically interested in as a + * parameter to glfs_stat(). What glfs_stat() actually got will be indicated + * in glfs_st_mask upon return. + * + * For each bit in the mask argument: + * + * - if the datum is not supported: + * + * - the bit will be cleared, and + * + * - the datum value is undefined + * + * - otherwise, if explicitly requested: + * + * - the field will be filled in and the bit will be set; + * + * - otherwise, if not requested, but available in, it will be filled in + * anyway, and the bit will be set upon return; + * + * - otherwise the field and the bit will be cleared before returning. + * + */ + +struct glfs_stat { + uint64_t glfs_st_mask; /* What results were written [uncond] */ + uint64_t glfs_st_attributes; /* Flags conveying information about the file + [uncond] */ + uint64_t glfs_st_attributes_mask; /* Mask to show what's supported in + st_attributes [ucond] */ + struct timespec glfs_st_atime; /* Last access time */ + struct timespec glfs_st_btime; /* File creation time */ + struct timespec glfs_st_ctime; /* Last attribute change time */ + struct timespec glfs_st_mtime; /* Last data modification time */ + ino_t glfs_st_ino; /* Inode number */ + off_t glfs_st_size; /* File size */ + blkcnt_t glfs_st_blocks; /* Number of 512-byte blocks allocated */ + uint32_t glfs_st_rdev_major; /* Device ID of special file [if bdev/cdev] */ + uint32_t glfs_st_rdev_minor; + uint32_t glfs_st_dev_major; /* ID of device containing file [uncond] */ + uint32_t glfs_st_dev_minor; + blksize_t glfs_st_blksize; /* Preferred general I/O size [uncond] */ + nlink_t glfs_st_nlink; /* Number of hard links */ + uid_t glfs_st_uid; /* User ID of owner */ + gid_t glfs_st_gid; /* Group ID of owner */ + mode_t glfs_st_mode; /* File mode */ +}; + #define GLFS_LEASE_ID_SIZE 16 /* 128bits */ typedef char glfs_leaseid_t[GLFS_LEASE_ID_SIZE]; @@ -504,9 +658,14 @@ glfs_set_xlator_option(glfs_t *fs, const char *xlator, const char *key, time of issuing the async IO call. This can be used by the caller to differentiate different instances of the async requests in a common callback function. + + @prestat and @poststat are allocated on the stack, that are auto destroyed + post the callback function returns. */ -typedef void (*glfs_io_cbk)(glfs_fd_t *fd, ssize_t ret, void *data); +typedef void (*glfs_io_cbk)(glfs_fd_t *fd, ssize_t ret, + struct glfs_stat *prestat, + struct glfs_stat *poststat, void *data); // glfs_{read,write}[_async] @@ -521,12 +680,12 @@ glfs_write(glfs_fd_t *fd, const void *buf, size_t count, int flags) __THROW int glfs_read_async(glfs_fd_t *fd, void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_read_async, 3.4.0); + GFAPI_PUBLIC(glfs_read_async, 6.0); int glfs_write_async(glfs_fd_t *fd, const void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_write_async, 3.4.0); + GFAPI_PUBLIC(glfs_write_async, 6.0); // glfs_{read,write}v[_async] @@ -541,32 +700,33 @@ glfs_writev(glfs_fd_t *fd, const struct iovec *iov, int iovcnt, int glfs_readv_async(glfs_fd_t *fd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_readv_async, 3.4.0); + GFAPI_PUBLIC(glfs_readv_async, 6.0); int glfs_writev_async(glfs_fd_t *fd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_writev_async, 3.4.0); + GFAPI_PUBLIC(glfs_writev_async, 6.0); // glfs_p{read,write}[_async] ssize_t -glfs_pread(glfs_fd_t *fd, void *buf, size_t count, off_t offset, - int flags) __THROW GFAPI_PUBLIC(glfs_pread, 3.4.0); +glfs_pread(glfs_fd_t *fd, void *buf, size_t count, off_t offset, int flags, + struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_pread, 6.0); ssize_t glfs_pwrite(glfs_fd_t *fd, const void *buf, size_t count, off_t offset, - int flags) __THROW GFAPI_PUBLIC(glfs_pwrite, 3.4.0); + int flags, struct glfs_stat *prestat, + struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_pwrite, 6.0); int glfs_pread_async(glfs_fd_t *fd, void *buf, size_t count, off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_pread_async, 3.4.0); + GFAPI_PUBLIC(glfs_pread_async, 6.0); int glfs_pwrite_async(glfs_fd_t *fd, const void *buf, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_pwrite_async, 3.4.0); + GFAPI_PUBLIC(glfs_pwrite_async, 6.0); // glfs_p{read,write}v[_async] @@ -581,29 +741,38 @@ glfs_pwritev(glfs_fd_t *fd, const struct iovec *iov, int iovcnt, off_t offset, int glfs_preadv_async(glfs_fd_t *fd, const struct iovec *iov, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_preadv_async, 3.4.0); + GFAPI_PUBLIC(glfs_preadv_async, 6.0); int glfs_pwritev_async(glfs_fd_t *fd, const struct iovec *iov, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_pwritev_async, 3.4.0); + GFAPI_PUBLIC(glfs_pwritev_async, 6.0); off_t glfs_lseek(glfs_fd_t *fd, off_t offset, int whence) __THROW GFAPI_PUBLIC(glfs_lseek, 3.4.0); +ssize_t +glfs_copy_file_range(struct glfs_fd *glfd_in, off64_t *off_in, + struct glfs_fd *glfd_out, off64_t *off_out, size_t len, + unsigned int flags, struct glfs_stat *statbuf, + struct glfs_stat *prestat, + struct glfs_stat *poststat) __THROW + GFAPI_PUBLIC(glfs_copy_file_range, 6.0); + int glfs_truncate(glfs_t *fs, const char *path, off_t length) __THROW GFAPI_PUBLIC(glfs_truncate, 3.7.15); int -glfs_ftruncate(glfs_fd_t *fd, off_t length) __THROW - GFAPI_PUBLIC(glfs_ftruncate, 3.4.0); +glfs_ftruncate(glfs_fd_t *fd, off_t length, struct glfs_stat *prestat, + struct glfs_stat *poststat) __THROW + GFAPI_PUBLIC(glfs_ftruncate, 6.0); int glfs_ftruncate_async(glfs_fd_t *fd, off_t length, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_ftruncate_async, 3.4.0); + GFAPI_PUBLIC(glfs_ftruncate_async, 6.0); int glfs_lstat(glfs_t *fs, const char *path, struct stat *buf) __THROW @@ -618,18 +787,21 @@ glfs_fstat(glfs_fd_t *fd, struct stat *buf) __THROW GFAPI_PUBLIC(glfs_fstat, 3.4.0); int -glfs_fsync(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_fsync, 3.4.0); +glfs_fsync(glfs_fd_t *fd, struct glfs_stat *prestat, + struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_fsync, 6.0); int glfs_fsync_async(glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_fsync_async, 3.4.0); + GFAPI_PUBLIC(glfs_fsync_async, 6.0); int -glfs_fdatasync(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_fdatasync, 3.4.0); +glfs_fdatasync(glfs_fd_t *fd, struct glfs_stat *prestat, + struct glfs_stat *poststat) __THROW + GFAPI_PUBLIC(glfs_fdatasync, 6.0); int glfs_fdatasync_async(glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW - GFAPI_PUBLIC(glfs_fdatasync_async, 3.4.0); + GFAPI_PUBLIC(glfs_fdatasync_async, 6.0); int glfs_access(glfs_t *fs, const char *path, int mode) __THROW @@ -811,7 +983,7 @@ glfs_discard(glfs_fd_t *fd, off_t offset, size_t len) __THROW int glfs_discard_async(glfs_fd_t *fd, off_t length, size_t lent, glfs_io_cbk fn, - void *data) __THROW GFAPI_PUBLIC(glfs_discard_async, 3.5.0); + void *data) __THROW GFAPI_PUBLIC(glfs_discard_async, 6.0); int glfs_zerofill(glfs_fd_t *fd, off_t offset, off_t len) __THROW @@ -819,8 +991,7 @@ glfs_zerofill(glfs_fd_t *fd, off_t offset, off_t len) __THROW int glfs_zerofill_async(glfs_fd_t *fd, off_t length, off_t len, glfs_io_cbk fn, - void *data) __THROW - GFAPI_PUBLIC(glfs_zerofill_async, 3.5.0); + void *data) __THROW GFAPI_PUBLIC(glfs_zerofill_async, 6.0); char * glfs_getcwd(glfs_t *fs, char *buf, size_t size) __THROW @@ -1233,5 +1404,82 @@ int glfs_lease(glfs_fd_t *glfd, glfs_lease_t *lease, glfs_recall_cbk fn, void *data) __THROW GFAPI_PUBLIC(glfs_lease, 4.0.0); +/* + SYNOPSIS + + glfs_fsetattr: Function to set attributes. + glfs_setattr: Function to set attributes + + DESCRIPTION + + The functions are used to set attributes on the file. + + PARAMETERS + + @glfs_fsetattr + + @glfd: The fd of the file for which the attributes are to be set, + this fd is returned by glfs_open/glfs_create. + + @glfs_setattr + + @fs: File object. + + @path: The path of the file that is being operated on. + + @follow: Flag used to resolve symlink. + + + @stat: Struct that has information about the file. + + @valid: This is the mask bit, that accepts GFAPI_SET_ATTR* masks. + Refer glfs.h to see the mask definitions. + + Both functions are similar in functionality, just that the + func setattr() uses file path whereas the func fsetattr() + uses the fd. + + RETURN VALUES + 0: Successful completion + <0: Failure. @errno will be set with the type of failure + + */ + +int +glfs_fsetattr(struct glfs_fd *glfd, struct glfs_stat *stat) __THROW + GFAPI_PUBLIC(glfs_fsetattr, 6.0); + +int +glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat, + int follow) __THROW GFAPI_PUBLIC(glfs_setattr, 6.0); + +/* + SYNOPSIS + + glfs_set_statedump_path: Function to set statedump path. + + DESCRIPTION + + This function is used to set statedump directory + + PARAMETERS + + @fs: The 'virtual mount' object to be configured with the volume + specification file. + + @path: statedump path. Should be a directory. But the API won't fail if the + directory doesn't exist yet, as one may create it later. + + RETURN VALUES + + 0 : Success. + -1 : Failure. @errno will be set with the type of failure. + + */ + +int +glfs_set_statedump_path(struct glfs *fs, const char *path) __THROW + GFAPI_PUBLIC(glfs_set_statedump_path, 7.0); + __END_DECLS #endif /* !_GLFS_H */ |
