summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-12-13 18:11:50 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:49 -0500
commitab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad (patch)
treed91dcd5c2a731925cec24e67c5a4e78dd3b7dac0 /source3/smbd/close.c
parent7d2771e758d4e8ef0adb45e55775b524de4dba9a (diff)
downloadsamba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.tar.gz
samba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.tar.bz2
samba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.zip
r12213: Final fix for #3303 - send rename messages to smbd's
that have open file handles to allow them to correctly implement delete on close. There is a further correctness fix I'm intending to add to this to cope with different share paths, but not right now... Jeremy. (This used to be commit 932e337db8788e75344e1c7cf1ef009d090cb039)
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r--source3/smbd/close.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d84b9f925b..407c607838 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -227,20 +227,43 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
*/
if (normal_close && delete_file) {
+ SMB_STRUCT_STAT sbuf;
+
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
fsp->fsp_name));
- if(SMB_VFS_UNLINK(conn,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
- * it when its last reference to this file went away. Hence
- * we log this but not at debug level zero.
- */
-
- DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
-with error %s\n", fsp->fsp_name, strerror(errno) ));
+
+ /* We can only delete the file if the name we have
+ is still valid and hasn't been renamed. */
+
+ if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
+ DEBUG(5,("close_file: file %s. Delete on close was set "
+ "and stat failed with error %s\n",
+ fsp->fsp_name, strerror(errno) ));
+ } else {
+ if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) {
+ DEBUG(5,("close_file: file %s. Delete on close was set and "
+ "dev and/or inode does not match\n",
+ fsp->fsp_name ));
+ DEBUG(5,("close_file: file %s. stored dev = %x, inode = %.0f "
+ "stat dev = %x, inode = %.0f\n",
+ fsp->fsp_name,
+ (unsigned int)fsp->dev, (double)fsp->inode,
+ (unsigned int)sbuf.st_dev, (double)sbuf.st_ino ));
+
+ } else if(SMB_VFS_UNLINK(conn,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
+ * it when its last reference to this file went away. Hence
+ * we log this but not at debug level zero.
+ */
+
+ DEBUG(5,("close_file: file %s. Delete on close was set "
+ "and unlink failed with error %s\n",
+ fsp->fsp_name, strerror(errno) ));
+ }
+ process_pending_change_notify_queue((time_t)0);
}
- process_pending_change_notify_queue((time_t)0);
}
talloc_free(lck);