mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
server: implement a new control SCHEDULE_FOR_DELETION to fill the delete_queue.
(This used to be ctdb commit 680223074e992b32ccf6f42cb80c3fa93074fee7)
This commit is contained in:
parent
46a05397a4
commit
8569fcbc83
@ -1385,4 +1385,17 @@ int ctdb_deferred_drop_all_ips(struct ctdb_context *ctdb);
|
||||
|
||||
int ctdb_process_deferred_attach(struct ctdb_context *ctdb);
|
||||
|
||||
/**
|
||||
* structure to pass to a schedule_for_deletion_control
|
||||
*/
|
||||
struct ctdb_control_schedule_for_deletion {
|
||||
uint32_t db_id;
|
||||
struct ctdb_ltdb_header hdr;
|
||||
uint32_t keylen;
|
||||
uint8_t key[1]; /* key[] */
|
||||
};
|
||||
|
||||
int32_t ctdb_control_schedule_for_deletion(struct ctdb_context *ctdb,
|
||||
TDB_DATA indata);
|
||||
|
||||
#endif
|
||||
|
@ -604,6 +604,15 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
|
||||
CHECK_CONTROL_DATA_SIZE(0);
|
||||
return ctdb_control_get_stat_history(ctdb, c, outdata);
|
||||
|
||||
case CTDB_CONTROL_SCHEDULE_FOR_DELETION: {
|
||||
struct ctdb_control_schedule_for_deletion *d;
|
||||
size_t size = offsetof(struct ctdb_control_schedule_for_deletion, key);
|
||||
CHECK_CONTROL_MIN_DATA_SIZE(size);
|
||||
d = (struct ctdb_control_schedule_for_deletion *)indata.dptr;
|
||||
size += d->keylen;
|
||||
CHECK_CONTROL_DATA_SIZE(size);
|
||||
return ctdb_control_schedule_for_deletion(ctdb, indata);
|
||||
}
|
||||
default:
|
||||
DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
|
||||
return -1;
|
||||
|
@ -1269,3 +1269,67 @@ int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a record for deletetion.
|
||||
* Called from the parent context.
|
||||
*/
|
||||
int32_t ctdb_control_schedule_for_deletion(struct ctdb_context *ctdb,
|
||||
TDB_DATA indata)
|
||||
{
|
||||
struct ctdb_control_schedule_for_deletion *dd;
|
||||
struct ctdb_db_context *ctdb_db;
|
||||
int ret;
|
||||
TDB_DATA key;
|
||||
uint32_t hash;
|
||||
struct delete_record_data *kd;
|
||||
|
||||
dd = (struct ctdb_control_schedule_for_deletion *)indata.dptr;
|
||||
|
||||
ctdb_db = find_ctdb_db(ctdb, dd->db_id);
|
||||
if (ctdb_db == NULL) {
|
||||
DEBUG(DEBUG_ERR, (__location__ " Unknown db id 0x%08x\n",
|
||||
dd->db_id));
|
||||
return -1;
|
||||
}
|
||||
|
||||
key.dsize = dd->keylen;
|
||||
key.dptr = dd->key;
|
||||
|
||||
hash = (uint32_t)ctdb_hash(&key);
|
||||
|
||||
DEBUG(DEBUG_INFO, (__location__ " Schedule for deletion: db[%s] "
|
||||
"db_id[0x%08x] "
|
||||
"key_hash[0x%08x] "
|
||||
"lmaster[%u] "
|
||||
"migrated_with_data[%s]\n",
|
||||
ctdb_db->db_name, dd->db_id,
|
||||
hash,
|
||||
ctdb_lmaster(ctdb_db->ctdb, &key),
|
||||
dd->hdr.flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA ? "yes" : "no"));
|
||||
|
||||
kd = (struct delete_record_data *)trbt_lookup32(ctdb_db->delete_queue, hash);
|
||||
if (kd != NULL) {
|
||||
if ((kd->key.dsize != key.dsize) ||
|
||||
(memcmp(kd->key.dptr, key.dptr, key.dsize) != 0))
|
||||
{
|
||||
DEBUG(DEBUG_INFO,
|
||||
("schedule for deletion: Hash collision (0x%08x)."
|
||||
" Skipping the record.\n", hash));
|
||||
return 0;
|
||||
} else {
|
||||
DEBUG(DEBUG_INFO,
|
||||
("schedule for deletetion: Overwriting entry for "
|
||||
"key with hash 0x%08x.\n", hash));
|
||||
}
|
||||
}
|
||||
|
||||
ret = insert_delete_record_data_into_tree(ctdb, ctdb_db,
|
||||
ctdb_db->delete_queue,
|
||||
&dd->hdr, key);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user