diff options
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r-- | source3/smbd/close.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 56aad64391..c290ee6f89 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -99,7 +99,9 @@ static int close_filestruct(files_struct *fsp) static int close_normal_file(files_struct *fsp, BOOL normal_close) { - BOOL delete_on_close = fsp->delete_on_close; + share_mode_entry *share_entry = NULL; + size_t share_entry_count = 0; + BOOL delete_on_close = False; connection_struct *conn = fsp->conn; int err = 0; int err1 = 0; @@ -120,21 +122,25 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) return 0; } - lock_share_entry_fsp(fsp); - del_share_mode(fsp); - unlock_share_entry_fsp(fsp); + /* + * Lock the share entries, and determine if we should delete + * on close. If so delete whilst the lock is still in effect. + * This prevents race conditions with the file being created. JRA. + */ - if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) - release_file_oplock(fsp); + lock_share_entry_fsp(fsp); + share_entry_count = del_share_mode(fsp, &share_entry); - locking_close_file(fsp); + /* + * We delete on close if it's the last open, and the + * delete on close flag was set in the entry we just deleted. + */ - err = fd_close(conn, fsp); + if ((share_entry_count == 0) && share_entry && + GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) ) + delete_on_close = True; - /* check for magic scripts */ - if (normal_close) { - check_magic(fsp,conn); - } + safe_free(share_entry); /* * NT can set delete_on_close of the last open @@ -157,6 +163,21 @@ with error %s\n", fsp->fsp_name, strerror(errno) )); } } + unlock_share_entry_fsp(fsp); + + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + release_file_oplock(fsp); + + locking_close_file(fsp); + + err = fd_close(conn, fsp); + + /* check for magic scripts */ + if (normal_close) { + check_magic(fsp,conn); + } + + DEBUG(2,("%s closed file %s (numopen=%d) %s\n", conn->user,fsp->fsp_name, conn->num_files_open, err ? strerror(err) : "")); |