summaryrefslogtreecommitdiff
path: root/source/smbd/close.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/close.c')
-rw-r--r--source/smbd/close.c91
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);
+}