r15949: Patch for bug #3308 to stop us returning duplicate
authorJeremy Allison <jra@samba.org>
Tue, 30 May 2006 05:08:15 +0000 (05:08 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:17:14 +0000 (11:17 -0500)
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)

source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/trans2.c

index e2a2543e3033df278260474da35fb490d38a0027..5d19d496fd93e4c975dea9cd5b1df5cd596b3910 100644 (file)
@@ -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) {
index f1d1b776dd2b509b14d02114b59441ee7bea27f0..5b615f01e2524fed43d4783f77b06412a0dda476 100644 (file)
@@ -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;
index ad78c51fdf464c0274ef8c707620609511916020..a033833d00096dd039d222ed516fcd6f5682081d 100644 (file)
@@ -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);