Index: smbd/open.c =================================================================== --- smbd/open.c (revision 15948) +++ smbd/open.c (working copy) @@ -599,7 +599,7 @@ } /* - * 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 @@ * 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 @@ 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 @@ } /* 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 @@ 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; Index: smbd/nttrans.c =================================================================== --- smbd/nttrans.c (revision 15948) +++ smbd/nttrans.c (working copy) @@ -1652,11 +1652,11 @@ 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 @@ } 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) { Index: smbd/trans2.c =================================================================== --- smbd/trans2.c (revision 15948) +++ smbd/trans2.c (working copy) @@ -4020,15 +4020,19 @@ 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 @@ 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 @@ 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);