g_lock: Add g_lock_write_data
authorVolker Lendecke <vl@samba.org>
Tue, 23 May 2017 10:32:24 +0000 (12:32 +0200)
committerVolker Lendecke <vl@samba.org>
Thu, 15 Jun 2017 11:19:14 +0000 (13:19 +0200)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/g_lock.h
source3/lib/g_lock.c

index 998a9da8544c400dabbc0a3d76ae8d66c2ed52df..f79e0ceef9997f476dc75387d79e3f64447b58f0 100644 (file)
@@ -43,6 +43,9 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
                     enum g_lock_type lock_type, struct timeval timeout);
 NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, const char *name);
 
+NTSTATUS g_lock_write_data(struct g_lock_ctx *ctx, const char *name,
+                          const uint8_t *buf, size_t buflen);
+
 NTSTATUS g_lock_do(const char *name, enum g_lock_type lock_type,
                   struct timeval timeout,
                   void (*fn)(void *private_data), void *private_data);
index 4a9d22968b2595131aa1cfff2a85eea9a87848b9..f6c35bb1bcc9a28259f2093ba1f725aa3ab60955 100644 (file)
@@ -551,6 +551,55 @@ done:
        return status;
 }
 
+NTSTATUS g_lock_write_data(struct g_lock_ctx *ctx, const char *name,
+                          const uint8_t *buf, size_t buflen)
+{
+       struct server_id self = messaging_server_id(ctx->msg);
+       struct db_record *rec = NULL;
+       struct g_lock_rec *locks = NULL;
+       size_t i, num_locks;
+       NTSTATUS status;
+       TDB_DATA value;
+
+       rec = dbwrap_fetch_locked(ctx->db, talloc_tos(),
+                                 string_term_tdb_data(name));
+       if (rec == NULL) {
+               DEBUG(10, ("fetch_locked(\"%s\") failed\n", name));
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       value = dbwrap_record_get_value(rec);
+
+       status = g_lock_get_talloc(talloc_tos(), value, &locks, &num_locks,
+                                  NULL, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("g_lock_get for %s failed: %s\n", name,
+                         nt_errstr(status));
+               status = NT_STATUS_FILE_INVALID;
+               goto done;
+       }
+
+       for (i=0; i<num_locks; i++) {
+               if (server_id_equal(&self, &locks[i].pid) &&
+                   (locks[i].lock_type == G_LOCK_WRITE)) {
+                       break;
+               }
+       }
+       if (i == num_locks) {
+               DBG_DEBUG("Not locked by us\n");
+               status = NT_STATUS_NOT_LOCKED;
+               goto done;
+       }
+
+       status = g_lock_record_store(rec, locks, num_locks, buf, buflen);
+
+done:
+       TALLOC_FREE(locks);
+       TALLOC_FREE(rec);
+       return status;
+}
+
 struct g_lock_locks_state {
        int (*fn)(const char *name, void *private_data);
        void *private_data;