summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-02-11 02:24:45 +0000
committerJeremy Allison <jra@samba.org>2003-02-11 02:24:45 +0000
commitcc99ea0ef00a42b0bfc96b2d1e3faeae5871c582 (patch)
tree7ed4f85d190357fa9a7748c203d7283517c588f7 /source3
parentf687e95377e336691df3b4751d63d06633b97df8 (diff)
downloadsamba-cc99ea0ef00a42b0bfc96b2d1e3faeae5871c582.tar.gz
samba-cc99ea0ef00a42b0bfc96b2d1e3faeae5871c582.tar.bz2
samba-cc99ea0ef00a42b0bfc96b2d1e3faeae5871c582.zip
Fix delete on close semantics to match W2K. I (think:-) I understand it now :-).
Thanks to Nir Livni <nirl@cyber-ark.com> for giving me the test case to track it down. Jeremy. (This used to be commit c98ebb3031649203e607264ecb15722adf55af58)
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/close.c16
-rw-r--r--source3/smbd/trans2.c75
2 files changed, 46 insertions, 45 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index b0620febef..4798d62db8 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -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",
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index b9956370c2..155c996314 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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;
}
@@ -2534,6 +2514,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
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);
+
break;
}