s3: Fix lock ordering in notify_add
authorVolker Lendecke <vl@samba.org>
Wed, 14 Mar 2012 09:52:03 +0000 (10:52 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 15 Mar 2012 10:00:24 +0000 (11:00 +0100)
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>
source3/smbd/notify_internal.c

index 985ece36c1c1a06d715a990901da3de310bd3973..7891601bfe797337f217aa66b746298ef86e949d 100644 (file)
@@ -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;