Clean error paths in opendir and fd_opendir by only setting handle data on success.
authorJeremy Allison <jra@samba.org>
Tue, 9 Apr 2013 17:29:47 +0000 (10:29 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 11 Apr 2013 16:49:41 +0000 (09:49 -0700)
Pass extra struct dirsort_privates * to open_and_sort_dir() function
to avoid it having to re-read the handle data.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/modules/vfs_dirsort.c

index 3ea720fc115b0f29f6e98fa1de819691daec72fb..d6f19b52ecdf0b18733cfb03642802803bcdc89a 100644 (file)
@@ -40,7 +40,8 @@ static void free_dirsort_privates(void **datap) {
        TALLOC_FREE(*datap);
 }
 
-static bool open_and_sort_dir (vfs_handle_struct *handle)
+static bool open_and_sort_dir(vfs_handle_struct *handle,
+                               struct dirsort_privates *data)
 {
        struct stat dir_stat;
        unsigned int i;
@@ -115,14 +116,15 @@ static DIR *dirsort_opendir(vfs_handle_struct *handle,
 
        data->fd = dirfd(data->source_directory);
 
-       SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
-                               struct dirsort_privates, return NULL);
-
-       if (!open_and_sort_dir(handle)) {
+       if (!open_and_sort_dir(handle, data)) {
                SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
+               TALLOC_FREE(data);
                return NULL;
        }
 
+       SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
+                               struct dirsort_privates, return NULL);
+
        return data->source_directory;
 }
 
@@ -153,16 +155,17 @@ static DIR *dirsort_fdopendir(vfs_handle_struct *handle,
 
        data->fd = dirfd(data->source_directory);
 
-       SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
-                               struct dirsort_privates, return NULL);
-
-       if (!open_and_sort_dir(handle)) {
+       if (!open_and_sort_dir(handle, data)) {
                SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
+               TALLOC_FREE(data);
                /* fd is now closed. */
                fsp->fh->fd = -1;
                return NULL;
        }
 
+       SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
+                               struct dirsort_privates, return NULL);
+
        return data->source_directory;
 }
 
@@ -185,7 +188,7 @@ static struct dirent *dirsort_readdir(vfs_handle_struct *handle,
 
        /* throw away cache and re-read the directory if we've changed */
        if (current_mtime > data->mtime) {
-               open_and_sort_dir(handle);
+               open_and_sort_dir(handle, data);
        }
 
        if (data->pos >= data->number_of_entries) {