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)
committerKarolin Seeger <kseeger@samba.org>
Wed, 19 Jun 2013 08:55:34 +0000 (10:55 +0200)
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 3b7f57a78c080333dd9dda4b7ec57a300caccbf2..82b96eb3ecadf867d2e70875dd050ace77ba15c7 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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_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) {