summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-03-14 10:52:03 +0100
committerStefan Metzmacher <metze@samba.org>2012-03-15 11:00:24 +0100
commitf69c6920d400acc3a31b778ab6cdb6b7da67adef (patch)
treee4dab7812e254629aa3a3382ca5bcaaeefd9aa13 /source3/smbd
parenta1fd41d83407eb449f8e80e309910b402272bc2e (diff)
downloadsamba-f69c6920d400acc3a31b778ab6cdb6b7da67adef.tar.gz
samba-f69c6920d400acc3a31b778ab6cdb6b7da67adef.tar.bz2
samba-f69c6920d400acc3a31b778ab6cdb6b7da67adef.zip
s3: Fix lock ordering in notify_add
It's not necessary to keep the global notify record locked during the inotify and notify_onelevel.tdb operations. Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/notify_internal.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 985ece36c1..7891601bfe 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -515,22 +515,12 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
struct notify_list *listel;
size_t len;
int depth;
- struct db_record *rec;
/* see if change notify is enabled at all */
if (notify == NULL) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- status = notify_fetch_locked(notify, &rec);
- NT_STATUS_NOT_OK_RETURN(status);
-
- status = notify_load(notify, rec);
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(rec);
- return status;
- }
-
/* cope with /. on the end of the path */
len = strlen(e.path);
if (len > 1 && e.path[len-1] == '.' && e.path[len-2] == '/') {
@@ -579,11 +569,23 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
then we need to install it in the array used for the
intra-samba notify handling */
if (e.filter != 0 || e.subdir_filter != 0) {
- status = notify_add_array(notify, rec, &e, private_data, depth);
- }
+ struct db_record *rec;
+ status = notify_fetch_locked(notify, &rec);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ status = notify_load(notify, rec);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(rec);
+ goto done;
+ }
+ status = notify_add_array(notify, rec, &e, private_data,
+ depth);
+ TALLOC_FREE(rec);
+ }
+ status = NT_STATUS_OK;
done:
- talloc_free(rec);
talloc_free(tmp_path);
return status;