Fix delete on close semantics to match W2K. I (think:-) I understand it now :-).
authorJeremy Allison <jra@samba.org>
Tue, 11 Feb 2003 02:24:51 +0000 (02:24 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 11 Feb 2003 02:24:51 +0000 (02:24 +0000)
Thanks to Nir Livni <nirl@cyber-ark.com> for giving me the test case to
track it down.
Jeremy.

source/smbd/close.c
source/smbd/trans2.c

index b0620febef9baa471306a2c1b70cff1319877adc..4798d62db8559b3a54f63a67a2049ba616f72810 100644 (file)
@@ -145,6 +145,22 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
         */
 
        lock_share_entry_fsp(fsp);
+
+       if (fsp->delete_on_close) {
+
+               /*
+                * Modify the share mode entry for all files open
+                * on this device and inode to tell other smbds we have
+                * changed the delete on close flag. The last closer will delete the file
+                * if flag is set.
+                */
+
+               NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close);
+               if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
+                       DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n",
+                               fsp->fsp_name ));
+       }
+
        share_entry_count = del_share_mode(fsp, &share_entry);
 
        DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
index b9956370c2fb8ccebc75e84f28e58e0e4066211d..155c9963146ee684d6177db7eda33d5dd7beb759 100644 (file)
@@ -2101,59 +2101,39 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
                DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
                        delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
        } else {
+               fsp->delete_on_close = delete_on_close;
+               DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
+                       delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+       }
 
-               files_struct *iterate_fsp;
-
-               /*
-                * Modify the share mode entry for all files open
-                * on this device and inode to tell other smbds we have 
-                * changed the delete on close flag. This will be noticed
-                * in the close code, the last closer will delete the file
-                * if flag is set.
-                */
-
-               DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
-                                       delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+       return NT_STATUS_OK;
+}
 
-               if (lock_share_entry_fsp(fsp) == False)
-                               return NT_STATUS_ACCESS_DENIED;
+/****************************************************************************
+ Sets the delete on close flag over all share modes on this file.
+ Modify the share mode entry for all files open
+ on this device and inode to tell other smbds we have
+ changed the delete on close flag. This will be noticed
+ in the close code, the last closer will delete the file
+ if flag is set.
+****************************************************************************/
 
-               if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
-                       DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
-                                       fsp->fsp_name ));
-                       unlock_share_entry_fsp(fsp);
-                       return NT_STATUS_ACCESS_DENIED;
-               }
+NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
+{
+       DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
+               delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
 
-               /*
-                * Release the lock.
-                */
+       if (lock_share_entry_fsp(fsp) == False)
+               return NT_STATUS_ACCESS_DENIED;
 
+       if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
+               DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
+                       fsp->fsp_name ));
                unlock_share_entry_fsp(fsp);
-
-               /*
-                * Go through all files we have open on the same device and
-                * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
-                * Other smbd's that have this file open will look in the share_mode on close.
-                * take care of this (rare) case in close_file(). See the comment there.
-                * NB. JRA. We don't really need to do this anymore - all should be taken
-                * care of in the share_mode changes in the tdb.
-                */
-
-               for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
-                               iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
-                                               fsp->delete_on_close = delete_on_close;
-
-               /*
-                * Set the delete on close flag in the fsp.
-                */
-               fsp->delete_on_close = delete_on_close;
-
-               DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
-                       delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
-
+               return NT_STATUS_ACCESS_DENIED;
        }
 
+       unlock_share_entry_fsp(fsp);
        return NT_STATUS_OK;
 }
 
@@ -2531,6 +2511,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
 
                        status = set_delete_on_close_internal(fsp, delete_on_close);
  
+                       if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
+                               return ERROR_NT(status);
+
+                       /* The set is across all open files on this dev/inode pair. */
+                       status =set_delete_on_close_over_all(fsp, delete_on_close);
                        if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
                                return ERROR_NT(status);