summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/messages.h1
-rw-r--r--source3/lib/dummysmbd.c4
-rw-r--r--source3/locking/locking.c4
-rw-r--r--source3/smbd/close.c1
-rw-r--r--source3/smbd/filename.c6
-rw-r--r--source3/smbd/server.c13
-rw-r--r--source3/smbd/statcache.c34
7 files changed, 63 insertions, 0 deletions
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 1c01ba08c2..223eca859b 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -72,6 +72,7 @@
#define MSG_SMB_INJECT_FAULT 3012
#define MSG_SMB_BLOCKING_LOCK_CANCEL 3013
#define MSG_SMB_NOTIFY 3014
+#define MSG_SMB_STAT_CACHE_DELETE 3015
/* winbind messages */
#define MSG_WINBIND_FINISHED 4001
diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c
index 442a612f93..c97dec5ef3 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/dummysmbd.c
@@ -53,3 +53,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
{
return NULL;
}
+
+void send_stat_cache_delete_message(const char *name)
+{
+}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 56d18a63ef..d2e8b7ef59 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -1281,6 +1281,10 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE
set_delete_on_close_lck(lck, delete_on_close, tok);
+ if (fsp->is_directory) {
+ send_stat_cache_delete_message(fsp->fsp_name);
+ }
+
TALLOC_FREE(lck);
return True;
}
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 8958878433..07f81f988e 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -431,6 +431,7 @@ static int close_directory(files_struct *fsp, enum file_close_type close_type)
become_user(fsp->conn, fsp->vuid);
became_user = True;
}
+ send_stat_cache_delete_message(fsp->fsp_name);
set_delete_on_close_lck(lck, True, &current_user.ut);
if (became_user) {
unbecome_user();
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index b69d2f3e5e..eb86a0efd1 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -462,6 +462,12 @@ NTSTATUS unix_convert(connection_struct *conn,
}
} /* end else */
+#ifdef DEVELOPER
+ if (VALID_STAT(st) && get_delete_on_close_flag(st.st_dev, st.st_ino)) {
+ return NT_STATUS_DELETE_PENDING;
+ }
+#endif
+
/*
* Add to the dirpath that we have resolved so far.
*/
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 4a242488da..e2f73285b3 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -83,6 +83,18 @@ static void smb_conf_updated(int msg_type, struct process_id src,
}
+/*******************************************************************
+ Delete a statcache entry.
+ ********************************************************************/
+
+static void smb_stat_cache_delete(int msg_type, struct process_id src,
+ void *buf, size_t len)
+{
+ const char *name = (const char *)buf;
+ DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
+ stat_cache_delete(name);
+}
+
/****************************************************************************
Terminate signal.
****************************************************************************/
@@ -422,6 +434,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
message_register(MSG_SHUTDOWN, msg_exit_server);
message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
+ message_register(MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete);
#ifdef DEVELOPER
message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault);
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index b453fdd544..1a2b7a8237 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -285,6 +285,40 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
}
}
+/***************************************************************************
+ Tell all smbd's to delete an entry.
+**************************************************************************/
+
+void send_stat_cache_delete_message(const char *name)
+{
+#ifdef DEVELOPER
+ message_send_all(conn_tdb_ctx(),
+ MSG_SMB_STAT_CACHE_DELETE,
+ name,
+ strlen(name)+1,
+ True,
+ NULL);
+#endif
+}
+
+/***************************************************************************
+ Delete an entry.
+**************************************************************************/
+
+void stat_cache_delete(const char *name)
+{
+ char *lname = strdup_upper(name);
+
+ if (!lname) {
+ return;
+ }
+ DEBUG(10,("stat_cache_delete: deleting name [%s] -> %s\n",
+ lname, name ));
+
+ tdb_delete_bystring(tdb_stat_cache, lname);
+ SAFE_FREE(lname);
+}
+
/***************************************************************
Compute a hash value based on a string key value.
The function returns the bucket index number for the hashed key.