]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ================== |
2 | Public OSD Version | |
3 | ================== | |
4 | ||
5 | We maintain two versions on disk: an eversion_t pg_log.head and a | |
6 | version_t info.user_version. Each object is tagged with both the pg | |
7 | version and user_version it was last modified with. The PG version is | |
8 | modified by manipulating OpContext::at_version and then persisting it | |
9 | to the pg log as transactions, and is incremented in all the places it | |
10 | used to be. The user_version is modified by manipulating the new | |
11 | OpContext::user_at_version and is also persisted via the pg log | |
12 | transactions. | |
13 | user_at_version is modified only in PrimaryLogPG::prepare_transaction | |
14 | when the op was a "user modify" (a non-watch write), and the durable | |
15 | user_version is updated according to the following rules: | |
16 | 1) set user_at_version to the maximum of ctx->new_obs.oi.user_version+1 | |
17 | and info.last_user_version+1. | |
18 | 2) set user_at_version to the maximum of itself and | |
19 | ctx->at_version.version. | |
20 | 3) ctx->new_obs.oi.user_version = ctx->user_at_version (to change the | |
21 | object's user_version) | |
22 | ||
23 | This set of update semantics mean that for traditional pools the | |
24 | user_version will be equal to the past reassert_version, while for | |
25 | caching pools the object and PG user-version will be able to cross | |
26 | pools without making a total mess of things. | |
27 | In order to support old clients, we keep the old reassert_version but | |
28 | rename it to "bad_replay_version"; we fill it in as before: for writes | |
29 | it is set to the at_version (and is the proper replay version); for | |
30 | watches it is set to our user version; for ENOENT replies it is set to | |
31 | the replay version's epoch but the user_version's version. We also now | |
32 | fill in the version_t portion of the bad_replay_version on read ops as | |
33 | well as write ops, which should be fine for all old clients. | |
34 | ||
35 | For new clients, we prevent them from reading bad_replay_version and | |
36 | add two proper members: user_version and replay_version; user_version | |
37 | is filled in on every operation (reads included) while replay_version | |
38 | is filled in for writes. | |
39 | ||
40 | The objclass function get_current_version() now always returns the | |
41 | pg->info.last_user_version, which means it is guaranteed to contain | |
42 | the version of the last user update in the PG (including on reads!). |