diff options
author | Jeremy Allison <jra@samba.org> | 2005-12-13 18:11:50 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:05:49 -0500 |
commit | ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad (patch) | |
tree | d91dcd5c2a731925cec24e67c5a4e78dd3b7dac0 /source3/smbd/close.c | |
parent | 7d2771e758d4e8ef0adb45e55775b524de4dba9a (diff) | |
download | samba-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.c | 45 |
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); |