[Gluster-devel] [PATCH v9] vfs_glusterfs: Samba VFS module for glusterfs
Anand Avati
avati at redhat.com
Wed May 29 20:54:20 UTC 2013
On 5/29/13 1:19 PM, Jeremy Allison wrote:
> On Wed, May 29, 2013 at 12:23:04PM -0700, Anand Avati wrote:
>>
>> We just uncovered this issue in our QE testing -
>>
>> On Wed, May 29, 2013 at 4:21 AM, Anand Avati <avati at redhat.com> wrote:
>> +static DIR *vfs_gluster_fdopendir(struct vfs_handle_struct *handle,
>> + files_struct *fsp, const char *mask,
>> + uint32 attributes)
>> +{
>> + return (DIR *) glfd_fd_get(fsp->fh->fd);
>> +}
>>
>> When code takes this vfs_fdopendir() path (happened when testing
>> fsstress, most of the times vfs_opendir() is called - not sure why),
>> we are just passing a pointer of glfs_fd structure ...
>
> The vfs_fdopendir() will get called when SMB2 is being
> used and a directory listing is being done on an open
> SMB2 directory handle.
>
>> +static int vfs_gluster_closedir(struct vfs_handle_struct *handle,
>> DIR *dirp)
>> +{
>> + return glfs_closedir((void *)dirp);
>> +}
>>
>> ... and Samba does a vfs_closedir() _and_ vfs_close(), essentially
>> doing a double free on the glfs_fd structure.
>
> Let me look into the mainline Samba code here. As I recall
> it should set the fsp->fh->fd to -1 after doing the vfs_closedir()
> when the file handle on the directory is closed. Thus the
> vfs_close should see the fsp->fh->fd as already zero and
> just ignore it.
>
Our testing was on a backport of this patch in v3-6-stable, which has
this interesting piece of code:
void dptr_CloseDir(files_struct *fsp)
{
if (fsp->dptr) {
/*
* Ugly hack. We have defined fdopendir to return ENOSYS if dirfd also
isn't
* present. I hate Solaris. JRA.
*/
#ifdef HAVE_DIRFD
if (fsp->fh->fd != -1 &&
fsp->dptr->dir_hnd &&
dirfd(fsp->dptr->dir_hnd->dir)) {
/* The call below closes the underlying fd. */
fsp->fh->fd = -1;
}
#endif
dptr_close_internal(fsp->dptr);
fsp->dptr = NULL;
}
}
1. The code is calling dirfd() on the value returned by vfs_fdopendir()
and vfs_opendir(). We return 'struct glfs_fd' typecasted to DIR *
(technique I copied from vfs_ceph). So dirfd() is getting called against
'struct glfs_fd *' in this case.
2. The logic around dirfd() is checking for > 0 as the condition of a
valid fd. Since dirfd is now working on a differnet object, it probably
picked an arbitrary location in glfs_fd and found the value to be 0, and
this lead to fsp->fh->fd to _not_ be 0.
3. In our test case the fd number returned by vfs_gluster for the
initial open file _was_ 0. That dirfd() condition needs a fix, I think?
I don't know if the master branch has equivalent code elsewhere,
couldn't find it easily..
Avati
More information about the Gluster-devel
mailing list