#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"
dst->st_ex_btime.tv_sec = src->st_mtime;
dst->st_ex_blksize = src->st_blksize;
dst->st_ex_blocks = src->st_blocks;
- dst->st_ex_file_id = dst->st_ex_ino;
- dst->st_ex_iflags |= ST_EX_IFLAG_CALCULATED_FILE_ID;
#ifdef STAT_HAVE_NSEC
dst->st_ex_atime.tv_nsec = src->st_atime_nsec;
dst->st_ex_mtime.tv_nsec = src->st_mtime_nsec;
dst->st_ex_ctime.tv_nsec = src->st_ctime_nsec;
dst->st_ex_btime.tv_nsec = src->st_mtime_nsec;
#endif
- dst->st_ex_itime = dst->st_ex_btime;
- dst->st_ex_iflags |= ST_EX_IFLAG_CALCULATED_ITIME;
}
/* pre-opened glfs_t */
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;
{
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;
+
START_PROFILE(syscall_renameat);
- ret = glfs_rename(handle->data, smb_fname_src->base_name,
- smb_fname_dst->base_name);
+
+ full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
+ srcfsp,
+ smb_fname_src);
+ if (full_fname_src == NULL) {
+ 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;
+ 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)
{
{
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);
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+
+ full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+ dirfsp,
+ smb_fname);
+ if (full_fname == NULL) {
+ END_PROFILE(syscall_unlinkat);
+ return -1;
+ }
+
if (flags & AT_REMOVEDIR) {
- ret = glfs_rmdir(handle->data, smb_fname->base_name);
+ ret = glfs_rmdir(handle->data, full_fname->base_name);
} else {
- ret = glfs_unlink(handle->data, smb_fname->base_name);
+ ret = glfs_unlink(handle->data, full_fname->base_name);
}
- END_PROFILE(syscall_unlinkat);
- return ret;
-}
-
-static int vfs_gluster_chmod(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- mode_t mode)
-{
- int ret;
+ TALLOC_FREE(full_fname);
+#endif
- START_PROFILE(syscall_chmod);
- ret = glfs_chmod(handle->data, smb_fname->base_name, mode);
- END_PROFILE(syscall_chmod);
+ END_PROFILE(syscall_unlinkat);
return ret;
}
return -1;
}
- ret = glfs_fchmod(glfd, mode);
+ if (!fsp->fsp_flags.is_pathref) {
+ /*
+ * We can use an io_fd to remove xattrs.
+ */
+ ret = glfs_fchmod(glfd, mode);
+ } else {
+ /*
+ * This is no longer a handle based call.
+ */
+ ret = glfs_chmod(handle->data, fsp->fsp_name->base_name, mode);
+ }
END_PROFILE(syscall_fchmod);
return ret;
static struct smb_filename *vfs_gluster_getwd(struct vfs_handle_struct *handle,
TALLOC_CTX *ctx)
{
- char *cwd;
+ char cwd[PATH_MAX] = { '\0' };
char *ret;
struct smb_filename *smb_fname = NULL;
START_PROFILE(syscall_getwd);
- cwd = SMB_CALLOC_ARRAY(char, PATH_MAX);
- if (cwd == NULL) {
- END_PROFILE(syscall_getwd);
- return NULL;
- }
-
ret = glfs_getcwd(handle->data, cwd, PATH_MAX - 1);
END_PROFILE(syscall_getwd);
if (ret == NULL) {
- SAFE_FREE(cwd);
return NULL;
}
smb_fname = synthetic_smb_fname(ctx,
NULL,
0,
0);
- SAFE_FREE(cwd);
return smb_fname;
}
-static int vfs_gluster_ntimes(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- struct smb_file_time *ft)
+static int vfs_gluster_fntimes(struct vfs_handle_struct *handle,
+ files_struct *fsp,
+ struct smb_file_time *ft)
{
int ret = -1;
struct timespec times[2];
+ glfs_fd_t *glfd = NULL;
- START_PROFILE(syscall_ntimes);
+ START_PROFILE(syscall_fntimes);
if (is_omit_timespec(&ft->atime)) {
- times[0].tv_sec = smb_fname->st.st_ex_atime.tv_sec;
- times[0].tv_nsec = smb_fname->st.st_ex_atime.tv_nsec;
+ times[0].tv_sec = fsp->fsp_name->st.st_ex_atime.tv_sec;
+ times[0].tv_nsec = fsp->fsp_name->st.st_ex_atime.tv_nsec;
} else {
times[0].tv_sec = ft->atime.tv_sec;
times[0].tv_nsec = ft->atime.tv_nsec;
}
if (is_omit_timespec(&ft->mtime)) {
- times[1].tv_sec = smb_fname->st.st_ex_mtime.tv_sec;
- times[1].tv_nsec = smb_fname->st.st_ex_mtime.tv_nsec;
+ times[1].tv_sec = fsp->fsp_name->st.st_ex_mtime.tv_sec;
+ times[1].tv_nsec = fsp->fsp_name->st.st_ex_mtime.tv_nsec;
} else {
times[1].tv_sec = ft->mtime.tv_sec;
times[1].tv_nsec = ft->mtime.tv_nsec;
}
if ((timespec_compare(×[0],
- &smb_fname->st.st_ex_atime) == 0) &&
+ &fsp->fsp_name->st.st_ex_atime) == 0) &&
(timespec_compare(×[1],
- &smb_fname->st.st_ex_mtime) == 0)) {
- END_PROFILE(syscall_ntimes);
+ &fsp->fsp_name->st.st_ex_mtime) == 0)) {
+ END_PROFILE(syscall_fntimes);
return 0;
}
- ret = glfs_utimens(handle->data, smb_fname->base_name, times);
- END_PROFILE(syscall_ntimes);
+ glfd = vfs_gluster_fetch_glfd(handle, fsp);
+ if (glfd == NULL) {
+ END_PROFILE(syscall_fntimes);
+ DBG_ERR("Failed to fetch gluster fd\n");
+ return -1;
+ }
+
+ 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;
}
return ok;
}
-static int vfs_gluster_kernel_flock(struct vfs_handle_struct *handle,
- files_struct *fsp, uint32_t share_access,
- uint32_t access_mask)
+static int vfs_gluster_filesystem_sharemode(struct vfs_handle_struct *handle,
+ files_struct *fsp,
+ uint32_t share_access,
+ uint32_t access_mask)
{
errno = ENOSYS;
return -1;
{
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);
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+
+ full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+ dirfsp,
+ new_smb_fname);
+ if (full_fname == NULL) {
+ END_PROFILE(syscall_symlinkat);
+ return -1;
+ }
+
ret = glfs_symlink(handle->data,
- link_target->base_name,
- new_smb_fname->base_name);
+ link_target->base_name,
+ full_fname->base_name);
+
+ TALLOC_FREE(full_fname);
+#endif
+
END_PROFILE(syscall_symlinkat);
return ret;
{
int ret;
+#ifdef HAVE_GFAPI_VER_7_11
+ glfs_fd_t *pglfd = NULL;
+
START_PROFILE(syscall_readlinkat);
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
- ret = glfs_readlink(handle->data, smb_fname->base_name, buf, bufsiz);
+
+ 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);
+ 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);
return ret;
{
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);
- SMB_ASSERT(srcfsp == srcfsp->conn->cwd_fsp);
- SMB_ASSERT(dstfsp == dstfsp->conn->cwd_fsp);
+ full_fname_old = full_path_from_dirfsp_atname(talloc_tos(),
+ 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);
+ if (full_fname_new == NULL) {
+ END_PROFILE(syscall_linkat);
+ TALLOC_FREE(full_fname_old);
+ return -1;
+ }
ret = glfs_link(handle->data,
- old_smb_fname->base_name,
- new_smb_fname->base_name);
+ full_fname_old->base_name,
+ full_fname_new->base_name);
+
+ 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 ret;
}
-static int vfs_gluster_chflags(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
+static int vfs_gluster_fchflags(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
unsigned int flags)
{
errno = ENOSYS;
return -1;
}
-static int vfs_gluster_get_real_filename(struct vfs_handle_struct *handle,
- const struct smb_filename *path,
- const char *name,
- TALLOC_CTX *mem_ctx,
- char **found_name)
+static NTSTATUS vfs_gluster_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
{
int ret;
char key_buf[GLUSTER_NAME_MAX + 64];
char val_buf[GLUSTER_NAME_MAX + 1];
if (strlen(name) >= GLUSTER_NAME_MAX) {
- errno = ENAMETOOLONG;
- return -1;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
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) {
errno = ENOENT;
}
- return -1;
+ return map_nt_error_from_unix(errno);
}
*found_name = talloc_strdup(mem_ctx, val_buf);
if (found_name[0] == NULL) {
- errno = ENOMEM;
- return -1;
+ return NT_STATUS_NO_MEMORY;
}
- return 0;
+
+ 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;
}
/* EA Operations */
-static ssize_t vfs_gluster_getxattr(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- const char *name,
- void *value,
- size_t size)
-{
- return glfs_getxattr(handle->data, smb_fname->base_name,
- name, value, size);
-}
-
static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle,
files_struct *fsp, const char *name,
void *value, size_t size)
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);
+ }
-static ssize_t vfs_gluster_listxattr(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- char *list,
- size_t size)
-{
- return glfs_listxattr(handle->data, smb_fname->base_name, list, 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,
DBG_ERR("Failed to fetch gluster fd\n");
return -1;
}
-
- return glfs_flistxattr(glfd, list, size);
-}
-
-static int vfs_gluster_removexattr(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- const char *name)
-{
- return glfs_removexattr(handle->data, smb_fname->base_name, name);
+ if (!fsp->fsp_flags.is_pathref) {
+ /*
+ * We can use an io_fd to list xattrs.
+ */
+ return glfs_flistxattr(glfd, list, size);
+ } else {
+ /*
+ * This is no longer a handle based call.
+ */
+ return glfs_listxattr(handle->data,
+ fsp->fsp_name->base_name,
+ list,
+ size);
+ }
}
static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle,
DBG_ERR("Failed to fetch gluster fd\n");
return -1;
}
-
- return glfs_fremovexattr(glfd, name);
-}
-
-static int vfs_gluster_setxattr(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- const char *name,
- const void *value, size_t size, int flags)
-{
- return glfs_setxattr(handle->data, smb_fname->base_name, name, value, size, flags);
+ if (!fsp->fsp_flags.is_pathref) {
+ /*
+ * We can use an io_fd to remove xattrs.
+ */
+ return glfs_fremovexattr(glfd, name);
+ } else {
+ /*
+ * This is no longer a handle based call.
+ */
+ return glfs_removexattr(handle->data,
+ fsp->fsp_name->base_name,
+ name);
+ }
}
static int vfs_gluster_fsetxattr(struct vfs_handle_struct *handle,
return -1;
}
- return glfs_fsetxattr(glfd, name, value, size, flags);
+ if (!fsp->fsp_flags.is_pathref) {
+ /*
+ * We can use an io_fd to set xattrs.
+ */
+ return glfs_fsetxattr(glfd, name, value, size, flags);
+ } else {
+ /*
+ * This is no longer a handle based call.
+ */
+ return glfs_setxattr(handle->data,
+ fsp->fsp_name->base_name,
+ name,
+ value,
+ size,
+ flags);
+ }
}
/* AIO Operations */
NTSTATUS status = NT_STATUS_NO_MEMORY;
int ret;
char *msdfs_link = NULL;
-
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+#ifdef HAVE_GFAPI_VER_7_11
+ glfs_fd_t *pglfd = NULL;
+#else
+ struct smb_filename *full_fname = NULL;
+#endif
/* Form the msdfs_link contents */
msdfs_link = msdfs_link_string(frame,
goto out;
}
- ret = glfs_symlink(handle->data,
- msdfs_link,
- smb_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 {
char link_target_buf[7];
#endif
struct stat st;
+ struct smb_filename *full_fname = NULL;
int ret;
-
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+#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;
}
}
- ret = glfs_lstat(handle->data, smb_fname->base_name, &st);
+ full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+ dirfsp,
+ smb_fname);
+ if (full_fname == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
+ }
+
+ ret = glfs_lstat(handle->data, full_fname->base_name, &st);
if (ret < 0) {
status = map_nt_error_from_unix(errno);
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,
- smb_fname->base_name,
+ full_fname->base_name,
link_target,
bufsize - 1);
+#endif
if (referral_len < 0) {
if (errno == EINVAL) {
- DBG_INFO("%s is not a link.\n", smb_fname->base_name);
+ DBG_INFO("%s is not a link.\n", full_fname->base_name);
status = NT_STATUS_OBJECT_TYPE_MISMATCH;
} else {
status = map_nt_error_from_unix(errno);
DBG_ERR("Error reading "
"msdfs link %s: %s\n",
- smb_fname->base_name,
+ full_fname->base_name,
strerror(errno));
}
goto err;
link_target[referral_len] = '\0';
DBG_INFO("%s -> %s\n",
- smb_fname->base_name,
+ full_fname->base_name,
link_target);
if (!strnequal(link_target, "msdfs:", 6)) {
if (ppreflist == NULL && preferral_count == NULL) {
/* Early return for checking if this is a DFS link. */
+ TALLOC_FREE(full_fname);
smb_stat_ex_from_stat(&smb_fname->st, &st);
return NT_STATUS_OK;
}
if (link_target != link_target_buf) {
TALLOC_FREE(link_target);
}
+ TALLOC_FREE(full_fname);
return status;
}
.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,
- .chmod_fn = vfs_gluster_chmod,
.fchmod_fn = vfs_gluster_fchmod,
.fchown_fn = vfs_gluster_fchown,
.lchown_fn = vfs_gluster_lchown,
.chdir_fn = vfs_gluster_chdir,
.getwd_fn = vfs_gluster_getwd,
- .ntimes_fn = vfs_gluster_ntimes,
+ .fntimes_fn = vfs_gluster_fntimes,
.ftruncate_fn = vfs_gluster_ftruncate,
.fallocate_fn = vfs_gluster_fallocate,
.lock_fn = vfs_gluster_lock,
- .kernel_flock_fn = vfs_gluster_kernel_flock,
+ .filesystem_sharemode_fn = vfs_gluster_filesystem_sharemode,
.fcntl_fn = vfs_gluster_fcntl,
.linux_setlease_fn = vfs_gluster_linux_setlease,
.getlock_fn = vfs_gluster_getlock,
.linkat_fn = vfs_gluster_linkat,
.mknodat_fn = vfs_gluster_mknodat,
.realpath_fn = vfs_gluster_realpath,
- .chflags_fn = vfs_gluster_chflags,
+ .fchflags_fn = vfs_gluster_fchflags,
.file_id_create_fn = NULL,
- .streaminfo_fn = NULL,
- .get_real_filename_fn = vfs_gluster_get_real_filename,
+ .fstreaminfo_fn = NULL,
+ .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,
/* NT ACL Operations */
.fget_nt_acl_fn = NULL,
- .get_nt_acl_at_fn = NULL,
.fset_nt_acl_fn = NULL,
.audit_file_fn = NULL,
/* Posix ACL Operations */
- .sys_acl_get_file_fn = posixacl_xattr_acl_get_file,
.sys_acl_get_fd_fn = posixacl_xattr_acl_get_fd,
- .sys_acl_blob_get_file_fn = posix_sys_acl_blob_get_file,
.sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd,
.sys_acl_set_fd_fn = posixacl_xattr_acl_set_fd,
- .sys_acl_delete_def_file_fn = posixacl_xattr_acl_delete_def_file,
+ .sys_acl_delete_def_fd_fn = posixacl_xattr_acl_delete_def_fd,
/* EA Operations */
- .getxattr_fn = vfs_gluster_getxattr,
.getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
.getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
.fgetxattr_fn = vfs_gluster_fgetxattr,
- .listxattr_fn = vfs_gluster_listxattr,
.flistxattr_fn = vfs_gluster_flistxattr,
- .removexattr_fn = vfs_gluster_removexattr,
.fremovexattr_fn = vfs_gluster_fremovexattr,
- .setxattr_fn = vfs_gluster_setxattr,
.fsetxattr_fn = vfs_gluster_fsetxattr,
/* AIO Operations */