#include "lib/util/sys_rw.h"
#include "lib/pthreadpool/pthreadpool_tevent.h"
#include "librpc/gen_ndr/ndr_ioctl.h"
+#include "offload_token.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
/* Disk operations */
-static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path,
- uint64_t *bsize, uint64_t *dfree,
- uint64_t *dsize)
+static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint64_t *bsize,
+ uint64_t *dfree,
+ uint64_t *dsize)
{
- if (sys_fsusage(path, dfree, dsize) != 0) {
+ if (sys_fsusage(smb_fname->base_name, dfree, dsize) != 0) {
return (uint64_t)-1;
}
return *dfree / 2;
}
-static int vfswrap_get_quota(struct vfs_handle_struct *handle, const char *path,
- enum SMB_QUOTA_TYPE qtype, unid_t id,
- SMB_DISK_QUOTA *qt)
+static int vfswrap_get_quota(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ enum SMB_QUOTA_TYPE qtype,
+ unid_t id,
+ SMB_DISK_QUOTA *qt)
{
#ifdef HAVE_SYS_QUOTAS
int result;
START_PROFILE(syscall_get_quota);
- result = sys_get_quota(path, qtype, id, qt);
+ result = sys_get_quota(smb_fname->base_name, qtype, id, qt);
END_PROFILE(syscall_get_quota);
return result;
#else
return -1; /* Not implemented. */
}
-static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
+static int vfswrap_statvfs(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ vfs_statvfs_struct *statbuf)
{
- return sys_statvfs(path, statbuf);
+ return sys_statvfs(smb_fname->base_name, statbuf);
}
static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
!handle->conn->sconn->using_smb2,
junction, &consumedcnt, &self_referral);
if (!NT_STATUS_IS_OK(status)) {
- vfs_ChDir(handle->conn, handle->conn->connectpath);
+ struct smb_filename connectpath_fname = {
+ .base_name = handle->conn->connectpath
+ };
+ vfs_ChDir(handle->conn, &connectpath_fname);
return status;
}
- vfs_ChDir(handle->conn, handle->conn->connectpath);
+ {
+ struct smb_filename connectpath_fname = {
+ .base_name = handle->conn->connectpath
+ };
+ vfs_ChDir(handle->conn, &connectpath_fname);
+ }
if (!self_referral) {
pathnamep[consumedcnt] = '\0';
return result;
}
-static void vfswrap_init_search_op(vfs_handle_struct *handle,
- DIR *dirp)
-{
- /* Default behavior is a NOOP */
-}
-
/* File operations */
static int vfswrap_open(vfs_handle_struct *handle,
struct vfswrap_pread_state {
ssize_t ret;
- int err;
int fd;
void *buf;
size_t count;
static void vfs_pread_do(void *private_data);
static void vfs_pread_done(struct tevent_req *subreq);
+static int vfs_pread_state_destructor(struct vfswrap_pread_state *state);
static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, vfs_pread_done, req);
+ talloc_set_destructor(state, vfs_pread_state_destructor);
+
return req;
}
state->offset);
} while ((state->ret == -1) && (errno == EINTR));
- state->err = errno;
+ if (state->ret == -1) {
+ state->vfs_aio_state.error = errno;
+ }
PROFILE_TIMESTAMP(&end_time);
SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
}
+static int vfs_pread_state_destructor(struct vfswrap_pread_state *state)
+{
+ return -1;
+}
+
static void vfs_pread_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
-#ifdef WITH_PROFILE
struct vfswrap_pread_state *state = tevent_req_data(
req, struct vfswrap_pread_state);
-#endif
int ret;
ret = pthreadpool_tevent_job_recv(subreq);
TALLOC_FREE(subreq);
SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
+ talloc_set_destructor(state, NULL);
if (tevent_req_error(req, ret)) {
return;
}
struct vfswrap_pwrite_state {
ssize_t ret;
- int err;
int fd;
const void *buf;
size_t count;
static void vfs_pwrite_do(void *private_data);
static void vfs_pwrite_done(struct tevent_req *subreq);
+static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state);
static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, vfs_pwrite_done, req);
+ talloc_set_destructor(state, vfs_pwrite_state_destructor);
+
return req;
}
state->offset);
} while ((state->ret == -1) && (errno == EINTR));
- state->err = errno;
+ if (state->ret == -1) {
+ state->vfs_aio_state.error = errno;
+ }
PROFILE_TIMESTAMP(&end_time);
SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
}
+static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state)
+{
+ return -1;
+}
+
static void vfs_pwrite_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
-#ifdef WITH_PROFILE
struct vfswrap_pwrite_state *state = tevent_req_data(
req, struct vfswrap_pwrite_state);
-#endif
int ret;
ret = pthreadpool_tevent_job_recv(subreq);
TALLOC_FREE(subreq);
SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
+ talloc_set_destructor(state, NULL);
if (tevent_req_error(req, ret)) {
return;
}
struct vfswrap_fsync_state {
ssize_t ret;
- int err;
int fd;
struct vfs_aio_state vfs_aio_state;
static void vfs_fsync_do(void *private_data);
static void vfs_fsync_done(struct tevent_req *subreq);
+static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state);
static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, vfs_fsync_done, req);
+ talloc_set_destructor(state, vfs_fsync_state_destructor);
+
return req;
}
state->ret = fsync(state->fd);
} while ((state->ret == -1) && (errno == EINTR));
- state->err = errno;
+ if (state->ret == -1) {
+ state->vfs_aio_state.error = errno;
+ }
PROFILE_TIMESTAMP(&end_time);
state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
}
+static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state)
+{
+ return -1;
+}
+
static void vfs_fsync_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
-#ifdef WITH_PROFILE
struct vfswrap_fsync_state *state = tevent_req_data(
req, struct vfswrap_fsync_state);
-#endif
int ret;
ret = pthreadpool_tevent_job_recv(subreq);
TALLOC_FREE(subreq);
SMBPROFILE_BASIC_ASYNC_END(state->profile_basic);
+ talloc_set_destructor(state, NULL);
if (tevent_req_error(req, ret)) {
return;
}
return set_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
}
-struct vfs_cc_state {
+static struct vfs_offload_ctx *vfswrap_offload_ctx;
+
+struct vfswrap_offload_read_state {
+ DATA_BLOB token;
+};
+
+static struct tevent_req *vfswrap_offload_read_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t fsctl,
+ uint32_t ttl,
+ off_t offset,
+ size_t to_copy)
+{
+ struct tevent_req *req = NULL;
+ struct vfswrap_offload_read_state *state = NULL;
+ NTSTATUS status;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct vfswrap_offload_read_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ status = vfs_offload_token_ctx_init(fsp->conn->sconn->client,
+ &vfswrap_offload_ctx);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ if (fsctl != FSCTL_SRV_REQUEST_RESUME_KEY) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
+ return tevent_req_post(req, ev);
+ }
+
+ status = vfs_offload_token_create_blob(state, fsp, fsctl,
+ &state->token);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ status = vfs_offload_token_db_store_fsp(vfswrap_offload_ctx, fsp,
+ &state->token);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
+
+static NTSTATUS vfswrap_offload_read_recv(struct tevent_req *req,
+ struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *token)
+{
+ struct vfswrap_offload_read_state *state = tevent_req_data(
+ req, struct vfswrap_offload_read_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ token->length = state->token.length;
+ token->data = talloc_move(mem_ctx, &state->token.data);
+
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
+
+struct vfswrap_offload_write_state {
struct tevent_context *ev;
uint8_t *buf;
bool read_lck_locked;
- struct lock_struct read_lck;
bool write_lck_locked;
- struct lock_struct write_lck;
+ DATA_BLOB *token;
struct files_struct *src_fsp;
off_t src_off;
struct files_struct *dst_fsp;
off_t to_copy;
off_t remaining;
size_t next_io_size;
- uint32_t flags;
};
-static NTSTATUS copy_chunk_loop(struct tevent_req *req);
+static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req);
-static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *handle,
- TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct files_struct *src_fsp,
- off_t src_off,
- struct files_struct *dest_fsp,
- off_t dest_off,
- off_t to_copy,
- uint32_t flags)
+static struct tevent_req *vfswrap_offload_write_send(
+ struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ uint32_t fsctl,
+ DATA_BLOB *token,
+ off_t transfer_offset,
+ struct files_struct *dest_fsp,
+ off_t dest_off,
+ off_t to_copy)
{
struct tevent_req *req;
- struct vfs_cc_state *state = NULL;
+ struct vfswrap_offload_write_state *state = NULL;
size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN);
+ files_struct *src_fsp = NULL;
NTSTATUS status;
- DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
-
- req = tevent_req_create(mem_ctx, &state, struct vfs_cc_state);
+ req = tevent_req_create(mem_ctx, &state,
+ struct vfswrap_offload_write_state);
if (req == NULL) {
return NULL;
}
- if (flags & ~VFS_COPY_CHUNK_FL_MASK_ALL) {
+ *state = (struct vfswrap_offload_write_state) {
+ .ev = ev,
+ .token = token,
+ .src_off = transfer_offset,
+ .dst_fsp = dest_fsp,
+ .dst_off = dest_off,
+ .to_copy = to_copy,
+ .remaining = to_copy,
+ };
+
+ switch (fsctl) {
+ case FSCTL_SRV_COPYCHUNK:
+ case FSCTL_SRV_COPYCHUNK_WRITE:
+ break;
+
+ case FSCTL_OFFLOAD_WRITE:
+ tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ return tevent_req_post(req, ev);
+
+ case FSCTL_DUP_EXTENTS_TO_FILE:
+ DBG_DEBUG("COW clones not supported by vfs_default\n");
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return tevent_req_post(req, ev);
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ return tevent_req_post(req, ev);
}
- if (flags & VFS_COPY_CHUNK_FL_MUST_CLONE) {
- DEBUG(10, ("COW clones not supported by vfs_default\n"));
- tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ /*
+ * From here on we assume a copy-chunk fsctl
+ */
+
+ if (to_copy == 0) {
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
+
+ status = vfs_offload_token_db_fetch_fsp(vfswrap_offload_ctx,
+ token, &src_fsp);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+ state->src_fsp = src_fsp;
+
+ DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
+
+ status = vfs_offload_token_check_handles(fsctl, src_fsp, dest_fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
- *state = (struct vfs_cc_state) {
- .ev = ev,
- .src_fsp = src_fsp,
- .src_off = src_off,
- .dst_fsp = dest_fsp,
- .dst_off = dest_off,
- .to_copy = to_copy,
- .remaining = to_copy,
- .flags = flags,
- };
state->buf = talloc_array(state, uint8_t, num);
if (tevent_req_nomem(state->buf, req)) {
return tevent_req_post(req, ev);
return tevent_req_post(req, ev);
}
- if (src_fsp->fsp_name->st.st_ex_size < src_off + num) {
+ if (src_fsp->fsp_name->st.st_ex_size < state->src_off + num) {
/*
* [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
* If the SourceOffset or SourceOffset + Length extends beyond
return tevent_req_post(req, ev);
}
- status = copy_chunk_loop(req);
+ status = vfswrap_offload_write_loop(req);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
return req;
}
-static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq);
+static void vfswrap_offload_write_read_done(struct tevent_req *subreq);
-static NTSTATUS copy_chunk_loop(struct tevent_req *req)
+static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req)
{
- struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+ struct vfswrap_offload_write_state *state = tevent_req_data(
+ req, struct vfswrap_offload_write_state);
struct tevent_req *subreq = NULL;
+ struct lock_struct read_lck;
bool ok;
state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
- if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
- init_strict_lock_struct(state->src_fsp,
+ init_strict_lock_struct(state->src_fsp,
state->src_fsp->op->global->open_persistent_id,
- state->src_off,
- state->next_io_size,
- READ_LOCK,
- &state->read_lck);
-
- ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
- state->src_fsp,
- &state->read_lck);
- if (!ok) {
- return NT_STATUS_FILE_LOCK_CONFLICT;
- }
+ state->src_off,
+ state->next_io_size,
+ READ_LOCK,
+ &read_lck);
+
+ ok = SMB_VFS_STRICT_LOCK_CHECK(state->src_fsp->conn,
+ state->src_fsp,
+ &read_lck);
+ if (!ok) {
+ return NT_STATUS_FILE_LOCK_CONFLICT;
}
subreq = SMB_VFS_PREAD_SEND(state,
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
- tevent_req_set_callback(subreq, vfswrap_copy_chunk_read_done, req);
+ tevent_req_set_callback(subreq, vfswrap_offload_write_read_done, req);
return NT_STATUS_OK;
}
-static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq);
+static void vfswrap_offload_write_write_done(struct tevent_req *subreq);
-static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
+static void vfswrap_offload_write_read_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+ struct vfswrap_offload_write_state *state = tevent_req_data(
+ req, struct vfswrap_offload_write_state);
struct vfs_aio_state aio_state;
+ struct lock_struct write_lck;
ssize_t nread;
bool ok;
- if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
- SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
- state->src_fsp,
- &state->read_lck);
- ZERO_STRUCT(state->read_lck);
- }
-
nread = SMB_VFS_PREAD_RECV(subreq, &aio_state);
TALLOC_FREE(subreq);
if (nread == -1) {
state->src_off += nread;
- if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
- init_strict_lock_struct(state->dst_fsp,
+ init_strict_lock_struct(state->dst_fsp,
state->dst_fsp->op->global->open_persistent_id,
- state->dst_off,
- state->next_io_size,
- WRITE_LOCK,
- &state->write_lck);
-
- ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
- state->dst_fsp,
- &state->write_lck);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
- return;
- }
+ state->dst_off,
+ state->next_io_size,
+ WRITE_LOCK,
+ &write_lck);
+
+ ok = SMB_VFS_STRICT_LOCK_CHECK(state->dst_fsp->conn,
+ state->dst_fsp,
+ &write_lck);
+ if (!ok) {
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return;
}
subreq = SMB_VFS_PWRITE_SEND(state,
tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- tevent_req_set_callback(subreq, vfswrap_copy_chunk_write_done, req);
+ tevent_req_set_callback(subreq, vfswrap_offload_write_write_done, req);
}
-static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq)
+static void vfswrap_offload_write_write_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+ struct vfswrap_offload_write_state *state = tevent_req_data(
+ req, struct vfswrap_offload_write_state);
struct vfs_aio_state aio_state;
ssize_t nwritten;
NTSTATUS status;
- if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
- SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
- state->dst_fsp,
- &state->write_lck);
- ZERO_STRUCT(state->write_lck);
- }
-
nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
TALLOC_FREE(subreq);
if (nwritten == -1) {
return;
}
- status = copy_chunk_loop(req);
+ status = vfswrap_offload_write_loop(req);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
return;
}
-static NTSTATUS vfswrap_copy_chunk_recv(struct vfs_handle_struct *handle,
+static NTSTATUS vfswrap_offload_write_recv(struct vfs_handle_struct *handle,
struct tevent_req *req,
off_t *copied)
{
- struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+ struct vfswrap_offload_write_state *state = tevent_req_data(
+ req, struct vfswrap_offload_write_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
return result;
}
-static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
+static int vfswrap_chdir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
int result;
START_PROFILE(syscall_chdir);
- result = chdir(path);
+ result = chdir(smb_fname->base_name);
END_PROFILE(syscall_chdir);
return result;
}
-static char *vfswrap_getwd(vfs_handle_struct *handle)
+static struct smb_filename *vfswrap_getwd(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx)
{
char *result;
+ struct smb_filename *smb_fname = NULL;
START_PROFILE(syscall_getwd);
result = sys_getwd();
END_PROFILE(syscall_getwd);
- return result;
+
+ if (result == NULL) {
+ return NULL;
+ }
+ smb_fname = synthetic_smb_fname(ctx,
+ result,
+ NULL,
+ NULL,
+ 0);
+ if (smb_fname == NULL) {
+ SAFE_FREE(result);
+ }
+ return smb_fname;
}
/*********************************************************************
return result;
}
-static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int vfswrap_symlink(vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
int result;
START_PROFILE(syscall_symlink);
- result = symlink(oldpath, newpath);
+ result = symlink(link_target, new_smb_fname->base_name);
END_PROFILE(syscall_symlink);
return result;
}
-static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int vfswrap_readlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
{
int result;
START_PROFILE(syscall_readlink);
- result = readlink(path, buf, bufsiz);
+ result = readlink(smb_fname->base_name, buf, bufsiz);
END_PROFILE(syscall_readlink);
return result;
}
-static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int vfswrap_link(vfs_handle_struct *handle,
+ const struct smb_filename *old_smb_fname,
+ const struct smb_filename *new_smb_fname)
{
int result;
START_PROFILE(syscall_link);
- result = link(oldpath, newpath);
+ result = link(old_smb_fname->base_name, new_smb_fname->base_name);
END_PROFILE(syscall_link);
return result;
}
return result;
}
-static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
+static struct smb_filename *vfswrap_realpath(vfs_handle_struct *handle,
+ TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname)
{
char *result;
+ struct smb_filename *result_fname = NULL;
START_PROFILE(syscall_realpath);
- result = sys_realpath(path);
+ result = sys_realpath(smb_fname->base_name);
END_PROFILE(syscall_realpath);
- return result;
+ if (result) {
+ result_fname = synthetic_smb_fname(ctx, result, NULL, NULL, 0);
+ SAFE_FREE(result);
+ }
+ return result_fname;
}
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
- unsigned int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ unsigned int flags)
{
#ifdef HAVE_CHFLAGS
- return chflags(path, flags);
+ return chflags(smb_fname->base_name, flags);
#else
errno = ENOSYS;
return -1;
}
static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
- const char *fname)
+ const struct smb_filename *smb_fname)
{
return handle->conn->connectpath;
}
return brl_lock_cancel_default(br_lck, plock);
}
-static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
- files_struct *fsp,
- struct lock_struct *plock)
-{
- SMB_ASSERT(plock->lock_type == READ_LOCK ||
- plock->lock_type == WRITE_LOCK);
-
- return strict_lock_default(fsp, plock);
-}
-
-static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
- files_struct *fsp,
- struct lock_struct *plock)
+static bool vfswrap_strict_lock_check(struct vfs_handle_struct *handle,
+ files_struct *fsp,
+ struct lock_struct *plock)
{
SMB_ASSERT(plock->lock_type == READ_LOCK ||
plock->lock_type == WRITE_LOCK);
- strict_unlock_default(fsp, plock);
+ return strict_lock_check_default(fsp, plock);
}
/* NT ACL operations. */
.mkdir_fn = vfswrap_mkdir,
.rmdir_fn = vfswrap_rmdir,
.closedir_fn = vfswrap_closedir,
- .init_search_op_fn = vfswrap_init_search_op,
/* File operations */
.brl_lock_windows_fn = vfswrap_brl_lock_windows,
.brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
.brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
- .strict_lock_fn = vfswrap_strict_lock,
- .strict_unlock_fn = vfswrap_strict_unlock,
+ .strict_lock_check_fn = vfswrap_strict_lock_check,
.translate_name_fn = vfswrap_translate_name,
.fsctl_fn = vfswrap_fsctl,
.set_dos_attributes_fn = vfswrap_set_dos_attributes,
.fset_dos_attributes_fn = vfswrap_fset_dos_attributes,
.get_dos_attributes_fn = vfswrap_get_dos_attributes,
.fget_dos_attributes_fn = vfswrap_fget_dos_attributes,
- .copy_chunk_send_fn = vfswrap_copy_chunk_send,
- .copy_chunk_recv_fn = vfswrap_copy_chunk_recv,
+ .offload_read_send_fn = vfswrap_offload_read_send,
+ .offload_read_recv_fn = vfswrap_offload_read_recv,
+ .offload_write_send_fn = vfswrap_offload_write_send,
+ .offload_write_recv_fn = vfswrap_offload_write_recv,
.get_compression_fn = vfswrap_get_compression,
.set_compression_fn = vfswrap_set_compression,