From e6ac820d81e632997726aab5b1937f71138f490a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Feb 2003 02:24:51 +0000 Subject: Fix delete on close semantics to match W2K. I (think:-) I understand it now :-). Thanks to Nir Livni for giving me the test case to track it down. Jeremy. (This used to be commit 41894489e82a474f4f8f66aa2c7a117ed05b33e1) --- source3/smbd/close.c | 16 +++++++++++ source3/smbd/trans2.c | 75 +++++++++++++++++++++------------------------------ 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; } @@ -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); -- cgit