#include <glusterfs/api/glfs.h>
#include "lib/util/dlinklist.h"
#include "lib/util/tevent_unix.h"
+#include "lib/util/util_file.h"
#include "smbd/globals.h"
#include "lib/util/sys_rw.h"
#include "smbprofile.h"
glfs_fini(entry->fs);
talloc_free(entry);
+ break;
}
}
}
/*
* file_lines_parse() plays horrible tricks with
- * the passed-in talloc pointers and the hierarcy
+ * the passed-in talloc pointers and the hierarchy
* which makes freeing hard to get right.
*
* As we know mem_ctx is freed by the caller, after
}
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) {
files_struct *fsp, const char *mask,
uint32_t attributes)
{
- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp);
+ glfs_fd_t *glfd = NULL;
+
+ glfd = glfs_opendir(handle->data, fsp->fsp_name->base_name);
if (glfd == NULL) {
- DBG_ERR("Failed to fetch gluster fd\n");
return NULL;
}
static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle,
struct files_struct *dirfsp,
- DIR *dirp,
- SMB_STRUCT_STAT *sbuf)
+ DIR *dirp)
{
static char direntbuf[512];
int ret;
- struct stat stat;
struct dirent *dirent = 0;
START_PROFILE(syscall_readdir);
- if (sbuf != NULL) {
- ret = glfs_readdirplus_r((void *)dirp, &stat, (void *)direntbuf,
- &dirent);
- } else {
- ret = glfs_readdir_r((void *)dirp, (void *)direntbuf, &dirent);
- }
+
+ ret = glfs_readdir_r((void *)dirp, (void *)direntbuf, &dirent);
if ((ret < 0) || (dirent == NULL)) {
END_PROFILE(syscall_readdir);
return NULL;
}
- if (sbuf != NULL) {
- SET_STAT_INVALID(*sbuf);
- if (!S_ISLNK(stat.st_mode)) {
- smb_stat_ex_from_stat(sbuf, &stat);
- }
- }
-
END_PROFILE(syscall_readdir);
return dirent;
}
-static long vfs_gluster_telldir(struct vfs_handle_struct *handle, DIR *dirp)
-{
- long ret;
-
- START_PROFILE(syscall_telldir);
- ret = glfs_telldir((void *)dirp);
- END_PROFILE(syscall_telldir);
-
- return ret;
-}
-
-static void vfs_gluster_seekdir(struct vfs_handle_struct *handle, DIR *dirp,
- long offset)
-{
- START_PROFILE(syscall_seekdir);
- glfs_seekdir((void *)dirp, offset);
- END_PROFILE(syscall_seekdir);
-}
-
static void vfs_gluster_rewinddir(struct vfs_handle_struct *handle, DIR *dirp)
{
START_PROFILE(syscall_rewinddir);
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(),
ret = glfs_mkdir(handle->data, full_fname->base_name, mode);
TALLOC_FREE(full_fname);
+#endif
END_PROFILE(syscall_mkdirat);
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
files_struct *fsp,
- int flags,
- mode_t mode)
+ 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 *glfd = NULL;
+ glfs_fd_t *pglfd = NULL;
glfs_fd_t **p_tmp;
START_PROFILE(syscall_openat);
- /*
- * 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) {
- return -1;
- }
- smb_fname = name;
+ if (how->resolve != 0) {
+ END_PROFILE(syscall_openat);
+ errno = ENOSYS;
+ return -1;
}
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 (flags & O_DIRECTORY) {
- glfd = glfs_opendir(handle->data, smb_fname->base_name);
- } else if (flags & O_CREAT) {
- glfd = glfs_creat(handle->data, smb_fname->base_name, flags,
- mode);
- } else {
- glfd = glfs_open(handle->data, smb_fname->base_name, 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.
+ */
+ if (flags & O_CREAT) {
+ glfd = glfs_creat(handle->data,
+ smb_fname->base_name,
+ flags,
+ how->mode);
+ } else {
+ 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);
*p_tmp = glfd;
- TALLOC_FREE(name);
END_PROFILE(syscall_openat);
/* An arbitrary value for error reporting, so you know its us. */
return 13371337;
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);
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;
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)
{
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(),
} else {
ret = glfs_unlink(handle->data, full_fname->base_name);
}
+
TALLOC_FREE(full_fname);
+#endif
+
END_PROFILE(syscall_unlinkat);
return ret;
return -1;
}
- ret = glfs_futimens(glfd, times);
+ if (!fsp->fsp_flags.is_pathref) {
+ ret = glfs_futimens(glfd, times);
+ } else {
+ ret = glfs_utimens(handle->data,
+ fsp->fsp_name->base_name,
+ times);
+ }
END_PROFILE(syscall_fntimes);
return ret;
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);
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;
ret = glfs_readlink(handle->data, full_fname->base_name, buf, bufsiz);
TALLOC_FREE(full_fname);
+#endif
END_PROFILE(syscall_readlinkat);
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);
+ if (src_pglfd == NULL) {
+ END_PROFILE(syscall_linkat);
+ 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_linkat);
+ DBG_ERR("Failed to fetch gluster fd\n");
+ return -1;
+ }
+
+ ret = glfs_linkat(src_pglfd,
+ old_smb_fname->base_name,
+ dst_pglfd,
+ new_smb_fname->base_name,
+ flags);
+#else
struct smb_filename *full_fname_old = NULL;
struct smb_filename *full_fname_new = NULL;
START_PROFILE(syscall_linkat);
full_fname_old = full_path_from_dirfsp_atname(talloc_tos(),
- srcfsp,
- old_smb_fname);
+ srcfsp,
+ old_smb_fname);
if (full_fname_old == NULL) {
END_PROFILE(syscall_linkat);
return -1;
}
+
full_fname_new = full_path_from_dirfsp_atname(talloc_tos(),
- dstfsp,
- new_smb_fname);
+ dstfsp,
+ new_smb_fname);
if (full_fname_new == NULL) {
- TALLOC_FREE(full_fname_old);
END_PROFILE(syscall_linkat);
+ TALLOC_FREE(full_fname_old);
return -1;
}
TALLOC_FREE(full_fname_old);
TALLOC_FREE(full_fname_new);
+#endif
+
END_PROFILE(syscall_linkat);
return ret;
mode_t mode,
SMB_DEV_T dev)
{
- struct smb_filename *full_fname = NULL;
int ret;
+#ifdef HAVE_GFAPI_VER_7_11
+ glfs_fd_t *pglfd = NULL;
+
+ START_PROFILE(syscall_mknodat);
+
+ pglfd = vfs_gluster_fetch_glfd(handle, dirfsp);
+ if (pglfd == NULL) {
+ END_PROFILE(syscall_mknodat);
+ DBG_ERR("Failed to fetch gluster fd\n");
+ return -1;
+ }
+
+ ret = glfs_mknodat(pglfd, smb_fname->base_name, mode, dev);
+#else
+ struct smb_filename *full_fname = NULL;
+
START_PROFILE(syscall_mknodat);
full_fname = full_path_from_dirfsp_atname(talloc_tos(),
- dirfsp,
- smb_fname);
+ dirfsp,
+ smb_fname);
if (full_fname == NULL) {
END_PROFILE(syscall_mknodat);
return -1;
ret = glfs_mknod(handle->data, full_fname->base_name, mode, dev);
TALLOC_FREE(full_fname);
+#endif
END_PROFILE(syscall_mknodat);
return -1;
}
-static NTSTATUS vfs_gluster_get_real_filename(
+static NTSTATUS vfs_gluster_get_real_filename_at(
struct vfs_handle_struct *handle,
- const struct smb_filename *path,
+ struct files_struct *dirfsp,
const char *name,
TALLOC_CTX *mem_ctx,
char **found_name)
snprintf(key_buf, GLUSTER_NAME_MAX + 64,
"glusterfs.get_real_filename:%s", name);
- ret = glfs_getxattr(handle->data, path->base_name, key_buf, val_buf,
+ ret = glfs_getxattr(handle->data,
+ dirfsp->fsp_name->base_name,
+ key_buf,
+ val_buf,
GLUSTER_NAME_MAX + 1);
if (ret == -1) {
if (errno == ENOATTR) {
if (found_name[0] == NULL) {
return NT_STATUS_NO_MEMORY;
}
+
return NT_STATUS_OK;
}
-static const char *vfs_gluster_connectpath(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname)
+static const char *vfs_gluster_connectpath(
+ struct vfs_handle_struct *handle,
+ const struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname)
{
return handle->conn->connectpath;
}
return -1;
}
- return glfs_fgetxattr(glfd, name, value, size);
+ if (!fsp->fsp_flags.is_pathref) {
+ /*
+ * We can use an io_fd to retrieve xattr value.
+ */
+ return glfs_fgetxattr(glfd, name, value, size);
+ }
+
+ /*
+ * This is no longer a handle based call.
+ */
+ return glfs_getxattr(handle->data,
+ fsp->fsp_name->base_name,
+ name,
+ value,
+ size);
}
static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle,
NTSTATUS status = NT_STATUS_NO_MEMORY;
int ret;
char *msdfs_link = NULL;
+#ifdef HAVE_GFAPI_VER_7_11
+ glfs_fd_t *pglfd = NULL;
+#else
struct smb_filename *full_fname = NULL;
-
- full_fname = full_path_from_dirfsp_atname(talloc_tos(),
- dirfsp,
- smb_fname);
- if (full_fname == NULL) {
- goto out;
- }
+#endif
/* Form the msdfs_link contents */
msdfs_link = msdfs_link_string(frame,
goto out;
}
- ret = glfs_symlink(handle->data,
- msdfs_link,
- full_fname->base_name);
+#ifdef HAVE_GFAPI_VER_7_11
+ pglfd = vfs_gluster_fetch_glfd(handle, dirfsp);
+ if (pglfd == NULL) {
+ DBG_ERR("Failed to fetch gluster fd\n");
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto out;
+ }
+
+ ret = glfs_symlinkat(msdfs_link, pglfd, smb_fname->base_name);
+#else
+ full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+ dirfsp,
+ smb_fname);
+ if (full_fname == NULL) {
+ goto out;
+ }
+
+ ret = glfs_symlink(handle->data, msdfs_link, full_fname->base_name);
+
+ TALLOC_FREE(full_fname);
+#endif
if (ret == 0) {
status = NT_STATUS_OK;
} else {
struct stat st;
struct smb_filename *full_fname = NULL;
int ret;
+#ifdef HAVE_GFAPI_VER_7_11
+ glfs_fd_t *pglfd = NULL;
+#endif
if (is_named_stream(smb_fname)) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto err;
}
+#ifdef HAVE_GFAPI_VER_7_11
+ pglfd = vfs_gluster_fetch_glfd(handle, dirfsp);
+ if (pglfd == NULL) {
+ DBG_ERR("Failed to fetch gluster fd\n");
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ referral_len = glfs_readlinkat(pglfd,
+ smb_fname->base_name,
+ link_target,
+ bufsize - 1);
+#else
referral_len = glfs_readlink(handle->data,
full_fname->base_name,
link_target,
bufsize - 1);
+#endif
if (referral_len < 0) {
if (errno == EINVAL) {
DBG_INFO("%s is not a link.\n", full_fname->base_name);
.fdopendir_fn = vfs_gluster_fdopendir,
.readdir_fn = vfs_gluster_readdir,
- .seekdir_fn = vfs_gluster_seekdir,
- .telldir_fn = vfs_gluster_telldir,
.rewind_dir_fn = vfs_gluster_rewinddir,
.mkdirat_fn = vfs_gluster_mkdirat,
.closedir_fn = vfs_gluster_closedir,
.stat_fn = vfs_gluster_stat,
.fstat_fn = vfs_gluster_fstat,
+ .fstatat_fn = vfs_gluster_fstatat,
.lstat_fn = vfs_gluster_lstat,
.get_alloc_size_fn = vfs_gluster_get_alloc_size,
.unlinkat_fn = vfs_gluster_unlinkat,
.fchflags_fn = vfs_gluster_fchflags,
.file_id_create_fn = NULL,
.fstreaminfo_fn = NULL,
- .get_real_filename_fn = vfs_gluster_get_real_filename,
+ .get_real_filename_at_fn = vfs_gluster_get_real_filename_at,
.connectpath_fn = vfs_gluster_connectpath,
.create_dfs_pathat_fn = vfs_gluster_create_dfs_pathat,
.read_dfs_pathat_fn = vfs_gluster_read_dfs_pathat,