The branch, v4-17-stable has been updated via e6294461ad1 VERSION: Disable GIT_SNAPSHOT for the 4.17.0rc4 release. via a7d399a32cd WHATSNEW: Add release notes for Samba 4.17.0rc4. via ffe95221aab vfs_glusterfs: Implement SMB_VFS_FSTATAT via d5831b0f098 vfs_glusterfs: Use glfs_fgetxattr() for SMB_VFS_GET_REAL_FILENAME_AT via 9d11c39a2b8 vfs_glusterfs: Use glfs_readlinkat() for SMB_VFS_READ_DFS_PATHAT via 5e26c570b7c vfs_glusterfs: Use glfs_symlinkat() for SMB_VFS_CREATE_DFS_PATHAT via 5e155ea4505 vfs_glusterfs: Use glfs_mknodat() for SMB_VFS_MKNODAT via 1d74f92deb4 vfs_glusterfs: Use glfs_linkat() for SMB_VFS_LINKAT via 894338eddbb vfs_glusterfs: Use glfs_readlinkat() for SMB_VFS_READLINKAT via 41eb80482b3 vfs_glusterfs: Use glfs_symlinkat() for SMB_VFS_SYMLINKAT via c9b0459a175 vfs_glusterfs: Use glfs_unlinkat() for SMB_VFS_UNLINKAT via 618c868642d vfs_glusterfs: Use glfs_renameat() for SMB_VFS_RENAMEAT via a41e308cf08 vfs_glusterfs: Use glfs_mkdirat() for SMB_VFS_MKDIRAT via e0375100d79 vfs_glusterfs: Use glfs_openat() for SMB_VFS_OPENAT via a8eab509154 source3/wscript: Detect glusterfs-api with *at() calls support via 9f04cb8f58d vfs_glusterfs: Accept fsp with const qualifier via fbd69dab91c VERSION: Bump version up to Samba 4.17.0rc4... from c15dfcca9f5 VERSION: Disable GIT_SNAPSHOT for the 4.17.0rc3 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-17-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 9 +- source3/modules/vfs_glusterfs.c | 438 ++++++++++++++++++++++++++++++++-------- source3/wscript | 4 + 4 files changed, 372 insertions(+), 81 deletions(-) Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index beafce89da7..6dd9eb383e4 100644 --- a/VERSION +++ b/VERSION @@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=3 +SAMBA_VERSION_RC_RELEASE=4 ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 63c5fe09a90..3591b8a4306 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,7 +1,7 @@ Release Announcements ===================== -This is the third release candidate of Samba 4.17. This is *not* +This is the fourth release candidate of Samba 4.17. This is *not* intended for production environments and is designed for testing purposes only. Please report any defects via the Samba bug reporting system at https://bugzilla.samba.org/. @@ -206,6 +206,13 @@ smb.conf changes nt hash store New parameter always volume serial number New parameter -1 +CHANGES SINCE 4.17.0rc3 +======================= + +o Anoop C S <anoo...@samba.org> + * BUG 15157: Make use of glfs_*at() API calls in vfs_glusterfs. + + CHANGES SINCE 4.17.0rc2 ======================= diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index dd05da0f9bb..e2f9fbd8bd4 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -606,7 +606,7 @@ static uint32_t vfs_gluster_fs_capabilities(struct vfs_handle_struct *handle, } static glfs_fd_t *vfs_gluster_fetch_glfd(struct vfs_handle_struct *handle, - files_struct *fsp) + const files_struct *fsp) { glfs_fd_t **glfd = (glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); if (glfd == NULL) { @@ -737,9 +737,24 @@ static int vfs_gluster_mkdirat(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) { - struct smb_filename *full_fname = NULL; int ret; +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *pglfd = NULL; + + START_PROFILE(syscall_mkdirat); + + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_mkdirat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_mkdirat(pglfd, smb_fname->base_name, mode); +#else + struct smb_filename *full_fname = NULL; + START_PROFILE(syscall_mkdirat); full_fname = full_path_from_dirfsp_atname(talloc_tos(), @@ -753,6 +768,7 @@ static int vfs_gluster_mkdirat(struct vfs_handle_struct *handle, ret = glfs_mkdir(handle->data, full_fname->base_name, mode); TALLOC_FREE(full_fname); +#endif END_PROFILE(syscall_mkdirat); @@ -765,9 +781,12 @@ static int vfs_gluster_openat(struct vfs_handle_struct *handle, files_struct *fsp, const struct vfs_open_how *how) { - struct smb_filename *name = NULL; + int flags = how->flags; + struct smb_filename *full_fname = NULL; + bool have_opath = false; bool became_root = false; glfs_fd_t *glfd; + glfs_fd_t *pglfd = NULL; glfs_fd_t **p_tmp; START_PROFILE(syscall_openat); @@ -778,58 +797,103 @@ static int vfs_gluster_openat(struct vfs_handle_struct *handle, return -1; } - /* - * Looks like glfs API doesn't have openat(). - */ - if (fsp_get_pathref_fd(dirfsp) != AT_FDCWD) { - name = full_path_from_dirfsp_atname(talloc_tos(), - dirfsp, - smb_fname); - if (name == NULL) { - END_PROFILE(syscall_openat); - return -1; - } - smb_fname = name; - } - p_tmp = VFS_ADD_FSP_EXTENSION(handle, fsp, glfs_fd_t *, NULL); if (p_tmp == NULL) { - TALLOC_FREE(name); END_PROFILE(syscall_openat); errno = ENOMEM; return -1; } +#ifdef O_PATH + have_opath = true; if (fsp->fsp_flags.is_pathref) { - /* - * ceph doesn't support O_PATH so we have to fallback to - * become_root(). - */ + flags |= O_PATH; + } +#endif + + full_fname = full_path_from_dirfsp_atname(talloc_tos(), + dirfsp, + smb_fname); + if (full_fname == NULL) { + END_PROFILE(syscall_openat); + return -1; + } + + if (fsp->fsp_flags.is_pathref && !have_opath) { become_root(); became_root = true; } - if (how->flags & O_DIRECTORY) { - glfd = glfs_opendir(handle->data, smb_fname->base_name); - } else if (how->flags & O_CREAT) { + /* + * O_CREAT flag in open is handled differently in a way which is *NOT* + * safe against symlink race situations. We use glfs_creat() instead + * for correctness as glfs_openat() is broken with O_CREAT present + * in open flags. + */ + if (flags & O_CREAT) { + if (fsp_get_pathref_fd(dirfsp) != AT_FDCWD) { + /* + * Replace smb_fname with full_path constructed above. + */ + smb_fname = full_fname; + } + + /* + * smb_fname can either be a full_path or the same one + * as received from the caller. In the latter case we + * are operating at current working directory. + */ glfd = glfs_creat(handle->data, smb_fname->base_name, - how->flags, + flags, how->mode); } else { - glfd = glfs_open(handle->data, - smb_fname->base_name, - how->flags); + if (fsp_get_pathref_fd(dirfsp) != AT_FDCWD) { +#ifdef HAVE_GFAPI_VER_7_11 + /* + * Fetch Gluster fd for parent directory using dirfsp + * before calling glfs_openat(); + */ + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_openat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + glfd = glfs_openat(pglfd, + smb_fname->base_name, + flags, + how->mode); +#else + /* + * Replace smb_fname with full_path constructed above. + */ + smb_fname = full_fname; +#endif + } + + if (pglfd == NULL) { + /* + * smb_fname can either be a full_path or the same one + * as received from the caller. In the latter case we + * are operating at current working directory. + */ + glfd = glfs_open(handle->data, + smb_fname->base_name, + flags); + } } if (became_root) { unbecome_root(); } + TALLOC_FREE(full_fname); + fsp->fsp_flags.have_proc_fds = false; if (glfd == NULL) { - TALLOC_FREE(name); END_PROFILE(syscall_openat); /* no extension destroy_fn, so no need to save errno */ VFS_REMOVE_FSP_EXTENSION(handle, fsp); @@ -838,7 +902,6 @@ static int vfs_gluster_openat(struct vfs_handle_struct *handle, *p_tmp = glfd; - TALLOC_FREE(name); END_PROFILE(syscall_openat); /* An arbitrary value for error reporting, so you know its us. */ return 13371337; @@ -1242,9 +1305,33 @@ static int vfs_gluster_renameat(struct vfs_handle_struct *handle, files_struct *dstfsp, const struct smb_filename *smb_fname_dst) { + int ret; + +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *src_pglfd = NULL; + glfs_fd_t *dst_pglfd = NULL; + + START_PROFILE(syscall_renameat); + + src_pglfd = vfs_gluster_fetch_glfd(handle, srcfsp); + if (src_pglfd == NULL) { + END_PROFILE(syscall_renameat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + dst_pglfd = vfs_gluster_fetch_glfd(handle, dstfsp); + if (dst_pglfd == NULL) { + END_PROFILE(syscall_renameat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_renameat(src_pglfd, smb_fname_src->base_name, + dst_pglfd, smb_fname_dst->base_name); +#else struct smb_filename *full_fname_src = NULL; struct smb_filename *full_fname_dst = NULL; - int ret; START_PROFILE(syscall_renameat); @@ -1252,24 +1339,28 @@ static int vfs_gluster_renameat(struct vfs_handle_struct *handle, srcfsp, smb_fname_src); if (full_fname_src == NULL) { - errno = ENOMEM; END_PROFILE(syscall_renameat); + errno = ENOMEM; return -1; } + full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(), dstfsp, smb_fname_dst); if (full_fname_dst == NULL) { + END_PROFILE(syscall_renameat); TALLOC_FREE(full_fname_src); errno = ENOMEM; - END_PROFILE(syscall_renameat); return -1; } ret = glfs_rename(handle->data, full_fname_src->base_name, full_fname_dst->base_name); + TALLOC_FREE(full_fname_src); TALLOC_FREE(full_fname_dst); +#endif + END_PROFILE(syscall_renameat); return ret; @@ -1452,6 +1543,55 @@ static int vfs_gluster_fstat(struct vfs_handle_struct *handle, return ret; } +static int vfs_gluster_fstatat(struct vfs_handle_struct *handle, + const struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + SMB_STRUCT_STAT *sbuf, + int flags) +{ + struct stat st; + int ret; + +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *pglfd = NULL; + + START_PROFILE(syscall_fstatat); + + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_fstatat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_fstatat(pglfd, smb_fname->base_name, &st, flags); +#else + struct smb_filename *full_fname = NULL; + + START_PROFILE(syscall_fstatat); + + full_fname = full_path_from_dirfsp_atname(talloc_tos(), + dirfsp, + smb_fname); + if (full_fname == NULL) { + END_PROFILE(syscall_fstatat); + return -1; + } + + ret = glfs_stat(handle->data, full_fname->base_name, &st); + + TALLOC_FREE(full_fname->base_name); +#endif + + if (ret == 0) { + smb_stat_ex_from_stat(sbuf, &st); + } + + END_PROFILE(syscall_fstatat); + + return ret; +} + static int vfs_gluster_lstat(struct vfs_handle_struct *handle, struct smb_filename *smb_fname) { @@ -1490,9 +1630,24 @@ static int vfs_gluster_unlinkat(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, int flags) { - struct smb_filename *full_fname = NULL; int ret; +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *pglfd = NULL; + + START_PROFILE(syscall_unlinkat); + + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_unlinkat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_unlinkat(pglfd, smb_fname->base_name, flags); +#else + struct smb_filename *full_fname = NULL; + START_PROFILE(syscall_unlinkat); full_fname = full_path_from_dirfsp_atname(talloc_tos(), @@ -1508,7 +1663,10 @@ static int vfs_gluster_unlinkat(struct vfs_handle_struct *handle, } else { ret = glfs_unlink(handle->data, full_fname->base_name); } + TALLOC_FREE(full_fname); +#endif + END_PROFILE(syscall_unlinkat); return ret; @@ -1908,24 +2066,42 @@ static int vfs_gluster_symlinkat(struct vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { - struct smb_filename *full_fname = NULL; int ret; +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *pglfd = NULL; + + START_PROFILE(syscall_symlinkat); + + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_symlinkat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_symlinkat(link_target->base_name, + pglfd, + new_smb_fname->base_name); +#else + struct smb_filename *full_fname = NULL; + START_PROFILE(syscall_symlinkat); full_fname = full_path_from_dirfsp_atname(talloc_tos(), - dirfsp, - new_smb_fname); + dirfsp, + new_smb_fname); if (full_fname == NULL) { END_PROFILE(syscall_symlinkat); return -1; } ret = glfs_symlink(handle->data, - link_target->base_name, - full_fname->base_name); + link_target->base_name, + full_fname->base_name); TALLOC_FREE(full_fname); +#endif END_PROFILE(syscall_symlinkat); @@ -1938,14 +2114,29 @@ static int vfs_gluster_readlinkat(struct vfs_handle_struct *handle, char *buf, size_t bufsiz) { - struct smb_filename *full_fname = NULL; int ret; +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *pglfd = NULL; + + START_PROFILE(syscall_readlinkat); + + pglfd = vfs_gluster_fetch_glfd(handle, dirfsp); + if (pglfd == NULL) { + END_PROFILE(syscall_readlinkat); + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_readlinkat(pglfd, smb_fname->base_name, buf, bufsiz); +#else + struct smb_filename *full_fname = NULL; + START_PROFILE(syscall_readlinkat); full_fname = full_path_from_dirfsp_atname(talloc_tos(), - dirfsp, - smb_fname); + dirfsp, + smb_fname); if (full_fname == NULL) { END_PROFILE(syscall_readlinkat); return -1; @@ -1954,6 +2145,7 @@ static int vfs_gluster_readlinkat(struct vfs_handle_struct *handle, ret = glfs_readlink(handle->data, full_fname->base_name, buf, bufsiz); TALLOC_FREE(full_fname); +#endif END_PROFILE(syscall_readlinkat); @@ -1968,24 +2160,52 @@ static int vfs_gluster_linkat(struct vfs_handle_struct *handle, int flags) { int ret; + +#ifdef HAVE_GFAPI_VER_7_11 + glfs_fd_t *src_pglfd = NULL; + glfs_fd_t *dst_pglfd = NULL; + + START_PROFILE(syscall_linkat); + + src_pglfd = vfs_gluster_fetch_glfd(handle, srcfsp); -- Samba Shared Repository