~ubuntu-branches/ubuntu/utopic/mariadb-5.5/utopic-security

« back to all changes in this revision

Viewing changes to storage/tokudb/ft-index/ft/rollback.cc

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2014-04-17 20:55:22 UTC
  • mfrom: (2.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140417205522-wof4l36nxhlkn89m
* New upstream release, fixing the following security issues:
  * Corresponding MariaDB CVEs for Oracle SPU April 2014 (Closes: #745330)
    - CVE-2014-0384 
    - CVE-2014-2419 
    - CVE-2014-2430 
    - CVE-2014-2431 
    - CVE-2014-2432 
    - CVE-2014-2436 
    - CVE-2014-2438 
    - CVE-2014-2440
* Re-enabled TokuDB with "if arch amd64" in d/rules
* Applied patch to log init output better
  (Closes https://mariadb.atlassian.net/browse/MDEV-5957)

Show diffs side-by-side

added added

removed removed

Lines of Context:
158
158
 
159
159
//
160
160
// initializes an empty rollback log node
161
 
// Does not touch the blocknum or hash, that is the
 
161
// Does not touch the blocknum, that is the
162
162
// responsibility of the caller
163
163
//
164
164
void rollback_empty_log_init(ROLLBACK_LOG_NODE log) {
173
173
    log->dirty = true;
174
174
    log->sequence = 0;
175
175
    log->previous = make_blocknum(0);
176
 
    log->previous_hash = 0;
177
176
    log->oldest_logentry = NULL;
178
177
    log->newest_logentry = NULL;
179
178
    log->rollentry_arena = NULL;
185
184
static void rollback_initialize_for_txn(
186
185
    ROLLBACK_LOG_NODE log,
187
186
    TOKUTXN txn,
188
 
    BLOCKNUM previous,
189
 
    uint32_t previous_hash
 
187
    BLOCKNUM previous
190
188
    )
191
189
{
192
190
    log->txnid = txn->txnid;
193
191
    log->sequence = txn->roll_info.num_rollback_nodes++;
194
192
    log->previous = previous;
195
 
    log->previous_hash = previous_hash;
196
193
    log->oldest_logentry = NULL;
197
194
    log->newest_logentry = NULL;
198
195
    log->rollentry_arena = memarena_create();
206
203
}
207
204
 
208
205
// create and pin a new rollback log node. chain it to the other rollback nodes
209
 
// by providing a previous blocknum/ hash and assigning the new rollback log
 
206
// by providing a previous blocknum and assigning the new rollback log
210
207
// node the next sequence number
211
208
static void rollback_log_create (
212
209
    TOKUTXN txn,
213
210
    BLOCKNUM previous,
214
 
    uint32_t previous_hash,
215
211
    ROLLBACK_LOG_NODE *result
216
212
    )
217
213
{
220
216
 
221
217
    CACHEFILE cf = txn->logger->rollback_cachefile;
222
218
    FT CAST_FROM_VOIDP(ft, toku_cachefile_get_userdata(cf));
223
 
    rollback_initialize_for_txn(log, txn, previous, previous_hash);
 
219
    rollback_initialize_for_txn(log, txn, previous);
224
220
    toku_allocate_blocknum(ft->blocktable, &log->blocknum, ft);
225
 
    log->hash = toku_cachetable_hash(ft->cf, log->blocknum);
 
221
    const uint32_t hash = toku_cachetable_hash(ft->cf, log->blocknum);
226
222
    *result = log;
227
 
    toku_cachetable_put(cf, log->blocknum, log->hash,
 
223
    toku_cachetable_put(cf, log->blocknum, hash,
228
224
                       log, rollback_memory_size(log),
229
225
                       get_write_callbacks_for_rollback_log(ft),
230
226
                       toku_rollback_node_save_ct_pair);
231
227
    txn->roll_info.current_rollback = log->blocknum;
232
 
    txn->roll_info.current_rollback_hash = log->hash;
233
228
}
234
229
 
235
230
void toku_rollback_log_unpin(TOKUTXN txn, ROLLBACK_LOG_NODE log) {
255
250
        if (!txn_has_spilled_rollback_logs(txn)) {
256
251
            //First spilled.  Copy to head.
257
252
            txn->roll_info.spilled_rollback_head      = txn->roll_info.current_rollback;
258
 
            txn->roll_info.spilled_rollback_head_hash = txn->roll_info.current_rollback_hash;
259
253
        }
260
254
        //Unconditionally copy to tail.  Old tail does not need to be cached anymore.
261
255
        txn->roll_info.spilled_rollback_tail      = txn->roll_info.current_rollback;
262
 
        txn->roll_info.spilled_rollback_tail_hash = txn->roll_info.current_rollback_hash;
263
256
 
264
257
        txn->roll_info.current_rollback      = ROLLBACK_NONE;
265
 
        txn->roll_info.current_rollback_hash = 0;
266
258
    }
267
259
}
268
260
 
311
303
    BLOCKNUM name = log->previous;
312
304
    int r = 0;
313
305
    if (name.b != ROLLBACK_NONE.b) {
314
 
        uint32_t hash = log->previous_hash;
315
306
        CACHEFILE cf = txn->logger->rollback_cachefile;
 
307
        uint32_t hash = toku_cachetable_hash(cf, name);
316
308
        FT CAST_FROM_VOIDP(h, toku_cachefile_get_userdata(cf));
317
309
        bool doing_prefetch = false;
318
310
        r = toku_cachefile_prefetch(cf, name, hash,
334
326
    assert(log->sequence == sequence);
335
327
}
336
328
 
337
 
void toku_get_and_pin_rollback_log(TOKUTXN txn, BLOCKNUM blocknum, uint32_t hash, ROLLBACK_LOG_NODE *log) {
 
329
void toku_get_and_pin_rollback_log(TOKUTXN txn, BLOCKNUM blocknum, ROLLBACK_LOG_NODE *log) {
338
330
    void * value;
339
331
    CACHEFILE cf = txn->logger->rollback_cachefile;
340
332
    FT CAST_FROM_VOIDP(h, toku_cachefile_get_userdata(cf));
 
333
    uint32_t hash = toku_cachetable_hash(cf, blocknum);
341
334
    int r = toku_cachetable_get_and_pin_with_dep_pairs(cf, blocknum, hash,
342
335
                                        &value, NULL,
343
336
                                        get_write_callbacks_for_rollback_log(h),
351
344
    assert(r == 0);
352
345
    ROLLBACK_LOG_NODE CAST_FROM_VOIDP(pinned_log, value);
353
346
    assert(pinned_log->blocknum.b == blocknum.b);
354
 
    assert(pinned_log->hash == hash);
355
347
    *log = pinned_log;
356
348
}
357
349
 
359
351
    ROLLBACK_LOG_NODE pinned_log = NULL;
360
352
    invariant(txn->state == TOKUTXN_LIVE || txn->state == TOKUTXN_PREPARING); // hot indexing may call this function for prepared transactions
361
353
    if (txn_has_current_rollback_log(txn)) {
362
 
        toku_get_and_pin_rollback_log(txn, txn->roll_info.current_rollback, txn->roll_info.current_rollback_hash, &pinned_log);
 
354
        toku_get_and_pin_rollback_log(txn, txn->roll_info.current_rollback, &pinned_log);
363
355
        toku_rollback_verify_contents(pinned_log, txn->txnid, txn->roll_info.num_rollback_nodes - 1);
364
356
    } else {
365
357
        // For each transaction, we try to acquire the first rollback log
378
370
                rollback_initialize_for_txn(
379
371
                    pinned_log,
380
372
                    txn,
381
 
                    txn->roll_info.spilled_rollback_tail,
382
 
                    txn->roll_info.spilled_rollback_tail_hash
 
373
                    txn->roll_info.spilled_rollback_tail
383
374
                    );
384
375
                txn->roll_info.current_rollback = pinned_log->blocknum;
385
 
                txn->roll_info.current_rollback_hash = pinned_log->hash;
386
376
            }
387
377
        }
388
378
        if (pinned_log == NULL) {
389
 
            rollback_log_create(txn, txn->roll_info.spilled_rollback_tail, txn->roll_info.spilled_rollback_tail_hash, &pinned_log);
 
379
            rollback_log_create(txn, txn->roll_info.spilled_rollback_tail, &pinned_log);
390
380
        }
391
381
    }
392
382
    assert(pinned_log->txnid.parent_id64 == txn->txnid.parent_id64);