s3:locking:brlock: let validate_lock_entries keep entries for disconnected servers...
authorGregor Beck <gbeck@sernet.de>
Tue, 5 Mar 2013 13:49:28 +0000 (14:49 +0100)
committerMichael Adam <obnox@samba.org>
Thu, 18 Apr 2013 11:15:12 +0000 (13:15 +0200)
We should not remove locks of disconnected opens just like that.
When getting the byte range lock record for a newly connected file
handle, we still do the clean up, because in that situation,
disconnected entries are not valid any more.

Signed-off-by: Gregor Beck <gbeck@sernet.de>
Reviewed-by: Michael Adam <obnox@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/locking/brlock.c

index 7942b41fb6f9326a489760f5d39b0982e0b3f649..e95458989a815c608574bb16a0092c885d155548 100644 (file)
@@ -1650,7 +1650,8 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
 /****************************************************************************
  Ensure this set of lock entries is valid.
 ****************************************************************************/
-static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks)
+static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks,
+                                 bool keep_disconnected)
 {
        unsigned int i;
        unsigned int num_valid_entries = 0;
@@ -1688,13 +1689,21 @@ static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct
        }
 
        for (i = 0; i < *pnum_entries; i++) {
-               if (!exists[i]) {
-                       /* This process no longer exists - mark this
-                          entry as invalid by zeroing it. */
-                       ZERO_STRUCTP(&locks[i]);
-               } else {
+               if (exists[i]) {
                        num_valid_entries++;
+                       continue;
                }
+
+               if (keep_disconnected &&
+                   server_id_is_disconnected(&ids[i]))
+               {
+                       num_valid_entries++;
+                       continue;
+               }
+
+               /* This process no longer exists - mark this
+                  entry as invalid by zeroing it. */
+               ZERO_STRUCTP(&locks[i]);
        }
        TALLOC_FREE(frame);
 
@@ -1770,7 +1779,7 @@ static int brl_traverse_fn(struct db_record *rec, void *state)
 
        /* Ensure the lock db is clean of entries from invalid processes. */
 
-       if (!validate_lock_entries(&num_locks, &locks)) {
+       if (!validate_lock_entries(&num_locks, &locks, true)) {
                SAFE_FREE(locks);
                return -1; /* Terminate traversal */
        }
@@ -1963,10 +1972,16 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx,
                 * record with this fsp. Go through and ensure all entries
                 * are valid - remove any that don't.
                 * This makes the lockdb self cleaning at low cost.
+                *
+                * Note: Disconnected entries belong to disconnected
+                * durable handles. So at this point, we have a new
+                * handle on the file and the disconnected durable has
+                * already been closed (we are not a durable reconnect).
+                * So we need to clean the disconnected brl entry.
                 */
 
                if (!validate_lock_entries(&br_lck->num_locks,
-                                          &br_lck->lock_data)) {
+                                          &br_lck->lock_data, false)) {
                        SAFE_FREE(br_lck->lock_data);
                        TALLOC_FREE(br_lck);
                        return NULL;