mirror of
https://github.com/samba-team/samba.git
synced 2025-02-04 17:47:26 +03:00
r15949: Patch for bug #3308 to stop us returning duplicate
mid replies on path based set-eof trans2 calls. Needs modification for HEAD (as in head open_file_ntcreateX properly returns NTSTATUS - I'll fix this tomorrow my time). Secondly it still fails the Samba4 RAW-OPLOCK smbtorture because of an interesting case. Our oplock code always returns "break to level 2" if it can. In this case (path-based set-eof or set-allocation size on an exclusive oplocked file) W2K3 always sends a break-to-none. We send the break to none (from level2) after we've done the write for eof or allocation size. I need to work out some way of telling our break code to always break to none (might need to extend the message field). Jeremy.
This commit is contained in:
parent
784126edff
commit
ad9895c654
@ -1652,11 +1652,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
|
||||
|
||||
fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,
|
||||
FILE_READ_DATA, /* Read-only. */
|
||||
0, /* No sharing. */
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
0, /* No create options. */
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NO_OPLOCK,
|
||||
&info);
|
||||
|
||||
if (!fsp1) {
|
||||
@ -1669,12 +1669,12 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
|
||||
}
|
||||
|
||||
fsp2 = open_file_ntcreate(conn,newname,&sbuf2,
|
||||
FILE_WRITE_DATA, /* Read-only. */
|
||||
0, /* No sharing. */
|
||||
FILE_WRITE_DATA, /* Write-only. */
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
FILE_CREATE,
|
||||
0, /* No create options. */
|
||||
fattr,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NO_OPLOCK,
|
||||
&info);
|
||||
|
||||
if (!fsp2) {
|
||||
|
@ -599,7 +599,7 @@ static BOOL is_delete_request(files_struct *fsp) {
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) No files open at all: Grant whatever the client wants.
|
||||
* 1) No files open at all or internal open: Grant whatever the client wants.
|
||||
*
|
||||
* 2) Exclusive (or batch) oplock around: If the requested access is a delete
|
||||
* request, break if the oplock around is a batch oplock. If it's another
|
||||
@ -608,7 +608,10 @@ static BOOL is_delete_request(files_struct *fsp) {
|
||||
* 3) Only level2 around: Grant level2 and do nothing else.
|
||||
*/
|
||||
|
||||
static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, int pass_number)
|
||||
static BOOL delay_for_oplocks(struct share_mode_lock *lck,
|
||||
files_struct *fsp,
|
||||
int pass_number,
|
||||
BOOL internal_only_open)
|
||||
{
|
||||
int i;
|
||||
struct share_mode_entry *exclusive = NULL;
|
||||
@ -616,7 +619,7 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, in
|
||||
BOOL delay_it = False;
|
||||
BOOL have_level2 = False;
|
||||
|
||||
if (is_stat_open(fsp->access_mask)) {
|
||||
if (internal_only_open || is_stat_open(fsp->access_mask)) {
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
return False;
|
||||
}
|
||||
@ -1367,7 +1370,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
|
||||
}
|
||||
|
||||
/* First pass - send break only on batch oplocks. */
|
||||
if (delay_for_oplocks(lck, fsp, 1)) {
|
||||
if (delay_for_oplocks(lck, fsp, 1, internal_only_open)) {
|
||||
schedule_defer_open(lck, request_time);
|
||||
TALLOC_FREE(lck);
|
||||
return NULL;
|
||||
@ -1380,7 +1383,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/* We might be going to allow this open. Check oplock status again. */
|
||||
/* Second pass - send break for both batch or exclusive oplocks. */
|
||||
if (delay_for_oplocks(lck, fsp, 2)) {
|
||||
if (delay_for_oplocks(lck, fsp, 2, internal_only_open)) {
|
||||
schedule_defer_open(lck, request_time);
|
||||
TALLOC_FREE(lck);
|
||||
return NULL;
|
||||
|
@ -4020,15 +4020,19 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
|
||||
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||
FILE_WRITE_DATA,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NO_OPLOCK,
|
||||
NULL);
|
||||
|
||||
if (new_fsp == NULL) {
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
|
||||
/* We have re-scheduled this call. */
|
||||
return -1;
|
||||
}
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
ret = vfs_allocate_file_space(new_fsp, allocation_size);
|
||||
if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
|
||||
@ -4561,7 +4565,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
POSIX_LOCK,
|
||||
&my_lock_ctx);
|
||||
|
||||
/* TODO: Deal with rescheduling blocking lock fail here... */
|
||||
if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
|
||||
/*
|
||||
* A blocking lock was requested. Package up
|
||||
@ -4660,15 +4663,19 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
|
||||
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||
FILE_WRITE_DATA,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NO_OPLOCK,
|
||||
NULL);
|
||||
|
||||
if (new_fsp == NULL) {
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
|
||||
/* We have re-scheduled this call. */
|
||||
return -1;
|
||||
}
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
ret = vfs_set_filelen(new_fsp, size);
|
||||
close_file(new_fsp,NORMAL_CLOSE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user