diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-06-05 16:25:44 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-06-05 16:25:44 +1000 |
commit | fcc7372975757d19e9e4366a26396bf210bdf86a (patch) | |
tree | bd25c433da39b932475ba5f23db472d1b30f29b8 /source4/ntvfs | |
parent | e53ee270916a5a1e6d21c4275b5307f642ab2794 (diff) | |
download | samba-fcc7372975757d19e9e4366a26396bf210bdf86a.tar.gz samba-fcc7372975757d19e9e4366a26396bf210bdf86a.tar.bz2 samba-fcc7372975757d19e9e4366a26396bf210bdf86a.zip |
fixed handling of change notify buffer overruns
When the notify buffer overruns and there are no pending notify
requests, the notify buffer doesn't actually get destroyed, it just
gets put in a state where new notifies are discarded and the next
notify change request will return 0 changes.
Diffstat (limited to 'source4/ntvfs')
-rw-r--r-- | source4/ntvfs/posix/pvfs_notify.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 09aa0f64e6..3e6f442d61 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -34,6 +34,7 @@ struct pvfs_notify_buffer { struct notify_changes *changes; uint32_t max_buffer_size; uint32_t current_buffer_size; + bool overflowed; /* a list of requests waiting for events on this handle */ struct notify_pending { @@ -71,7 +72,7 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, while (notify_buffer->pending) { pvfs_notify_send(notify_buffer, NT_STATUS_OK, immediate); } - talloc_free(notify_buffer); + notify_buffer->overflowed = true; return; } @@ -88,6 +89,7 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, info->nttrans.out.num_changes = notify_buffer->num_changes; info->nttrans.out.changes = talloc_steal(req, notify_buffer->changes); notify_buffer->num_changes = 0; + notify_buffer->overflowed = false; notify_buffer->changes = NULL; notify_buffer->current_buffer_size = 0; @@ -133,6 +135,10 @@ static void pvfs_notify_callback(void *private_data, const struct notify_event * struct notify_changes *n2; char *new_path; + if (n->overflowed) { + return; + } + n2 = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); if (n2 == NULL) { /* nothing much we can do for this */ @@ -267,7 +273,8 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, DLIST_ADD_END(f->notify_buffer->pending, pending, struct notify_pending *); /* if the buffer is empty then start waiting */ - if (f->notify_buffer->num_changes == 0) { + if (f->notify_buffer->num_changes == 0 && + !f->notify_buffer->overflowed) { struct pvfs_wait *wait_handle; wait_handle = pvfs_wait_message(pvfs, req, -1, timeval_zero(), |