diff options
Diffstat (limited to 'source/smbd/close.c')
-rw-r--r-- | source/smbd/close.c | 91 |
1 files changed, 68 insertions, 23 deletions
diff --git a/source/smbd/close.c b/source/smbd/close.c index f588f248487..905b1c5b947 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -23,9 +23,6 @@ extern int DEBUGLEVEL; -extern int32 global_oplocks_open; - - /**************************************************************************** run a file if it is a magic script ****************************************************************************/ @@ -72,6 +69,8 @@ static void close_filestruct(files_struct *fsp) { connection_struct *conn = fsp->conn; + flush_write_cache(fsp, CLOSE_FLUSH); + fsp->open = False; fsp->is_directory = False; @@ -80,13 +79,6 @@ static void close_filestruct(files_struct *fsp) free((char *)fsp->wbmpx_ptr); fsp->wbmpx_ptr = NULL; } - -#if WITH_MMAP - if(fsp->mmap_ptr) { - munmap(fsp->mmap_ptr,fsp->mmap_size); - fsp->mmap_ptr = NULL; - } -#endif } /**************************************************************************** @@ -97,13 +89,15 @@ static void close_filestruct(files_struct *fsp) the closing of the connection. In the latter case printing and magic scripts are not run. ****************************************************************************/ -void close_file(files_struct *fsp, BOOL normal_close) + +static int close_normal_file(files_struct *fsp, BOOL normal_close) { SMB_DEV_T dev = fsp->fd_ptr->dev; SMB_INO_T inode = fsp->fd_ptr->inode; - BOOL last_reference = False; - BOOL delete_on_close = fsp->fd_ptr->delete_on_close; + BOOL last_reference = False; + BOOL delete_on_close = fsp->fd_ptr->delete_on_close; connection_struct *conn = fsp->conn; + int err = 0; remove_pending_lock_requests_by_fid(fsp); @@ -118,10 +112,15 @@ void close_file(files_struct *fsp, BOOL normal_close) del_share_mode(fsp); } - if(fd_attempt_close(fsp) == 0) + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + release_file_oplock(fsp); + + locking_close_file(fsp); + + if(fd_attempt_close(fsp, &err) == 0) last_reference = True; - fsp->fd_ptr = NULL; + fsp->fd_ptr = NULL; if (lp_share_modes(SNUM(conn))) unlock_share_entry(conn, dev, inode); @@ -161,31 +160,47 @@ with error %s\n", fsp->fsp_name, strerror(errno) )); } } - if(fsp->granted_oplock == True) - global_oplocks_open--; - - fsp->sent_oplock_break = False; - - DEBUG(2,("%s closed file %s (numopen=%d)\n", + DEBUG(2,("%s closed file %s (numopen=%d) %s\n", conn->user,fsp->fsp_name, - conn->num_files_open)); + conn->num_files_open, err ? strerror(err) : "")); if (fsp->fsp_name) { string_free(&fsp->fsp_name); } file_free(fsp); + + return err; } /**************************************************************************** Close a directory opened by an NT SMB call. ****************************************************************************/ -void close_directory(files_struct *fsp) +static int close_directory(files_struct *fsp, BOOL normal_close) { remove_pending_change_notify_requests_by_fid(fsp); /* + * NT can set delete_on_close of the last open + * reference to a directory also. + */ + + if (normal_close && fsp->directory_delete_on_close) { + BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name); + DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n", + fsp->fsp_name, ok ? "succeeded" : "failed" )); + + /* + * Ensure we remove any change notify requests that would + * now fail as the directory has been deleted. + */ + + if(ok) + remove_pending_change_notify_requests_by_filename(fsp); + } + + /* * Do the code common to files and directories. */ close_filestruct(fsp); @@ -194,5 +209,35 @@ void close_directory(files_struct *fsp) string_free(&fsp->fsp_name); file_free(fsp); + + return 0; +} + +/**************************************************************************** + Close a file opened with null permissions in order to read permissions. +****************************************************************************/ + +static int close_statfile(files_struct *fsp, BOOL normal_close) +{ + close_filestruct(fsp); + + if (fsp->fsp_name) + string_free(&fsp->fsp_name); + + file_free(fsp); + + return 0; } +/**************************************************************************** + Close a directory opened by an NT SMB call. +****************************************************************************/ + +int close_file(files_struct *fsp, BOOL normal_close) +{ + if(fsp->is_directory) + return close_directory(fsp, normal_close); + else if(fsp->stat_open) + return close_statfile(fsp, normal_close); + return close_normal_file(fsp, normal_close); +} |