mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
s3: Add strict lock/unlock calls to the vfs layer to replace is_locked
This commit is contained in:
committed by
Tim Prouty
parent
1355dc2fd3
commit
1fcc11ff25
@ -3409,11 +3409,16 @@ void brl_register_msgs(struct messaging_context *msg_ctx);
|
|||||||
|
|
||||||
const char *lock_type_name(enum brl_type lock_type);
|
const char *lock_type_name(enum brl_type lock_type);
|
||||||
const char *lock_flav_name(enum brl_flavour lock_flav);
|
const char *lock_flav_name(enum brl_flavour lock_flav);
|
||||||
bool is_locked(files_struct *fsp,
|
void init_strict_lock_struct(files_struct *fsp,
|
||||||
uint32 smbpid,
|
uint32 smbpid,
|
||||||
uint64_t count,
|
br_off start,
|
||||||
uint64_t offset,
|
br_off size,
|
||||||
enum brl_type lock_type);
|
enum brl_type lock_type,
|
||||||
|
struct lock_struct *plock);
|
||||||
|
bool strict_lock_default(files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
|
void strict_unlock_default(files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
NTSTATUS query_lock(files_struct *fsp,
|
NTSTATUS query_lock(files_struct *fsp,
|
||||||
uint32 *psmbpid,
|
uint32 *psmbpid,
|
||||||
uint64_t *pcount,
|
uint64_t *pcount,
|
||||||
|
@ -243,6 +243,14 @@ enum profile_stats_values
|
|||||||
#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count)
|
#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count)
|
||||||
#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time)
|
#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time)
|
||||||
|
|
||||||
|
PR_VALUE_SYSCALL_STRICT_LOCK,
|
||||||
|
#define syscall_strict_lock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, count)
|
||||||
|
#define syscall_strict_lock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, time)
|
||||||
|
|
||||||
|
PR_VALUE_SYSCALL_STRICT_UNLOCK,
|
||||||
|
#define syscall_strict_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, count)
|
||||||
|
#define syscall_strict_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, time)
|
||||||
|
|
||||||
/* counters for individual SMB types */
|
/* counters for individual SMB types */
|
||||||
PR_VALUE_SMBMKDIR,
|
PR_VALUE_SMBMKDIR,
|
||||||
#define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count)
|
#define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count)
|
||||||
|
@ -116,6 +116,7 @@
|
|||||||
/* Leave at 25 - not yet released. Add SMB_STRUCT_STAT to readdir. - sdann */
|
/* Leave at 25 - not yet released. Add SMB_STRUCT_STAT to readdir. - sdann */
|
||||||
/* Leave at 25 - not yet released. Add init_search_op call. - sdann */
|
/* Leave at 25 - not yet released. Add init_search_op call. - sdann */
|
||||||
/* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */
|
/* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */
|
||||||
|
/* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */
|
||||||
|
|
||||||
#define SMB_VFS_INTERFACE_VERSION 25
|
#define SMB_VFS_INTERFACE_VERSION 25
|
||||||
|
|
||||||
@ -223,6 +224,8 @@ typedef enum _vfs_op_type {
|
|||||||
SMB_VFS_OP_BRL_LOCK_WINDOWS,
|
SMB_VFS_OP_BRL_LOCK_WINDOWS,
|
||||||
SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
|
SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
|
||||||
SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
||||||
|
SMB_VFS_OP_STRICT_LOCK,
|
||||||
|
SMB_VFS_OP_STRICT_UNLOCK,
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
@ -415,6 +418,14 @@ struct vfs_ops {
|
|||||||
struct lock_struct *plock,
|
struct lock_struct *plock,
|
||||||
struct blocking_lock_record *blr);
|
struct blocking_lock_record *blr);
|
||||||
|
|
||||||
|
bool (*strict_lock)(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
|
|
||||||
|
void (*strict_unlock)(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
|
NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
|
||||||
@ -556,6 +567,8 @@ struct vfs_ops {
|
|||||||
struct vfs_handle_struct *brl_lock_windows;
|
struct vfs_handle_struct *brl_lock_windows;
|
||||||
struct vfs_handle_struct *brl_unlock_windows;
|
struct vfs_handle_struct *brl_unlock_windows;
|
||||||
struct vfs_handle_struct *brl_cancel_windows;
|
struct vfs_handle_struct *brl_cancel_windows;
|
||||||
|
struct vfs_handle_struct *strict_lock;
|
||||||
|
struct vfs_handle_struct *strict_unlock;
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
|
@ -91,6 +91,8 @@
|
|||||||
#define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
#define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
||||||
#define SMB_VFS_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs.ops.brl_unlock_windows((conn)->vfs.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
#define SMB_VFS_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs.ops.brl_unlock_windows((conn)->vfs.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
||||||
#define SMB_VFS_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs.ops.brl_cancel_windows((conn)->vfs.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
#define SMB_VFS_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs.ops.brl_cancel_windows((conn)->vfs.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
||||||
|
#define SMB_VFS_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_lock((conn)->vfs.handles.strict_lock, (fsp), (plock)))
|
||||||
|
#define SMB_VFS_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_unlock((conn)->vfs.handles.strict_unlock, (fsp), (plock)))
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
#define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
#define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
||||||
@ -223,6 +225,8 @@
|
|||||||
#define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
#define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
||||||
#define SMB_VFS_OPAQUE_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs_opaque.ops.brl_unlock_windows((conn)->vfs_opaque.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
#define SMB_VFS_OPAQUE_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs_opaque.ops.brl_unlock_windows((conn)->vfs_opaque.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
||||||
#define SMB_VFS_OPAQUE_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs_opaque.ops.brl_cancel_windows((conn)->vfs_opaque.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
#define SMB_VFS_OPAQUE_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs_opaque.ops.brl_cancel_windows((conn)->vfs_opaque.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
||||||
|
#define SMB_VFS_OPAQUE_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_lock((conn)->vfs_opaque.handles.strict_lock, (fsp), (plock)))
|
||||||
|
#define SMB_VFS_OPAQUE_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_unlock((conn)->vfs_opaque.handles.strict_unlock, (fsp), (plock)))
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
#define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
#define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
||||||
@ -356,6 +360,8 @@
|
|||||||
#define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
#define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
|
||||||
#define SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck, plock) ((handle)->vfs_next.ops.brl_unlock_windows((handle)->vfs_next.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
#define SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck, plock) ((handle)->vfs_next.ops.brl_unlock_windows((handle)->vfs_next.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
|
||||||
#define SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr) ((handle)->vfs_next.ops.brl_cancel_windows((handle)->vfs_next.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
#define SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr) ((handle)->vfs_next.ops.brl_cancel_windows((handle)->vfs_next.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
|
||||||
|
#define SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_lock((handle)->vfs_next.handles.strict_lock, (fsp), (plock)))
|
||||||
|
#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_unlock((handle)->vfs_next.handles.strict_unlock, (fsp), (plock)))
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
|
||||||
|
@ -75,69 +75,89 @@ const char *lock_flav_name(enum brl_flavour lock_flav)
|
|||||||
Called in the read/write codepath.
|
Called in the read/write codepath.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
bool is_locked(files_struct *fsp,
|
void init_strict_lock_struct(files_struct *fsp,
|
||||||
uint32 smbpid,
|
uint32 smbpid,
|
||||||
uint64_t count,
|
br_off start,
|
||||||
uint64_t offset,
|
br_off size,
|
||||||
enum brl_type lock_type)
|
enum brl_type lock_type,
|
||||||
|
struct lock_struct *plock)
|
||||||
|
{
|
||||||
|
SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
|
||||||
|
|
||||||
|
plock->context.smbpid = smbpid;
|
||||||
|
plock->context.tid = fsp->conn->cnum;
|
||||||
|
plock->context.pid = procid_self();
|
||||||
|
plock->start = start;
|
||||||
|
plock->size = size;
|
||||||
|
plock->fnum = fsp->fnum;
|
||||||
|
plock->lock_type = lock_type;
|
||||||
|
plock->lock_flav = lp_posix_cifsu_locktype(fsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
|
||||||
{
|
{
|
||||||
int strict_locking = lp_strict_locking(fsp->conn->params);
|
int strict_locking = lp_strict_locking(fsp->conn->params);
|
||||||
enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
|
bool ret = False;
|
||||||
bool ret = True;
|
|
||||||
|
|
||||||
if (count == 0) {
|
if (plock->size == 0) {
|
||||||
return False;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lp_locking(fsp->conn->params) || !strict_locking) {
|
if (!lp_locking(fsp->conn->params) || !strict_locking) {
|
||||||
return False;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strict_locking == Auto) {
|
if (strict_locking == Auto) {
|
||||||
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
|
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
|
||||||
DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
|
DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
|
||||||
ret = False;
|
ret = True;
|
||||||
} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
|
} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
|
||||||
(lock_type == READ_LOCK)) {
|
(plock->lock_type == READ_LOCK)) {
|
||||||
DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
|
DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
|
||||||
ret = False;
|
ret = True;
|
||||||
} else {
|
} else {
|
||||||
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
|
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
|
||||||
if (!br_lck) {
|
if (!br_lck) {
|
||||||
return False;
|
return True;
|
||||||
}
|
}
|
||||||
ret = !brl_locktest(br_lck,
|
ret = brl_locktest(br_lck,
|
||||||
smbpid,
|
plock->context.smbpid,
|
||||||
procid_self(),
|
plock->context.pid,
|
||||||
offset,
|
plock->start,
|
||||||
count,
|
plock->size,
|
||||||
lock_type,
|
plock->lock_type,
|
||||||
lock_flav);
|
plock->lock_flav);
|
||||||
TALLOC_FREE(br_lck);
|
TALLOC_FREE(br_lck);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
|
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
|
||||||
if (!br_lck) {
|
if (!br_lck) {
|
||||||
return False;
|
return True;
|
||||||
}
|
}
|
||||||
ret = !brl_locktest(br_lck,
|
ret = brl_locktest(br_lck,
|
||||||
smbpid,
|
plock->context.smbpid,
|
||||||
procid_self(),
|
plock->context.pid,
|
||||||
offset,
|
plock->start,
|
||||||
count,
|
plock->size,
|
||||||
lock_type,
|
plock->lock_type,
|
||||||
lock_flav);
|
plock->lock_flav);
|
||||||
TALLOC_FREE(br_lck);
|
TALLOC_FREE(br_lck);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
|
DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
|
||||||
lock_flav_name(lock_flav),
|
"len=%.0f %s for fnum %d file %s\n",
|
||||||
(double)offset, (double)count, ret ? "locked" : "unlocked",
|
lock_flav_name(plock->lock_flav),
|
||||||
fsp->fnum, fsp->fsp_name ));
|
(double)plock->start, (double)plock->size,
|
||||||
|
ret ? "unlocked" : "locked",
|
||||||
|
plock->fnum, fsp->fsp_name ));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Find out if a lock could be granted - return who is blocking us if we can't.
|
Find out if a lock could be granted - return who is blocking us if we can't.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1157,6 +1157,26 @@ static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
|
|||||||
return brl_lock_cancel_default(br_lck, plock);
|
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)
|
||||||
|
{
|
||||||
|
SMB_ASSERT(plock->lock_type == READ_LOCK ||
|
||||||
|
plock->lock_type == WRITE_LOCK);
|
||||||
|
|
||||||
|
return strict_unlock_default(fsp, plock);
|
||||||
|
}
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
|
static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
|
||||||
@ -1592,6 +1612,10 @@ static vfs_op_tuple vfs_default_ops[] = {
|
|||||||
SMB_VFS_LAYER_OPAQUE},
|
SMB_VFS_LAYER_OPAQUE},
|
||||||
{SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
{SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
||||||
SMB_VFS_LAYER_OPAQUE},
|
SMB_VFS_LAYER_OPAQUE},
|
||||||
|
{SMB_VFS_OP(vfswrap_strict_lock), SMB_VFS_OP_STRICT_LOCK,
|
||||||
|
SMB_VFS_LAYER_OPAQUE},
|
||||||
|
{SMB_VFS_OP(vfswrap_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK,
|
||||||
|
SMB_VFS_LAYER_OPAQUE},
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
|
@ -234,6 +234,12 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
|
|||||||
struct byte_range_lock *br_lck,
|
struct byte_range_lock *br_lck,
|
||||||
struct lock_struct *plock,
|
struct lock_struct *plock,
|
||||||
struct blocking_lock_record *blr);
|
struct blocking_lock_record *blr);
|
||||||
|
static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
|
static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock);
|
||||||
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
||||||
uint32 security_info,
|
uint32 security_info,
|
||||||
SEC_DESC **ppdesc);
|
SEC_DESC **ppdesc);
|
||||||
@ -483,6 +489,10 @@ static vfs_op_tuple audit_op_tuples[] = {
|
|||||||
SMB_VFS_LAYER_LOGGER},
|
SMB_VFS_LAYER_LOGGER},
|
||||||
{SMB_VFS_OP(smb_full_audit_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
{SMB_VFS_OP(smb_full_audit_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS,
|
||||||
SMB_VFS_LAYER_LOGGER},
|
SMB_VFS_LAYER_LOGGER},
|
||||||
|
{SMB_VFS_OP(smb_full_audit_strict_lock), SMB_VFS_OP_STRICT_LOCK,
|
||||||
|
SMB_VFS_LAYER_LOGGER},
|
||||||
|
{SMB_VFS_OP(smb_full_audit_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK,
|
||||||
|
SMB_VFS_LAYER_LOGGER},
|
||||||
|
|
||||||
/* NT ACL operations. */
|
/* NT ACL operations. */
|
||||||
|
|
||||||
@ -660,6 +670,8 @@ static struct {
|
|||||||
{ SMB_VFS_OP_BRL_LOCK_WINDOWS, "brl_lock_windows" },
|
{ SMB_VFS_OP_BRL_LOCK_WINDOWS, "brl_lock_windows" },
|
||||||
{ SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
|
{ SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
|
||||||
{ SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" },
|
{ SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" },
|
||||||
|
{ SMB_VFS_OP_STRICT_LOCK, "strict_lock" },
|
||||||
|
{ SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" },
|
||||||
{ SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" },
|
{ SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" },
|
||||||
{ SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" },
|
{ SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" },
|
||||||
{ SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" },
|
{ SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" },
|
||||||
@ -1766,6 +1778,34 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
|
||||||
|
|
||||||
|
do_log(SMB_VFS_OP_STRICT_LOCK, result, handle,
|
||||||
|
"%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
|
||||||
|
plock->size);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
struct lock_struct *plock)
|
||||||
|
{
|
||||||
|
SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
|
||||||
|
|
||||||
|
do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle,
|
||||||
|
"%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
|
||||||
|
plock->size);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
||||||
uint32 security_info,
|
uint32 security_info,
|
||||||
SEC_DESC **ppdesc)
|
SEC_DESC **ppdesc)
|
||||||
|
@ -2859,6 +2859,7 @@ void reply_readbraw(struct smb_request *req)
|
|||||||
size_t nread = 0;
|
size_t nread = 0;
|
||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT st;
|
||||||
SMB_OFF_T size = 0;
|
SMB_OFF_T size = 0;
|
||||||
|
|
||||||
@ -2959,10 +2960,11 @@ void reply_readbraw(struct smb_request *req)
|
|||||||
/* ensure we don't overrun the packet size */
|
/* ensure we don't overrun the packet size */
|
||||||
maxcount = MIN(65535,maxcount);
|
maxcount = MIN(65535,maxcount);
|
||||||
|
|
||||||
if (is_locked(fsp,(uint32)req->smbpid,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)maxcount,
|
(uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
|
||||||
(uint64_t)startpos,
|
&lock);
|
||||||
READ_LOCK)) {
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_readbraw_error();
|
reply_readbraw_error();
|
||||||
END_PROFILE(SMBreadbraw);
|
END_PROFILE(SMBreadbraw);
|
||||||
return;
|
return;
|
||||||
@ -2993,7 +2995,11 @@ void reply_readbraw(struct smb_request *req)
|
|||||||
send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
|
send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
|
||||||
|
|
||||||
DEBUG(5,("reply_readbraw finished\n"));
|
DEBUG(5,("reply_readbraw finished\n"));
|
||||||
|
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
END_PROFILE(SMBreadbraw);
|
END_PROFILE(SMBreadbraw);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
@ -3121,6 +3127,7 @@ void reply_read(struct smb_request *req)
|
|||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
int outsize = 0;
|
int outsize = 0;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
|
|
||||||
START_PROFILE(SMBread);
|
START_PROFILE(SMBread);
|
||||||
|
|
||||||
@ -3162,8 +3169,11 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
|
|||||||
|
|
||||||
data = smb_buf(req->outbuf) + 3;
|
data = smb_buf(req->outbuf) + 3;
|
||||||
|
|
||||||
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, READ_LOCK)) {
|
(uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS,ERRlock);
|
reply_doserror(req, ERRDOS,ERRlock);
|
||||||
END_PROFILE(SMBread);
|
END_PROFILE(SMBread);
|
||||||
return;
|
return;
|
||||||
@ -3174,8 +3184,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
|
|||||||
|
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
reply_unixerror(req, ERRDOS,ERRnoaccess);
|
reply_unixerror(req, ERRDOS,ERRnoaccess);
|
||||||
END_PROFILE(SMBread);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_set_message((char *)req->outbuf, 5, nread+3, False);
|
srv_set_message((char *)req->outbuf, 5, nread+3, False);
|
||||||
@ -3188,6 +3197,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
|
|||||||
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
|
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
|
||||||
fsp->fnum, (int)numtoread, (int)nread ) );
|
fsp->fnum, (int)numtoread, (int)nread ) );
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
END_PROFILE(SMBread);
|
END_PROFILE(SMBread);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3387,6 +3399,7 @@ void reply_read_and_X(struct smb_request *req)
|
|||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
size_t smb_maxcnt;
|
size_t smb_maxcnt;
|
||||||
|
struct lock_struct lock;
|
||||||
bool big_readX = False;
|
bool big_readX = False;
|
||||||
#if 0
|
#if 0
|
||||||
size_t smb_mincnt = SVAL(req->vwv+6, 0);
|
size_t smb_mincnt = SVAL(req->vwv+6, 0);
|
||||||
@ -3474,8 +3487,11 @@ void reply_read_and_X(struct smb_request *req)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, READ_LOCK)) {
|
(uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
END_PROFILE(SMBreadX);
|
END_PROFILE(SMBreadX);
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
return;
|
return;
|
||||||
@ -3483,12 +3499,14 @@ void reply_read_and_X(struct smb_request *req)
|
|||||||
|
|
||||||
if (!big_readX &&
|
if (!big_readX &&
|
||||||
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
|
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
|
||||||
END_PROFILE(SMBreadX);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
|
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
END_PROFILE(SMBreadX);
|
END_PROFILE(SMBreadX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3523,6 +3541,7 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
char *data=NULL;
|
char *data=NULL;
|
||||||
bool write_through;
|
bool write_through;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
START_PROFILE(SMBwritebraw);
|
START_PROFILE(SMBwritebraw);
|
||||||
@ -3584,8 +3603,11 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, WRITE_LOCK)) {
|
(uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
error_to_writebrawerr(req);
|
error_to_writebrawerr(req);
|
||||||
END_PROFILE(SMBwritebraw);
|
END_PROFILE(SMBwritebraw);
|
||||||
@ -3604,8 +3626,7 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
if (nwritten < (ssize_t)numtowrite) {
|
if (nwritten < (ssize_t)numtowrite) {
|
||||||
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
||||||
error_to_writebrawerr(req);
|
error_to_writebrawerr(req);
|
||||||
END_PROFILE(SMBwritebraw);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
total_written = nwritten;
|
total_written = nwritten;
|
||||||
@ -3615,8 +3636,7 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
reply_doserror(req, ERRDOS, ERRnomem);
|
reply_doserror(req, ERRDOS, ERRnomem);
|
||||||
error_to_writebrawerr(req);
|
error_to_writebrawerr(req);
|
||||||
END_PROFILE(SMBwritebraw);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a SMBwritebraw message to the redirector to tell
|
/* Return a SMBwritebraw message to the redirector to tell
|
||||||
@ -3674,8 +3694,7 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
TALLOC_FREE(buf);
|
TALLOC_FREE(buf);
|
||||||
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
||||||
error_to_writebrawerr(req);
|
error_to_writebrawerr(req);
|
||||||
END_PROFILE(SMBwritebraw);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nwritten < (ssize_t)numtowrite) {
|
if (nwritten < (ssize_t)numtowrite) {
|
||||||
@ -3697,8 +3716,7 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
fsp->fsp_name, nt_errstr(status) ));
|
fsp->fsp_name, nt_errstr(status) ));
|
||||||
reply_nterror(req, status);
|
reply_nterror(req, status);
|
||||||
error_to_writebrawerr(req);
|
error_to_writebrawerr(req);
|
||||||
END_PROFILE(SMBwritebraw);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
|
DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
|
||||||
@ -3706,6 +3724,8 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
fsp->fnum, (double)startpos, (int)numtowrite,
|
fsp->fnum, (double)startpos, (int)numtowrite,
|
||||||
(int)total_written));
|
(int)total_written));
|
||||||
|
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
/* We won't return a status if write through is not selected - this
|
/* We won't return a status if write through is not selected - this
|
||||||
* follows what WfWg does */
|
* follows what WfWg does */
|
||||||
END_PROFILE(SMBwritebraw);
|
END_PROFILE(SMBwritebraw);
|
||||||
@ -3726,6 +3746,12 @@ void reply_writebraw(struct smb_request *req)
|
|||||||
TALLOC_FREE(req->outbuf);
|
TALLOC_FREE(req->outbuf);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
|
END_PROFILE(SMBwritebraw);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
@ -3744,6 +3770,7 @@ void reply_writeunlock(struct smb_request *req)
|
|||||||
const char *data;
|
const char *data;
|
||||||
NTSTATUS status = NT_STATUS_OK;
|
NTSTATUS status = NT_STATUS_OK;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
|
|
||||||
START_PROFILE(SMBwriteunlock);
|
START_PROFILE(SMBwriteunlock);
|
||||||
|
|
||||||
@ -3770,13 +3797,17 @@ void reply_writeunlock(struct smb_request *req)
|
|||||||
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
|
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
|
||||||
data = (const char *)req->buf + 3;
|
data = (const char *)req->buf + 3;
|
||||||
|
|
||||||
if (numtowrite
|
if (numtowrite) {
|
||||||
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, WRITE_LOCK)) {
|
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
END_PROFILE(SMBwriteunlock);
|
END_PROFILE(SMBwriteunlock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The special X/Open SMB protocol handling of
|
/* The special X/Open SMB protocol handling of
|
||||||
zero length writes is *NOT* done for
|
zero length writes is *NOT* done for
|
||||||
@ -3792,14 +3823,12 @@ void reply_writeunlock(struct smb_request *req)
|
|||||||
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
|
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
|
||||||
fsp->fsp_name, nt_errstr(status) ));
|
fsp->fsp_name, nt_errstr(status) ));
|
||||||
reply_nterror(req, status);
|
reply_nterror(req, status);
|
||||||
END_PROFILE(SMBwriteunlock);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
|
if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
|
||||||
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
||||||
END_PROFILE(SMBwriteunlock);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numtowrite) {
|
if (numtowrite) {
|
||||||
@ -3812,8 +3841,7 @@ void reply_writeunlock(struct smb_request *req)
|
|||||||
|
|
||||||
if (NT_STATUS_V(status)) {
|
if (NT_STATUS_V(status)) {
|
||||||
reply_nterror(req, status);
|
reply_nterror(req, status);
|
||||||
END_PROFILE(SMBwriteunlock);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3824,6 +3852,11 @@ void reply_writeunlock(struct smb_request *req)
|
|||||||
DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
|
DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
|
||||||
fsp->fnum, (int)numtowrite, (int)nwritten));
|
fsp->fnum, (int)numtowrite, (int)nwritten));
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
if (numtowrite) {
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
}
|
||||||
|
|
||||||
END_PROFILE(SMBwriteunlock);
|
END_PROFILE(SMBwriteunlock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3843,6 +3876,7 @@ void reply_write(struct smb_request *req)
|
|||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
const char *data;
|
const char *data;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
START_PROFILE(SMBwrite);
|
START_PROFILE(SMBwrite);
|
||||||
@ -3877,8 +3911,11 @@ void reply_write(struct smb_request *req)
|
|||||||
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
|
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
|
||||||
data = (const char *)req->buf + 3;
|
data = (const char *)req->buf + 3;
|
||||||
|
|
||||||
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, WRITE_LOCK)) {
|
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
END_PROFILE(SMBwrite);
|
END_PROFILE(SMBwrite);
|
||||||
return;
|
return;
|
||||||
@ -3897,14 +3934,12 @@ void reply_write(struct smb_request *req)
|
|||||||
nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
|
nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
|
||||||
if (nwritten < 0) {
|
if (nwritten < 0) {
|
||||||
reply_nterror(req, NT_STATUS_DISK_FULL);
|
reply_nterror(req, NT_STATUS_DISK_FULL);
|
||||||
END_PROFILE(SMBwrite);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
|
nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
|
||||||
if (nwritten < 0) {
|
if (nwritten < 0) {
|
||||||
reply_nterror(req, NT_STATUS_DISK_FULL);
|
reply_nterror(req, NT_STATUS_DISK_FULL);
|
||||||
END_PROFILE(SMBwrite);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
trigger_write_time_update_immediate(fsp);
|
trigger_write_time_update_immediate(fsp);
|
||||||
} else {
|
} else {
|
||||||
@ -3916,14 +3951,12 @@ void reply_write(struct smb_request *req)
|
|||||||
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
|
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
|
||||||
fsp->fsp_name, nt_errstr(status) ));
|
fsp->fsp_name, nt_errstr(status) ));
|
||||||
reply_nterror(req, status);
|
reply_nterror(req, status);
|
||||||
END_PROFILE(SMBwrite);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
||||||
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
||||||
END_PROFILE(SMBwrite);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_outbuf(req, 1, 0);
|
reply_outbuf(req, 1, 0);
|
||||||
@ -3937,6 +3970,9 @@ void reply_write(struct smb_request *req)
|
|||||||
|
|
||||||
DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
|
DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
END_PROFILE(SMBwrite);
|
END_PROFILE(SMBwrite);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4034,6 +4070,7 @@ void reply_write_and_X(struct smb_request *req)
|
|||||||
{
|
{
|
||||||
connection_struct *conn = req->conn;
|
connection_struct *conn = req->conn;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
size_t numtowrite;
|
size_t numtowrite;
|
||||||
bool write_through;
|
bool write_through;
|
||||||
@ -4136,9 +4173,11 @@ void reply_write_and_X(struct smb_request *req)
|
|||||||
#endif /* LARGE_SMB_OFF_T */
|
#endif /* LARGE_SMB_OFF_T */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_locked(fsp,(uint32)req->smbpid,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)numtowrite,
|
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
|
||||||
(uint64_t)startpos, WRITE_LOCK)) {
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
END_PROFILE(SMBwriteX);
|
END_PROFILE(SMBwriteX);
|
||||||
return;
|
return;
|
||||||
@ -4156,8 +4195,7 @@ void reply_write_and_X(struct smb_request *req)
|
|||||||
if ((req->unread_bytes == 0) &&
|
if ((req->unread_bytes == 0) &&
|
||||||
schedule_aio_write_and_X(conn, req, fsp, data, startpos,
|
schedule_aio_write_and_X(conn, req, fsp, data, startpos,
|
||||||
numtowrite)) {
|
numtowrite)) {
|
||||||
END_PROFILE(SMBwriteX);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nwritten = write_file(req,fsp,data,startpos,numtowrite);
|
nwritten = write_file(req,fsp,data,startpos,numtowrite);
|
||||||
@ -4165,8 +4203,7 @@ void reply_write_and_X(struct smb_request *req)
|
|||||||
|
|
||||||
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
||||||
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
reply_unixerror(req, ERRHRD, ERRdiskfull);
|
||||||
END_PROFILE(SMBwriteX);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_outbuf(req, 6, 0);
|
reply_outbuf(req, 6, 0);
|
||||||
@ -4186,13 +4223,20 @@ void reply_write_and_X(struct smb_request *req)
|
|||||||
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
|
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
|
||||||
fsp->fsp_name, nt_errstr(status) ));
|
fsp->fsp_name, nt_errstr(status) ));
|
||||||
reply_nterror(req, status);
|
reply_nterror(req, status);
|
||||||
END_PROFILE(SMBwriteX);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
END_PROFILE(SMBwriteX);
|
END_PROFILE(SMBwriteX);
|
||||||
chain_reply(req);
|
chain_reply(req);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
|
END_PROFILE(SMBwriteX);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -4432,6 +4476,7 @@ void reply_writeclose(struct smb_request *req)
|
|||||||
const char *data;
|
const char *data;
|
||||||
struct timespec mtime;
|
struct timespec mtime;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
struct lock_struct lock;
|
||||||
|
|
||||||
START_PROFILE(SMBwriteclose);
|
START_PROFILE(SMBwriteclose);
|
||||||
|
|
||||||
@ -4458,13 +4503,17 @@ void reply_writeclose(struct smb_request *req)
|
|||||||
mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
|
mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
|
||||||
data = (const char *)req->buf + 1;
|
data = (const char *)req->buf + 1;
|
||||||
|
|
||||||
if (numtowrite
|
if (numtowrite) {
|
||||||
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
(uint64_t)startpos, WRITE_LOCK)) {
|
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
reply_doserror(req, ERRDOS,ERRlock);
|
reply_doserror(req, ERRDOS,ERRlock);
|
||||||
END_PROFILE(SMBwriteclose);
|
END_PROFILE(SMBwriteclose);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nwritten = write_file(req,fsp,data,startpos,numtowrite);
|
nwritten = write_file(req,fsp,data,startpos,numtowrite);
|
||||||
|
|
||||||
@ -4487,19 +4536,23 @@ void reply_writeclose(struct smb_request *req)
|
|||||||
|
|
||||||
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
|
||||||
reply_doserror(req, ERRHRD, ERRdiskfull);
|
reply_doserror(req, ERRHRD, ERRdiskfull);
|
||||||
END_PROFILE(SMBwriteclose);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!NT_STATUS_IS_OK(close_status)) {
|
if(!NT_STATUS_IS_OK(close_status)) {
|
||||||
reply_nterror(req, close_status);
|
reply_nterror(req, close_status);
|
||||||
END_PROFILE(SMBwriteclose);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_outbuf(req, 1, 0);
|
reply_outbuf(req, 1, 0);
|
||||||
|
|
||||||
SSVAL(req->outbuf,smb_vwv0,nwritten);
|
SSVAL(req->outbuf,smb_vwv0,nwritten);
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
if (numtowrite) {
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
}
|
||||||
|
|
||||||
END_PROFILE(SMBwriteclose);
|
END_PROFILE(SMBwriteclose);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user