mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
r21092: Ok, that's the one that activates the Samba4 notify backend.
Now to clean up / fix lots of stuff. Volker
This commit is contained in:
parent
686345b7ed
commit
9e7443fa14
@ -669,6 +669,7 @@ typedef struct connection_struct {
|
||||
name_compare_entry *aio_write_behind_list; /* Per-share list of files to use aio write behind on. */
|
||||
struct dfree_cached_info *dfree_info;
|
||||
struct trans_state *pending_trans;
|
||||
struct notify_context *notify_ctx;
|
||||
} connection_struct;
|
||||
|
||||
struct current_user {
|
||||
|
@ -483,7 +483,10 @@ void file_free(files_struct *fsp)
|
||||
fsp->fh->ref_count--;
|
||||
}
|
||||
|
||||
TALLOC_FREE(fsp->notify);
|
||||
if (fsp->notify) {
|
||||
notify_remove(fsp->conn->notify_ctx, fsp);
|
||||
TALLOC_FREE(fsp->notify);
|
||||
}
|
||||
|
||||
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
|
||||
files_used--;
|
||||
|
@ -159,7 +159,8 @@ void change_notify_reply(const char *request_buf, uint32 max_param_count,
|
||||
}
|
||||
|
||||
NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param_count,
|
||||
uint32 filter, struct files_struct *fsp)
|
||||
uint32 filter, BOOL recursive,
|
||||
struct files_struct *fsp)
|
||||
{
|
||||
struct notify_change_request *request = NULL;
|
||||
struct notify_mid_map *map = NULL;
|
||||
@ -177,9 +178,7 @@ NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param_count,
|
||||
request->max_param_count = max_param_count;
|
||||
request->filter = filter;
|
||||
request->fsp = fsp;
|
||||
|
||||
request->backend_data = cnotify->notify_add(NULL, smbd_event_context(),
|
||||
fsp, &request->filter);
|
||||
request->backend_data = NULL;
|
||||
|
||||
DLIST_ADD_END(fsp->notify->requests, request,
|
||||
struct notify_change_request *);
|
||||
@ -343,6 +342,18 @@ void notify_action(connection_struct *conn, const char *parent,
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char *fullpath;
|
||||
|
||||
if (asprintf(&fullpath, "%s/%s/%s", conn->connectpath,
|
||||
parent, name) != -1) {
|
||||
notify_trigger(conn->notify_ctx, action, filter,
|
||||
fullpath);
|
||||
SAFE_FREE(fullpath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(lck = get_share_mode_lock(NULL, sbuf.st_dev, sbuf.st_ino,
|
||||
NULL, NULL))) {
|
||||
return;
|
||||
@ -405,20 +416,21 @@ void notify_action(connection_struct *conn, const char *parent,
|
||||
void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
|
||||
const char *path)
|
||||
{
|
||||
char *parent;
|
||||
const char *name;
|
||||
char *fullpath;
|
||||
|
||||
if (!parent_dirname_talloc(tmp_talloc_ctx(), path, &parent, &name)) {
|
||||
if (asprintf(&fullpath, "%s/%s", conn->connectpath, path) == -1) {
|
||||
DEBUG(0, ("asprintf failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
notify_action(conn, parent, name, filter, action);
|
||||
TALLOC_FREE(parent);
|
||||
notify_trigger(conn->notify_ctx, action, filter, fullpath);
|
||||
SAFE_FREE(fullpath);
|
||||
}
|
||||
|
||||
void notify_fsp(files_struct *fsp, uint32 action, char *name)
|
||||
void notify_fsp(files_struct *fsp, uint32 action, const char *name)
|
||||
{
|
||||
struct notify_change *change, *changes;
|
||||
char *name2;
|
||||
|
||||
if (fsp->notify == NULL) {
|
||||
/*
|
||||
@ -427,35 +439,12 @@ void notify_fsp(files_struct *fsp, uint32 action, char *name)
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsp->notify->requests != NULL) {
|
||||
/*
|
||||
* Someone is waiting for the change, trigger the reply
|
||||
* immediately.
|
||||
*
|
||||
* TODO: do we have to walk the lists of requests pending?
|
||||
*/
|
||||
|
||||
struct notify_change_request *req = fsp->notify->requests;
|
||||
struct notify_change onechange;
|
||||
|
||||
if (name == NULL) {
|
||||
/*
|
||||
* Catch-all change, possibly from notify_hash.c
|
||||
*/
|
||||
change_notify_reply(req->request_buf,
|
||||
req->max_param_count,
|
||||
-1, NULL);
|
||||
if (!(name2 = talloc_strdup(fsp->notify, name))) {
|
||||
DEBUG(0, ("talloc_strdup failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
onechange.action = action;
|
||||
onechange.name = name;
|
||||
|
||||
change_notify_reply(req->request_buf, req->max_param_count,
|
||||
1, &onechange);
|
||||
change_notify_remove_request(req);
|
||||
return;
|
||||
}
|
||||
string_replace(name2, '/', '\\');
|
||||
|
||||
/*
|
||||
* Someone has triggered a notify previously, queue the change for
|
||||
@ -468,6 +457,7 @@ void notify_fsp(files_struct *fsp, uint32 action, char *name)
|
||||
* W2k3 seems to store at most 30 changes.
|
||||
*/
|
||||
TALLOC_FREE(fsp->notify->changes);
|
||||
TALLOC_FREE(name2);
|
||||
fsp->notify->num_changes = -1;
|
||||
return;
|
||||
}
|
||||
@ -480,6 +470,7 @@ void notify_fsp(files_struct *fsp, uint32 action, char *name)
|
||||
fsp->notify, fsp->notify->changes,
|
||||
struct notify_change, fsp->notify->num_changes+1))) {
|
||||
DEBUG(0, ("talloc_realloc failed\n"));
|
||||
TALLOC_FREE(name2);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -487,14 +478,40 @@ void notify_fsp(files_struct *fsp, uint32 action, char *name)
|
||||
|
||||
change = &(fsp->notify->changes[fsp->notify->num_changes]);
|
||||
|
||||
if (!(change->name = talloc_strdup(changes, name))) {
|
||||
DEBUG(0, ("talloc_strdup failed\n"));
|
||||
return;
|
||||
}
|
||||
change->name = talloc_move(changes, &name2);
|
||||
change->action = action;
|
||||
fsp->notify->num_changes += 1;
|
||||
|
||||
if (fsp->notify->requests == NULL) {
|
||||
/*
|
||||
* Nobody is waiting, so don't send anything. The ot
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == NOTIFY_ACTION_OLD_NAME) {
|
||||
/*
|
||||
* We have to send the two rename events in one reply. So hold
|
||||
* the first part back.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Someone is waiting for the change, trigger the reply immediately.
|
||||
*
|
||||
* TODO: do we have to walk the lists of requests pending?
|
||||
*/
|
||||
|
||||
change_notify_reply(fsp->notify->requests->request_buf,
|
||||
fsp->notify->requests->max_param_count,
|
||||
fsp->notify->num_changes,
|
||||
fsp->notify->changes);
|
||||
|
||||
change_notify_remove_request(fsp->notify->requests);
|
||||
|
||||
TALLOC_FREE(fsp->notify->changes);
|
||||
fsp->notify->num_changes = 0;
|
||||
}
|
||||
|
||||
static void notify_message_callback(int msgtype, struct process_id pid,
|
||||
|
@ -1787,6 +1787,13 @@ int reply_ntrename(connection_struct *conn,
|
||||
don't allow a directory to be opened.
|
||||
****************************************************************************/
|
||||
|
||||
static void notify_callback(void *private_data, const struct notify_event *e)
|
||||
{
|
||||
files_struct *fsp = (files_struct *)private_data;
|
||||
DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name));
|
||||
notify_fsp(fsp, e->action, e->path);
|
||||
}
|
||||
|
||||
static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
char *outbuf, int length,
|
||||
int bufsize,
|
||||
@ -1801,6 +1808,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
files_struct *fsp;
|
||||
uint32 filter;
|
||||
NTSTATUS status;
|
||||
BOOL recursive;
|
||||
|
||||
if(setup_count < 6) {
|
||||
return ERROR_DOS(ERRDOS,ERRbadfunc);
|
||||
@ -1808,6 +1816,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
|
||||
fsp = file_fsp((char *)setup,4);
|
||||
filter = IVAL(setup, 0);
|
||||
recursive = (SVAL(setup, 6) != 0) ? True : False;
|
||||
|
||||
DEBUG(3,("call_nt_transact_notify_change\n"));
|
||||
|
||||
@ -1815,18 +1824,55 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
return ERROR_DOS(ERRDOS,ERRbadfid);
|
||||
}
|
||||
|
||||
DEBUG(3,("call_nt_transact_notify_change: notify change called on "
|
||||
"directory name = %s\n", fsp->fsp_name ));
|
||||
{
|
||||
char *filter_string;
|
||||
|
||||
if (!(filter_string = notify_filter_string(NULL, filter))) {
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
DEBUG(3,("call_nt_transact_notify_change: notify change "
|
||||
"called on %s, filter = %s, recursive = %d\n",
|
||||
fsp->fsp_name, filter_string, recursive));
|
||||
|
||||
TALLOC_FREE(filter_string);
|
||||
}
|
||||
|
||||
if((!fsp->is_directory) || (conn != fsp->conn)) {
|
||||
return ERROR_DOS(ERRDOS,ERRbadfid);
|
||||
}
|
||||
|
||||
if (fsp->notify == NULL) {
|
||||
char *fullpath;
|
||||
struct notify_entry e;
|
||||
|
||||
if (!(fsp->notify = TALLOC_ZERO_P(
|
||||
NULL, struct notify_change_buf))) {
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath,
|
||||
fsp->fsp_name) == -1) {
|
||||
DEBUG(0, ("asprintf failed\n"));
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
e.path = fullpath;
|
||||
e.filter = filter;
|
||||
e.subdir_filter = 0;
|
||||
if (recursive) {
|
||||
e.subdir_filter = filter;
|
||||
}
|
||||
|
||||
status = notify_add(fsp->conn->notify_ctx, &e, notify_callback,
|
||||
fsp);
|
||||
SAFE_FREE(fullpath);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(10, ("notify_add returned %s\n",
|
||||
nt_errstr(status)));
|
||||
return ERROR_NT(status);
|
||||
}
|
||||
}
|
||||
|
||||
if (fsp->notify->num_changes != 0) {
|
||||
@ -1840,8 +1886,6 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
* here.
|
||||
*/
|
||||
|
||||
SMB_ASSERT(fsp->notify->requests == NULL);
|
||||
|
||||
change_notify_reply(inbuf, max_param_count,
|
||||
fsp->notify->num_changes,
|
||||
fsp->notify->changes);
|
||||
@ -1861,7 +1905,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
|
||||
*/
|
||||
|
||||
status = change_notify_add_request(inbuf, max_param_count, filter,
|
||||
fsp);
|
||||
recursive, fsp);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ERROR_NT(status);
|
||||
}
|
||||
|
@ -946,6 +946,13 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
|
||||
set_conn_connectpath(conn,s);
|
||||
}
|
||||
|
||||
if ((!conn->printer) && (!conn->ipc)) {
|
||||
conn->notify_ctx = notify_init(conn->mem_ctx, server_id_self(),
|
||||
smbd_messaging_context(),
|
||||
smbd_event_context(),
|
||||
conn->params);
|
||||
}
|
||||
|
||||
/* ROOT Activities: */
|
||||
/* check number of connections */
|
||||
if (!claim_connection(conn,
|
||||
|
Loading…
Reference in New Issue
Block a user