struct aio_open_private_data *prev, *next;
/* Inputs. */
int dir_fd;
+ bool opened_dir_fd;
int flags;
mode_t mode;
uint64_t mid;
static void opd_free(struct aio_open_private_data *opd)
{
- if (opd->dir_fd != -1) {
+ if (opd->opened_dir_fd && opd->dir_fd != -1) {
close(opd->dir_fd);
}
DLIST_REMOVE(open_pd_list, opd);
static struct aio_open_private_data *create_private_open_data(
TALLOC_CTX *ctx,
+ const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
const files_struct *fsp,
int flags,
return NULL;
}
+ if (fsp_get_pathref_fd(dirfsp) != AT_FDCWD) {
+ opd->dir_fd = fsp_get_pathref_fd(dirfsp);
+ } else {
#if defined(O_DIRECTORY)
- opd->dir_fd = open(".", O_RDONLY|O_DIRECTORY);
+ opd->dir_fd = open(".", O_RDONLY|O_DIRECTORY);
#else
- opd->dir_fd = open(".", O_RDONLY);
+ opd->dir_fd = open(".", O_RDONLY);
#endif
+ opd->opened_dir_fd = true;
+ }
if (opd->dir_fd == -1) {
opd_free(opd);
return NULL;
Setup an async open.
*****************************************************************/
-static int open_async(const struct smb_filename *smb_fname,
+static int open_async(const struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
const files_struct *fsp,
int flags,
mode_t mode)
* memory leaks.
*/
opd = create_private_open_data(fsp->conn,
+ dirfsp,
smb_fname,
fsp,
flags,
opens to prevent any race conditions.
*****************************************************************/
-static int aio_pthread_open_fn(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
+static int aio_pthread_openat_fn(vfs_handle_struct *handle,
+ const struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ struct files_struct *fsp,
+ const struct vfs_open_how *how)
{
int my_errno = 0;
int fd = -1;
bool aio_allow_open = lp_parm_bool(
SNUM(handle->conn), "aio_pthread", "aio open", false);
- if (smb_fname->stream_name) {
+ if (how->resolve != 0) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ if (is_named_stream(smb_fname)) {
/* Don't handle stream opens. */
errno = ENOENT;
return -1;
}
- if (!aio_allow_open) {
- /* aio opens turned off. */
- return open(smb_fname->base_name, flags, mode);
+ if (fsp->conn->sconn->pool == NULL) {
+ /*
+ * a threadpool is required for async support
+ */
+ aio_allow_open = false;
}
- if (!(flags & O_CREAT)) {
+ if (fsp->conn->sconn->client != NULL &&
+ fsp->conn->sconn->client->server_multi_channel_enabled) {
+ /*
+ * This module is not compatible with multi channel yet.
+ */
+ aio_allow_open = false;
+ }
+
+ if (fsp->fsp_flags.is_pathref) {
+ /* Use SMB_VFS_NEXT_OPENAT() to call openat() with O_PATH. */
+ aio_allow_open = false;
+ }
+
+ if (!(how->flags & O_CREAT)) {
/* Only creates matter. */
- return open(smb_fname->base_name, flags, mode);
+ aio_allow_open = false;
}
- if (!(flags & O_EXCL)) {
+ if (!(how->flags & O_EXCL)) {
/* Only creates with O_EXCL matter. */
- return open(smb_fname->base_name, flags, mode);
+ aio_allow_open = false;
+ }
+
+ if (!aio_allow_open) {
+ /* aio opens turned off. */
+ return SMB_VFS_NEXT_OPENAT(handle,
+ dirfsp,
+ smb_fname,
+ fsp,
+ how);
}
/*
}
/* Ok, it's a create exclusive call - pass it to a thread helper. */
- return open_async(smb_fname, fsp, flags, mode);
+ return open_async(dirfsp, smb_fname, fsp, how->flags, how->mode);
}
#endif
static struct vfs_fn_pointers vfs_aio_pthread_fns = {
#if defined(HAVE_OPENAT) && defined(HAVE_LINUX_THREAD_CREDENTIALS)
- .open_fn = aio_pthread_open_fn,
+ .openat_fn = aio_pthread_openat_fn,
#endif
};