summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_search.c')
-rw-r--r--source4/ntvfs/posix/pvfs_search.c93
1 files changed, 35 insertions, 58 deletions
diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c
index 07f2a0f127..7b0da321d3 100644
--- a/source4/ntvfs/posix/pvfs_search.c
+++ b/source4/ntvfs/posix/pvfs_search.c
@@ -23,6 +23,17 @@
#include "include/includes.h"
#include "vfs_posix.h"
+
+/*
+ destroy an open search
+*/
+static int pvfs_search_destructor(void *ptr)
+{
+ struct pvfs_search_state *search = ptr;
+ idr_remove(search->pvfs->idtree_search, search->handle);
+ return 0;
+}
+
/*
fill in a single search result for a given info level
*/
@@ -224,32 +235,6 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-/*
- return the next available search handle
-*/
-static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handle,
- uint_t max_handles)
-{
- struct pvfs_search_state *search;
-
- if (pvfs->search.num_active_searches >= max_handles) {
- return NT_STATUS_INSUFFICIENT_RESOURCES;
- }
-
- (*handle) = (pvfs->search.next_search_handle) & (max_handles-1);
-again:
- for (search=pvfs->search.open_searches;search;search=search->next) {
- if (*handle == search->handle) {
- *handle = ((*handle)+1) & (max_handles-1);
- goto again;
- }
- }
- pvfs->search.next_search_handle = ((*handle)+1) & (max_handles-1);
-
- return NT_STATUS_OK;
-}
-
-
/*
list files in a directory matching a wildcard pattern - old SMBsearch interface
*/
@@ -266,6 +251,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
const char *pattern;
NTSTATUS status;
struct pvfs_filename *name;
+ int id;
search_attrib = io->search_first.in.search_attrib;
pattern = io->search_first.in.pattern;
@@ -301,15 +287,19 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
/* we need to give a handle back to the client so it
can continue a search */
- status = pvfs_next_search_handle(pvfs, &search->handle, 0x100);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ id = idr_get_new(pvfs->idtree_search, search, 0x100);
+ if (id == -1) {
+ return NT_STATUS_INSUFFICIENT_RESOURCES;
}
-
+
+ search->pvfs = pvfs;
+ search->handle = id;
search->dir = dir;
search->current_index = 0;
search->search_attrib = search_attrib;
+ talloc_set_destructor(search, pvfs_search_destructor);
+
status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level,
&reply_count, search_private, callback);
if (!NT_STATUS_IS_OK(status)) {
@@ -323,9 +313,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
return STATUS_NO_MORE_FILES;
}
- pvfs->search.num_active_searches++;
talloc_steal(pvfs, search);
- DLIST_ADD(pvfs->search.open_searches, search);
return NT_STATUS_OK;
}
@@ -346,11 +334,8 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs,
handle = io->search_next.in.id.handle;
max_count = io->search_next.in.max_count;
- for (search=pvfs->search.open_searches; search; search = search->next) {
- if (search->handle == handle) break;
- }
-
- if (!search) {
+ search = idr_find(pvfs->idtree_search, handle);
+ if (search == NULL) {
/* we didn't find the search handle */
return NT_STATUS_INVALID_HANDLE;
}
@@ -369,7 +354,6 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs,
/* not matching any entries means end of search */
if (reply_count == 0) {
- DLIST_REMOVE(pvfs->search.open_searches, search);
talloc_free(search);
}
@@ -392,6 +376,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
const char *pattern;
NTSTATUS status;
struct pvfs_filename *name;
+ int id;
if (io->generic.level >= RAW_SEARCH_SEARCH) {
return pvfs_search_first_old(ntvfs, req, io, search_private, callback);
@@ -430,17 +415,19 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
return status;
}
- /* we need to give a handle back to the client so it
- can continue a search */
- status = pvfs_next_search_handle(pvfs, &search->handle, 0x10000);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ id = idr_get_new(pvfs->idtree_search, search, 0x10000);
+ if (id == -1) {
+ return NT_STATUS_INSUFFICIENT_RESOURCES;
}
-
+
+ search->pvfs = pvfs;
+ search->handle = id;
search->dir = dir;
search->current_index = 0;
search->search_attrib = search_attrib;
+ talloc_set_destructor(search, pvfs_search_destructor);
+
status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level,
&reply_count, search_private, callback);
if (!NT_STATUS_IS_OK(status)) {
@@ -463,9 +450,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
io->t2ffirst.out.end_of_search)) {
talloc_free(search);
} else {
- pvfs->search.num_active_searches++;
talloc_steal(pvfs, search);
- DLIST_ADD(pvfs->search.open_searches, search);
}
return NT_STATUS_OK;
@@ -491,11 +476,8 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
handle = io->t2fnext.in.handle;
- for (search=pvfs->search.open_searches; search; search = search->next) {
- if (search->handle == handle) break;
- }
-
- if (!search) {
+ search = idr_find(pvfs->idtree_search, handle);
+ if (search == NULL) {
/* we didn't find the search handle */
return NT_STATUS_INVALID_HANDLE;
}
@@ -544,7 +526,6 @@ found:
if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) ||
((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) &&
io->t2fnext.out.end_of_search)) {
- DLIST_REMOVE(pvfs->search.open_searches, search);
talloc_free(search);
}
@@ -565,16 +546,12 @@ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs,
handle = io->findclose.in.handle;
}
- for (search=pvfs->search.open_searches; search; search = search->next) {
- if (search->handle == handle) break;
- }
-
- if (!search) {
+ search = idr_find(pvfs->idtree_search, handle);
+ if (search == NULL) {
/* we didn't find the search handle */
return NT_STATUS_INVALID_HANDLE;
}
- DLIST_REMOVE(pvfs->search.open_searches, search);
talloc_free(search);
return NT_STATUS_OK;