first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba-autobuild/.git] / source3 / smbd / close.c
index c37c2ceab2de15176e2d33ac53449c7ba3424375..d06cb3b5bbdf80a5d44f7859e15138c06ec4c2b5 100644 (file)
@@ -23,9 +23,6 @@
 
 extern int DEBUGLEVEL;
 
-extern int32 global_oplocks_open;
-
-
 /****************************************************************************
 run a file if it is a magic script
 ****************************************************************************/
@@ -72,6 +69,8 @@ static void close_filestruct(files_struct *fsp)
 {   
        connection_struct *conn = fsp->conn;
     
+    flush_write_cache(fsp, CLOSE_FLUSH);
+
        fsp->open = False;
        fsp->is_directory = False; 
     
@@ -80,13 +79,6 @@ static void close_filestruct(files_struct *fsp)
                free((char *)fsp->wbmpx_ptr);
                fsp->wbmpx_ptr = NULL; 
        }  
-     
-#if WITH_MMAP
-       if(fsp->mmap_ptr) {
-               munmap(fsp->mmap_ptr,fsp->mmap_size);
-               fsp->mmap_ptr = NULL;
-       }  
-#endif 
 }    
 
 /****************************************************************************
@@ -97,14 +89,16 @@ static void close_filestruct(files_struct *fsp)
  the closing of the connection. In the latter case printing and
  magic scripts are not run.
 ****************************************************************************/
-void close_file(files_struct *fsp, BOOL normal_close)
+
+static int close_normal_file(files_struct *fsp, BOOL normal_close)
 {
        SMB_DEV_T dev = fsp->fd_ptr->dev;
        SMB_INO_T inode = fsp->fd_ptr->inode;
        int token;
-    BOOL last_reference = False;
-    BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
+       BOOL last_reference = False;
+       BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
        connection_struct *conn = fsp->conn;
+       int err = 0;
 
        remove_pending_lock_requests_by_fid(fsp);
 
@@ -119,7 +113,10 @@ void close_file(files_struct *fsp, BOOL normal_close)
                del_share_mode(token, fsp);
        }
 
-       if(fd_attempt_close(fsp) == 0)
+       if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+               release_file_oplock(fsp);
+
+       if(fd_attempt_close(fsp->fd_ptr,&err) == 0)
                last_reference = True;
 
     fsp->fd_ptr = NULL;
@@ -129,7 +126,7 @@ void close_file(files_struct *fsp, BOOL normal_close)
 
        /* NT uses smbclose to start a print - weird */
        if (normal_close && fsp->print_file)
-               print_file(conn, SNUM(conn), fsp);
+               print_file(conn, fsp);
 
        /* check for magic scripts */
        if (normal_close) {
@@ -144,7 +141,8 @@ void close_file(files_struct *fsp, BOOL normal_close)
     if (normal_close && last_reference && delete_on_close) {
         DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
            fsp->fsp_name));
-               if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) {
+               if(dos_unlink(fsp->fsp_name) != 0) {
+
           /*
            * This call can potentially fail as another smbd may have
            * had the file open with delete on close set and deleted
@@ -157,30 +155,46 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
         }
     }
 
-       if(fsp->granted_oplock == True)
-               global_oplocks_open--;
-
-       fsp->sent_oplock_break = False;
-
-       DEBUG(2,("%s closed file %s (numopen=%d)\n",
+       DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
                 conn->user,fsp->fsp_name,
-                conn->num_files_open));
+                conn->num_files_open, err ? strerror(err) : ""));
 
        if (fsp->fsp_name) {
                string_free(&fsp->fsp_name);
        }
 
        file_free(fsp);
+
+       return err;
 }
 
 /****************************************************************************
  Close a directory opened by an NT SMB call. 
 ****************************************************************************/
   
-void close_directory(files_struct *fsp)
+static int close_directory(files_struct *fsp, BOOL normal_close)
 {
        remove_pending_change_notify_requests_by_fid(fsp);
 
+       /*
+        * NT can set delete_on_close of the last open
+        * reference to a directory also.
+        */
+
+       if (normal_close && fsp->directory_delete_on_close) {
+               BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
+               DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
+                       fsp->fsp_name, ok ? "succeeded" : "failed" ));
+
+               /*
+                * Ensure we remove any change notify requests that would
+                * now fail as the directory has been deleted.
+                */
+
+               if(ok)
+                       remove_pending_change_notify_requests_by_filename(fsp);
+    }
+
        /*
         * Do the code common to files and directories.
         */
@@ -190,5 +204,35 @@ void close_directory(files_struct *fsp)
                string_free(&fsp->fsp_name);
        
        file_free(fsp);
+
+       return 0;
+}
+
+/****************************************************************************
+ Close a file opened with null permissions in order to read permissions.
+****************************************************************************/
+
+static int close_statfile(files_struct *fsp, BOOL normal_close)
+{
+       close_filestruct(fsp);
+       
+       if (fsp->fsp_name)
+               string_free(&fsp->fsp_name);
+       
+       file_free(fsp);
+
+       return 0;
 }
 
+/****************************************************************************
+ Close a directory opened by an NT SMB call. 
+****************************************************************************/
+  
+int close_file(files_struct *fsp, BOOL normal_close)
+{
+       if(fsp->is_directory)
+               return close_directory(fsp, normal_close);
+       else if(fsp->stat_open)
+               return close_statfile(fsp, normal_close);
+       return close_normal_file(fsp, normal_close);
+}