diff options
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r-- | source3/smbd/close.c | 138 |
1 files changed, 73 insertions, 65 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f2d54445b9..8a63d3b227 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -143,54 +143,15 @@ static void notify_deferred_opens(struct share_mode_lock *lck) } /**************************************************************************** - Close a file. - - close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE. - printing and magic scripts are only run on normal close. - delete on close is done on normal and shutdown close. + Deal with removing a share mode on last close. ****************************************************************************/ -static int close_normal_file(files_struct *fsp, enum file_close_type close_type) +static int close_remove_share_mode(files_struct *fsp, enum file_close_type close_type) { - BOOL delete_file = False; connection_struct *conn = fsp->conn; - int saved_errno = 0; - int err = 0; - int err1 = 0; + BOOL delete_file = False; struct share_mode_lock *lck; - remove_pending_lock_requests_by_fid(fsp); - - if (fsp->aio_write_behind) { - /* - * If we're finishing write behind on a close we can get a write - * error here, we must remember this. - */ - int ret = wait_for_aio_completion(fsp); - if (ret) { - saved_errno = ret; - err1 = -1; - } - } else { - cancel_aio_by_fsp(fsp); - } - - /* - * If we're flushing on a close we can get a write - * error here, we must remember this. - */ - - if (close_filestruct(fsp) == -1) { - saved_errno = errno; - err1 = -1; - } - - if (fsp->print_file) { - print_fsp_end(fsp, close_type); - file_free(fsp); - return 0; - } - /* * Lock the share entries, and determine if we should delete * on close. If so delete whilst the lock is still in effect. @@ -200,12 +161,12 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); if (lck == NULL) { - DEBUG(0, ("close_file: Could not get share mode lock for file %s\n", fsp->fsp_name)); + DEBUG(0, ("close_remove_share_mode: Could not get share mode lock for file %s\n", fsp->fsp_name)); return EINVAL; } if (!del_share_mode(lck, fsp)) { - DEBUG(0, ("close_file: Could not delete share entry for file %s\n", fsp->fsp_name)); + DEBUG(0, ("close_remove_share_mode: Could not delete share entry for file %s\n", fsp->fsp_name)); } delete_file = (lck->delete_on_close | lck->initial_delete_on_close); @@ -236,13 +197,13 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) lck->delete_token) { SMB_STRUCT_STAT sbuf; - DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); /* Become the user who requested the delete. */ if (!push_sec_ctx()) { - smb_panic("close_file: file %s. failed to push sec_ctx.\n"); + smb_panic("close_remove_share_mode: file %s. failed to push sec_ctx.\n"); } set_sec_ctx(lck->delete_token->uid, @@ -253,17 +214,17 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) /* 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 " + DEBUG(5,("close_remove_share_mode: 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 " + DEBUG(5,("close_remove_share_mode: 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 " + DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, inode = %.0f " "stat dev = %x, inode = %.0f\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, @@ -277,21 +238,80 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) * we log this but not at debug level zero. */ - DEBUG(5,("close_file: file %s. Delete on close was set " + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " "and unlink failed with error %s\n", fsp->fsp_name, strerror(errno) )); } } /* unbecome user. */ pop_sec_ctx(); - + process_pending_change_notify_queue((time_t)0); } TALLOC_FREE(lck); + return 0; +} + +/**************************************************************************** + Close a file. + + close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE. + printing and magic scripts are only run on normal close. + delete on close is done on normal and shutdown close. +****************************************************************************/ + +static int close_normal_file(files_struct *fsp, enum file_close_type close_type) +{ + connection_struct *conn = fsp->conn; + int saved_errno = 0; + int err = 0; + int err1 = 0; - if(fsp->oplock_type) + remove_pending_lock_requests_by_fid(fsp); + + if (fsp->aio_write_behind) { + /* + * If we're finishing write behind on a close we can get a write + * error here, we must remember this. + */ + int ret = wait_for_aio_completion(fsp); + if (ret) { + saved_errno = ret; + err1 = -1; + } + } else { + cancel_aio_by_fsp(fsp); + } + + /* + * If we're flushing on a close we can get a write + * error here, we must remember this. + */ + + if (close_filestruct(fsp) == -1) { + saved_errno = errno; + err1 = -1; + } + + if (fsp->print_file) { + print_fsp_end(fsp, close_type); + file_free(fsp); + return 0; + } + + /* If this is an old DOS or FCB open and we have multiple opens on + the same handle we only have one share mode. Ensure we only remove + the share mode on the last close. */ + + if (fsp->fh->ref_count == 1) { + /* Should we return on error here... ? */ + close_remove_share_mode(fsp, close_type); + } + + if(fsp->oplock_type) { release_file_oplock(fsp); + } locking_close_file(fsp); @@ -323,9 +343,6 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) conn->num_files_open, (err == -1 || err1 == -1) ? strerror(saved_errno) : "")); - if (fsp->fsp_name) - string_free(&fsp->fsp_name); - file_free(fsp); if (err == -1 || err1 == -1) { @@ -410,11 +427,6 @@ static int close_directory(files_struct *fsp, enum file_close_type close_type) * Do the code common to files and directories. */ close_filestruct(fsp); - - if (fsp->fsp_name) { - string_free(&fsp->fsp_name); - } - file_free(fsp); return 0; } @@ -429,10 +441,6 @@ static int close_stat(files_struct *fsp) * Do the code common to files and directories. */ close_filestruct(fsp); - - if (fsp->fsp_name) - string_free(&fsp->fsp_name); - file_free(fsp); return 0; } |