summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
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);