s3:g_lock: keep old mylock on error and don't store new mylock on error
authorStefan Metzmacher <metze@samba.org>
Wed, 20 Dec 2017 07:41:09 +0000 (08:41 +0100)
committerRalph Boehme <slow@samba.org>
Wed, 10 Jan 2018 00:01:23 +0000 (01:01 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/lib/g_lock.c

index 68a9ab3b061fcb2dbea6419e3da106617e3f4902..4c42fb07bf5806cae7c7270bc0c741e87407305b 100644 (file)
@@ -200,6 +200,8 @@ static NTSTATUS g_lock_trylock(struct db_record *rec, struct server_id self,
        TDB_DATA data;
        size_t i;
        struct g_lock lck;
+       struct g_lock_rec _mylock;
+       struct g_lock_rec *mylock = NULL;
        NTSTATUS status;
        bool modified = false;
        bool ok;
@@ -242,11 +244,18 @@ static NTSTATUS g_lock_trylock(struct db_record *rec, struct server_id self,
                                status = NT_STATUS_WAS_LOCKED;
                                goto done;
                        }
+                       if (mylock != NULL) {
+                               status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+                               goto done;
+                       }
+                       _mylock = lock;
+                       mylock = &_mylock;
                        /*
                         * Remove "our" lock entry. Re-add it later
                         * with our new lock type.
                         */
                        g_lock_rec_del(&lck, i);
+                       modified = true;
                        continue;
                }
 
@@ -278,12 +287,18 @@ static NTSTATUS g_lock_trylock(struct db_record *rec, struct server_id self,
 
        modified = true;
 
+       _mylock = (struct g_lock_rec) {
+               .pid = self,
+               .lock_type = type
+       };
+       mylock = &_mylock;
+
        status = NT_STATUS_OK;
 done:
        if (modified) {
-               struct g_lock_rec mylock = { .pid = self, .lock_type = type };
                NTSTATUS store_status;
-               store_status = g_lock_store(rec, &lck, &mylock);
+
+               store_status = g_lock_store(rec, &lck, mylock);
                if (!NT_STATUS_IS_OK(store_status)) {
                        DBG_WARNING("g_lock_record_store failed: %s\n",
                                    nt_errstr(store_status));