diff options
author | Jeremy Allison <jra@samba.org> | 2006-05-30 05:08:15 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:17:14 -0500 |
commit | 41f139c0bbe02ac4abe15d1e540fe9bff8cff5a5 (patch) | |
tree | 69b6506dd34e80455baa7ab6e72647d77b4c4644 /source3/smbd | |
parent | 0a1ca7fa3d19f46c4bcb0c80c78a619c90fe5f2a (diff) | |
download | samba-41f139c0bbe02ac4abe15d1e540fe9bff8cff5a5.tar.gz samba-41f139c0bbe02ac4abe15d1e540fe9bff8cff5a5.tar.bz2 samba-41f139c0bbe02ac4abe15d1e540fe9bff8cff5a5.zip |
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 used to be commit ad9895c654f400e242adcd4099f7cd004521ee92)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/nttrans.c | 10 | ||||
-rw-r--r-- | source3/smbd/open.c | 13 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 21 |
3 files changed, 27 insertions, 17 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index e2a2543e30..5d19d496fd 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -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) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index f1d1b776dd..5b615f01e2 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ad78c51fdf..a033833d00 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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); |