VFS connection data cleanup with multiple modules
Constantine Vetoshev
gepardcv at gmail.com
Wed Oct 1 19:46:34 GMT 2008
On Tue, Sep 30, 2008 at 4:54 PM, Jeremy Allison <jra at samba.org> wrote:
>> When I disconnect from the share, I expect that release_data_1 and
>> release_data_2 both run, but logging shows that only release_data_1
>> runs. I can force release_data_2 to run by putting an explicit call to
>> it from a disconnect callback for vfs_object_2, but that doesn't seem
>> right.
>>
>> Am I missing something about how the release functions should work?
>
> It should get called from conn_free_internal() when the
> connection struct is removed. See this code :
>
> /* Free vfs_connection_struct */
> handle = conn->vfs_handles;
> while(handle) {
> DLIST_REMOVE(conn->vfs_handles, handle);
> thandle = handle->next;
> if (handle->free_data)
> handle->free_data(&handle->data);
> handle = thandle;
> }
>
> which should call all the handle release functions in
> reverse order of registration.
After poking at the code with gdb, I think I see a minor bug here.
Before the loop enters, conn->vfs_handles looks good, and
conn->vfs_handles->next also looks correct (as do all subsequent
->next pointers). Then, in the first iteration, after DLIST_REMOVE,
handle->next is NULL, so thandle is set to NULL. Looking at the
implementation of DLIST_REMOVE, I understand why: the p argument sets
its next and prev pointers to NULL if list != p, which it definitely
is not after list gets assigned to p->next. The code then sets handle
to thandle (which is NULL), and the loop terminates after checking
handle. In effect, free_data gets called on just the first handle.
A trivial workaround is to just set thandle before calling DLIST_REMOVE.
This code hasn't changed from 3.0.28a and 3.2.4, so the problem should
affect 3.2.4.
More information about the samba-technical
mailing list