summaryrefslogtreecommitdiff
path: root/source3/smbd/close.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r--source3/smbd/close.c92
1 files changed, 68 insertions, 24 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index c37c2ceab2..d06cb3b5bb 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);
+}