s3:dbwrap_ctdb: in ctdb_delete, send a SCHEDULE_FOR_DELETION control to local ctdbd
authorMichael Adam <obnox@samba.org>
Wed, 22 Dec 2010 13:16:07 +0000 (14:16 +0100)
committerMichael Adam <obnox@samba.org>
Fri, 11 Mar 2011 15:23:44 +0000 (16:23 +0100)
This way, the record will be scheduled for fast vacuuming.

source3/lib/dbwrap_ctdb.c

index 6887575d44059339768577259b3cd171c5fd63e5..dfbd123b9ade3677911a76575c772232209fca7a 100644 (file)
@@ -888,6 +888,12 @@ static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
 static NTSTATUS db_ctdb_delete(struct db_record *rec)
 {
        TDB_DATA data;
+       NTSTATUS status;
+       struct ctdb_control_schedule_for_deletion *dd;
+       TDB_DATA indata;
+       int cstatus;
+       struct db_ctdb_rec *crec = talloc_get_type_abort(
+               rec->private_data, struct db_ctdb_rec);
 
        /*
         * We have to store the header with empty data. TODO: Fix the
@@ -896,8 +902,43 @@ static NTSTATUS db_ctdb_delete(struct db_record *rec)
 
        ZERO_STRUCT(data);
 
-       return db_ctdb_store(rec, data, 0);
+       status = db_ctdb_store(rec, data, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       indata.dsize = offsetof(struct ctdb_control_schedule_for_deletion, key) + rec->key.dsize;
+       indata.dptr = talloc_zero_array(crec, uint8_t, indata.dsize);
+       if (indata.dptr == NULL) {
+               printf("out of memory\n");
+               exit(1);
+       }
+       dd = (struct ctdb_control_schedule_for_deletion *)(void *)indata.dptr;
+       dd->db_id = crec->ctdb_ctx->db_id;
+       dd->hdr = crec->header;
+       dd->keylen = rec->key.dsize;
+       memcpy(dd->key, rec->key.dptr, rec->key.dsize);
+
+       status = ctdbd_control_local(messaging_ctdbd_connection(),
+                                    CTDB_CONTROL_SCHEDULE_FOR_DELETION,
+                                    crec->ctdb_ctx->db_id,
+                                    0, /* flags */
+                                    indata,
+                                    NULL, /* outdata */
+                                    NULL, /* errmsg */
+                                    &cstatus);
+       talloc_free(indata.dptr);
+
+       if (!NT_STATUS_IS_OK(status) || cstatus != 0) {
+               DEBUG(1, (__location__ " Error sending local control "
+                         "SCHEDULE_FOR_DELETION: %s, cstatus = %d\n",
+                         nt_errstr(status), cstatus));
+               if (NT_STATUS_IS_OK(status)) {
+                       status = NT_STATUS_UNSUCCESSFUL;
+               }
+       }
 
+       return status;
 }
 
 static int db_ctdb_record_destr(struct db_record* data)