diff options
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r-- | source3/smbd/close.c | 92 |
1 files changed, 68 insertions, 24 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index c37c2ceab2d..d06cb3b5bbd 100644 --- a/source3/smbd/close.c +++ b/source3/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,14 +89,16 @@ 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; int token; - 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); @@ -119,7 +113,10 @@ void close_file(files_struct *fsp, BOOL normal_close) del_share_mode(token, fsp); } - if(fd_attempt_close(fsp) == 0) + if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) + release_file_oplock(fsp); + + if(fd_attempt_close(fsp->fd_ptr,&err) == 0) last_reference = True; fsp->fd_ptr = NULL; @@ -129,7 +126,7 @@ void close_file(files_struct *fsp, BOOL normal_close) /* NT uses smbclose to start a print - weird */ if (normal_close && fsp->print_file) - print_file(conn, SNUM(conn), fsp); + print_file(conn, fsp); /* check for magic scripts */ if (normal_close) { @@ -144,7 +141,8 @@ void close_file(files_struct *fsp, BOOL normal_close) if (normal_close && last_reference && delete_on_close) { DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); - if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) { + if(dos_unlink(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 @@ -157,31 +155,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); @@ -190,5 +204,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); +} |