summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2006-03-30 03:14:38 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:59:19 -0500
commit8260854a18fe784be01fa88be1678bf0e267720c (patch)
treedf005e19184cdfd336dba6398119f7da111f268f /source4
parent0d3a9493a27e7724a5c0337a5f93037114990956 (diff)
downloadsamba-8260854a18fe784be01fa88be1678bf0e267720c.tar.gz
samba-8260854a18fe784be01fa88be1678bf0e267720c.tar.bz2
samba-8260854a18fe784be01fa88be1678bf0e267720c.zip
r14796: handle overflows in the notify buffer. The pending events are dumped
and the notify buffer removed (This used to be commit a4c0e23f9dc5049e7d6df3bf3d3ee694f715ce05)
Diffstat (limited to 'source4')
-rw-r--r--source4/ntvfs/posix/pvfs_notify.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c
index a41a2d3cd2..121ba499b3 100644
--- a/source4/ntvfs/posix/pvfs_notify.c
+++ b/source4/ntvfs/posix/pvfs_notify.c
@@ -52,7 +52,21 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS
struct ntvfs_request *req;
struct smb_notify *info;
- if (pending == NULL) return;
+ if (notify_buffer->current_buffer_size > notify_buffer->max_buffer_size &&
+ notify_buffer->num_changes != 0) {
+ /* on buffer overflow return no changes and destroys the notify buffer */
+ notify_buffer->num_changes = 0;
+ while (notify_buffer->pending) {
+ pvfs_notify_send(notify_buffer, NT_STATUS_OK);
+ }
+ talloc_free(notify_buffer);
+ return;
+ }
+
+ /* see if there is anyone waiting */
+ if (notify_buffer->pending == NULL) {
+ return;
+ }
DLIST_REMOVE(notify_buffer->pending, pending);
@@ -67,8 +81,6 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS
talloc_free(pending);
- DEBUG(0,("sending %d changes\n", info->out.num_changes));
-
if (info->out.num_changes != 0) {
status = NT_STATUS_OK;
}
@@ -96,14 +108,23 @@ static int pvfs_notify_destructor(void *ptr)
static void pvfs_notify_callback(void *private, const struct notify_event *ev)
{
struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer);
+ size_t len;
n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1);
n->changes[n->num_changes].action = ev->action;
n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path);
n->num_changes++;
- DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action));
+ /*
+ work out how much room this will take in the buffer
+ */
+ len = 12 + strlen_m(ev->path)*2;
+ if (len & 3) {
+ len += 4 - (len & 3);
+ }
+ n->current_buffer_size += len;
+ /* send what we have */
pvfs_notify_send(n, NT_STATUS_OK);
}
@@ -187,6 +208,8 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs,
NT_STATUS_NOT_OK_RETURN(status);
}
+ f->notify_buffer->max_buffer_size = info->in.buffer_size;
+
pending = talloc(f->notify_buffer, struct notify_pending);
NT_STATUS_HAVE_NO_MEMORY(pending);