diff options
author | Andrew Tridgell <tridge@samba.org> | 2006-03-30 03:14:38 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:59:19 -0500 |
commit | 8260854a18fe784be01fa88be1678bf0e267720c (patch) | |
tree | df005e19184cdfd336dba6398119f7da111f268f /source4 | |
parent | 0d3a9493a27e7724a5c0337a5f93037114990956 (diff) | |
download | samba-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.c | 31 |
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); |