s3: Fix a deadlock between smbd and ctdbd
authorVolker Lendecke <vl@samba.org>
Fri, 21 Jan 2011 09:30:13 +0000 (10:30 +0100)
committerVolker Lendecke <vlendec@samba.org>
Fri, 21 Jan 2011 11:29:21 +0000 (12:29 +0100)
Do the notification after we released the share mode lock. Inside notify_fname
we take out another tdb lock. With ctdb also accessing our databases, this can
lead to deadlocks. Putting this notify after the TALLOC_FREE(lck) above we
avoid locking two records simultaneously. Notifies are async and informational
only, so calling the notify_fname without holding the share mode lock should
not do any harm.

Autobuild-User: Volker Lendecke <vlendec@samba.org>
Autobuild-Date: Fri Jan 21 12:29:21 CET 2011 on sn-devel-104

source3/smbd/close.c

index 00bcef0a71689e89edd500c31742015840a5187f..a6610e58f1cf6ba6f144ba669ce2f2535bea57f6 100644 (file)
@@ -473,10 +473,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                status = map_nt_error_from_unix(errno);
        }
 
-       notify_fname(conn, NOTIFY_ACTION_REMOVED,
-                    FILE_NOTIFY_CHANGE_FILE_NAME,
-                    fsp->fsp_name->base_name);
-
        /* As we now have POSIX opens which can unlink
         * with other open files we may have taken
         * this code path with more than one share mode
@@ -495,6 +491,24 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        }
 
        TALLOC_FREE(lck);
+
+       if (delete_file) {
+               /*
+                * Do the notification after we released the share
+                * mode lock. Inside notify_fname we take out another
+                * tdb lock. With ctdb also accessing our databases,
+                * this can lead to deadlocks. Putting this notify
+                * after the TALLOC_FREE(lck) above we avoid locking
+                * two records simultaneously. Notifies are async and
+                * informational only, so calling the notify_fname
+                * without holding the share mode lock should not do
+                * any harm.
+                */
+               notify_fname(conn, NOTIFY_ACTION_REMOVED,
+                            FILE_NOTIFY_CHANGE_FILE_NAME,
+                            fsp->fsp_name->base_name);
+       }
+
        return status;
 }